diff --git a/copienator/annotation_read_cache.py b/copienator/annotation_read_cache.py index d1ec702..b96628a 100644 --- a/copienator/annotation_read_cache.py +++ b/copienator/annotation_read_cache.py @@ -26,6 +26,8 @@ def _files_digest(paths) -> str: class AnnotationReadCache: + state_file = STATE_FILE + def __init__(self, workspace, mode: str, data: dict, group_dirs=()): self.workspace = workspace self.mode = mode @@ -59,7 +61,7 @@ class AnnotationReadCache: return False directory = self.workspace.root / self.mode / f"Copie{copy_id}" try: - state = read_json(directory / STATE_FILE) + state = read_json(directory / self.state_file) return (state["signature"] == self.signatures[copy_id] and bool(state["outputs"]) and all(Path(path).is_file() for path in state["outputs"])) @@ -82,7 +84,7 @@ class AnnotationReadCache: stem = destination.name.rsplit(" (", 1)[0] outputs.extend(path for suffix in (".jpg", ".pdf") if (path := destination / (stem + suffix)).is_file()) - atomic_write_json(directory / STATE_FILE, { + atomic_write_json(directory / self.state_file, { "signature": self.signatures[copy_id], "outputs": [str(path) for path in outputs], }) diff --git a/copienator/commands/giving_names.py b/copienator/commands/giving_names.py index 8638fef..ec91bee 100644 --- a/copienator/commands/giving_names.py +++ b/copienator/commands/giving_names.py @@ -38,6 +38,7 @@ def build_parser() -> argparse.ArgumentParser: "directories, matching folders by their trailing copy ID" ), ) + parser.add_argument("--incremental", action="store_true", help="Skip unchanged return folders") return parser @@ -147,6 +148,7 @@ def update_named_return_answers( def prepare_named_returns( workspace: EvaluationWorkspace, annotation_dir_name: str, + *, incremental: bool = False, ) -> ExitCode: workspace.require_directories("Copies", annotation_dir_name) workspace.return_dir.mkdir(parents=True, exist_ok=True) @@ -198,6 +200,12 @@ def prepare_named_returns( assigned_names.add(name) destination = existing_returns.get(int(copy_id), workspace.return_dir / f"{safe_name} ({copy_id})") output_name = destination.name.rsplit(" (", 1)[0] + from copienator.reviewed_cache import ReturnCache + cache = ReturnCache(workspace.root, source_folder, destination) if incremental else None + if cache and cache.unchanged(): + print(f"Skipping unchanged return {destination.name}") + continue + copy_failed = False destination.mkdir(parents=True, exist_ok=True) try: publish_answer_returns(workspace.root, source_folder, destination) @@ -238,6 +246,9 @@ def prepare_named_returns( file=sys.stderr, ) had_errors = True + copy_failed = True + if cache and not copy_failed: + cache.remember() unassigned = expected_names - assigned_names if unassigned: @@ -253,10 +264,11 @@ def run( *, annotation_dir: str, update: bool = False, + incremental: bool = False, ) -> ExitCode: if update: return update_named_return_answers(workspace, annotation_dir) - return prepare_named_returns(workspace, annotation_dir) + return prepare_named_returns(workspace, annotation_dir, incremental=incremental) def main(argv: Sequence[str] | None = None) -> int: @@ -268,6 +280,7 @@ def main(argv: Sequence[str] | None = None) -> int: workspace_from_args(args, repository=Path.cwd()), annotation_dir=args.annotation_dir, update=args.update, + incremental=args.incremental, ), ) diff --git a/copienator/commands/modify_annotations.py b/copienator/commands/modify_annotations.py index a466af8..27ded20 100644 --- a/copienator/commands/modify_annotations.py +++ b/copienator/commands/modify_annotations.py @@ -25,16 +25,22 @@ from copienator.annotation_modifications import ( from copienator.filesystem import publish_file_sets -def run(workspace: EvaluationWorkspace, *, annotation_dir: str = "BGnot") -> ExitCode: +def run(workspace: EvaluationWorkspace, *, annotation_dir: str = "BGnot", incremental: bool = False) -> ExitCode: workspace.require_files("labels", DRAFT) workspace.require_directories("Copies", annotation_dir) text = (workspace.root / DRAFT).read_text(encoding="utf-8") instructions = read_instructions(text, annotation_dir) - validate_instructions(workspace.root, annotation_dir, instructions) directory = workspace.root / annotation_dir applied = directory / APPLIED previous = read_instructions(applied.read_text(encoding="utf-8"), annotation_dir) if applied.exists() else [] + if incremental and previous == instructions: + print("Skipping unchanged transfer instructions") + return ExitCode.SUCCESS + validate_instructions(workspace.root, annotation_dir, instructions) copy_ids = sorted({item.copy_id for item in [*previous, *instructions]}) + if incremental: + copy_ids = [cid for cid in copy_ids + if [i for i in previous if i.copy_id == cid] != [i for i in instructions if i.copy_id == cid]] # Prepare every copy before publishing anything, including the applied file. with TemporaryDirectory(prefix=".annotation-edits-", dir=directory) as temporary: staging_root = Path(temporary) @@ -61,12 +67,13 @@ def run(workspace: EvaluationWorkspace, *, annotation_dir: str = "BGnot") -> Exi def build_parser(): parser = evaluation_parser("Modify reviewed answer bodies using annotation_modifications.txt") parser.add_argument("--annotation-dir", choices=MODES, default="BGnot") + parser.add_argument("--incremental", action="store_true", help="Skip unchanged transfer instructions") return parser def main(argv: Sequence[str] | None = None) -> int: return execute(build_parser(), argv, lambda args: run( - workspace_from_args(args), annotation_dir=args.annotation_dir)) + workspace_from_args(args), annotation_dir=args.annotation_dir, incremental=args.incremental)) if __name__ == "__main__": diff --git a/copienator/commands/regenerate_reviewed.py b/copienator/commands/regenerate_reviewed.py index d3f60f3..a8c6d83 100644 --- a/copienator/commands/regenerate_reviewed.py +++ b/copienator/commands/regenerate_reviewed.py @@ -5,9 +5,19 @@ from copienator.commands.reading_annotations import apply_actions_and_regenerate from copienator.commands.reading_grouped_annotations import apply_actions_and_regenerate_grouped -def run(workspace: EvaluationWorkspace, mode: str): +def run(workspace: EvaluationWorkspace, mode: str, *, incremental: bool = False): directories = sorted((p for p in (workspace.root / mode).glob('Copie*') if p.is_dir() and p.name[5:].isdigit() and (p / 'score.json').is_file())) + from copienator.reviewed_cache import ReviewedReadCache + cache = ReviewedReadCache(workspace, mode, directories) if incremental else None + if cache: + pending = [] + for directory in directories: + if cache.unchanged(directory.name[5:]): + print(f"Skipping unchanged {directory.name}", flush=True) + else: + pending.append(directory) + directories = pending # Validate every snapshot before starting to publish any copy. for directory in directories: if not (directory / FILENAME).is_file(): @@ -29,10 +39,14 @@ def run(workspace: EvaluationWorkspace, mode: str): print(log, flush=True) if result != ExitCode.SUCCESS: status = ExitCode.PARTIAL + elif cache: + # Rendering can normalize the saved snapshot; fingerprint the published inputs. + ReviewedReadCache(workspace, mode, [directory]).remember([cid]) return status def main(argv=None): parser = evaluation_parser('Regenerate from saved reviewed inputs without rescanning handwriting') parser.add_argument('--annotation-dir', choices=('Bnot', 'BGnot'), required=True) - return execute(parser, argv, lambda args: run(workspace_from_args(args), args.annotation_dir)) + parser.add_argument("--incremental", action="store_true", help="Skip unchanged copies") + return execute(parser, argv, lambda args: run(workspace_from_args(args), args.annotation_dir, incremental=args.incremental)) diff --git a/copienator/finalisation.py b/copienator/finalisation.py index 97e8642..2836a30 100644 --- a/copienator/finalisation.py +++ b/copienator/finalisation.py @@ -9,7 +9,7 @@ import subprocess import sys import threading -from copienator import atomic_write_json, read_json, utils +from copienator import EvaluationWorkspace, atomic_write_json, read_json, utils from copienator import custom_remarks, general_remarks from copienator.annotation_modifications import DRAFT, APPLIED, BASELINE, read_instructions, validate_instructions from copienator.return_identity import return_folders, RETURN_FOLDER_PATTERN, set_copy_name @@ -17,8 +17,9 @@ from copienator.score_editing import set_score class Finalisation: - def __init__(self, root: Path, mode: str, token: str, lock_fd: int | None = None): + def __init__(self, root: Path, mode: str, token: str, lock_fd: int | None = None, *, repository: Path | None = None): self.root = root.resolve() + self.repository = (repository or Path.cwd()).resolve() if mode not in ('Bnot', 'BGnot'): raise ValueError('Choisissez Bnot ou BGnot.') self.mode, self.token = mode, token @@ -80,10 +81,13 @@ class Finalisation: 'image': (directory / f'{label}.jpg').is_file(), 'editableBody': label in base.get('images', {}), 'info': info.get(label, {})} for label in self.labels]}) + names_path = EvaluationWorkspace(self.root, self.repository).names_file() + expected_names = (sorted({line.strip() for line in names_path.read_text(encoding='utf-8').splitlines() + if line.strip()}, key=str.casefold) if names_path.is_file() else None) applied = self.root / self.mode / APPLIED applied_text = applied.read_text() if applied.exists() else f'### Source: {self.mode}\n' return {'evaluation': self.root.name, 'mode': self.mode, 'labels': self.labels, 'copies': copies, - 'draft': self.draft(), 'applied': applied_text, 'revision': self.revision(), + 'expectedNames': expected_names, 'draft': self.draft(), 'applied': applied_text, 'revision': self.revision(), 'dirty': read_json(self.dirty_path, default={}).get('dirty', False), 'job': dict(self.job)} def save(self, data): @@ -116,10 +120,20 @@ class Finalisation: else: raise ValueError('Modification inconnue.') self.dirty_path.parent.mkdir(exist_ok=True) - atomic_write_json(self.dirty_path, {'dirty': True}) + pending = read_json(self.dirty_path, default={'dirty': False}) + kinds = set(pending.get('kinds', ['unknown'] if pending.get('dirty') else [])) + kinds.add(kind) + render_inputs = None + if kinds == {'name'}: + render_inputs = (pending.get('render_inputs') if pending.get('kinds') == ['name'] + else self._render_inputs()) + pending = {'dirty': True, 'kinds': sorted(kinds)} + if kinds == {'name'}: + pending['render_inputs'] = render_inputs + atomic_write_json(self.dirty_path, pending) return self.state() - def start_job(self, revision: str, apply_draft: bool): + def start_job(self, revision: str, apply_draft: bool, incremental: bool = True): with self.mutex: if self.job['running'] or self.closing or revision != self.revision(): raise ValueError('Traitement déjà en cours ou données modifiées. Rechargez la page.') @@ -128,12 +142,12 @@ class Finalisation: if not (self.root / DRAFT).exists(): (self.root / DRAFT).write_text(self.draft()) self.job = {'running': True, 'status': 'running', 'log': ''} - threading.Thread(target=self._run_job, args=(apply_draft,), daemon=True).start() + threading.Thread(target=self._run_job, args=(apply_draft, incremental), daemon=True).start() return dict(self.job) - def _run_job(self, apply_draft): + def _run_job(self, apply_draft, incremental=True): try: - self._regenerate(apply_draft) + self._regenerate(apply_draft, incremental) except Exception as exc: with self.mutex: self.job.update(status='failed', log=self.job['log'] + '\n' + str(exc)) @@ -141,7 +155,26 @@ class Finalisation: with self.mutex: self.job['running'] = False - def _regenerate(self, apply_draft): + def _render_inputs(self): + from copienator.reviewed_cache import ReviewedReadCache + from copienator.review_snapshot import FILENAME + directories = self.copies() + if not directories or not all((d / FILENAME).is_file() for d in directories): + return None + cache = ReviewedReadCache(EvaluationWorkspace(self.root), self.mode, directories) + # Keep the fast path conservative when an existing rendered file disappears. + outputs = [] + for directory in directories: + info = read_json(directory / 'info.json', default={}) + paths = [directory / 'info.json', directory / BASELINE] + paths += [directory / f'{label}.jpg' for label, entry in info.items() if entry['present']] + paths += list(directory.glob('Concat*.*')) + if any(not path.is_file() for path in paths): + return None + outputs.extend(str(p) for p in paths) + return {'signatures': cache.signatures, 'outputs': sorted(outputs)} + + def _regenerate(self, apply_draft, incremental=True): from copienator.return_answers import load_return_answer_options options = load_return_answer_options(self.root) reader = 'read-grouped' if self.mode == 'BGnot' else 'read-annotations' @@ -152,13 +185,25 @@ class Finalisation: if apply_draft: commands.append(['modify-annotations', str(self.root), '--annotation-dir', self.mode]) commands.append(['giving-names', str(self.root), self.mode]) + pending = read_json(self.dirty_path, default={}) + names_only = (incremental and not apply_draft and pending.get('kinds') == ['name'] + and pending.get('render_inputs') is not None + and pending['render_inputs'] == self._render_inputs()) from copienator.review_snapshot import FILENAME - if all((directory / FILENAME).is_file() for directory in self.copies()): + if names_only: + commands = [['giving-names', str(self.root), self.mode]] + with self.mutex: + self.job['log'] += 'Noms seuls modifiés : conservation des images et PDF de correction.\n' + elif all((directory / FILENAME).is_file() for directory in self.copies()): commands[0] = ['regenerate-reviewed', str(self.root), '--annotation-dir', self.mode] elif (self.root / 'BRnot').is_dir(): with self.mutex: self.job.update(running=False, status='failed', log='Résultat de lecture sauvegardé absent pour une évaluation avec reprise. Relisez le passage principal puis fusionnez la reprise avant de régénérer dans le navigateur. Aucun résultat n’a été remplacé.') return + if incremental: + for command in commands: + if command[0] in ('regenerate-reviewed', 'modify-annotations', 'giving-names'): + command.append('--incremental') env = dict(os.environ, COPIENATOR_FINALISATION_TOKEN=self.token, PYTHONUNBUFFERED='1') from copienator import configuration if configuration.CONFIG_PATH is not None: diff --git a/copienator/finalisation_server.py b/copienator/finalisation_server.py index c2882bd..0cf5d26 100644 --- a/copienator/finalisation_server.py +++ b/copienator/finalisation_server.py @@ -33,6 +33,7 @@ class Change(BaseModel): class Regenerate(BaseModel): revision: str apply_draft: bool = False + incremental: bool = True class Preview(BaseModel): @@ -91,7 +92,7 @@ def create_app(service: Finalisation, browser_token: str, stop=lambda: None): @app.post('/api/regenerate') def regenerate(data: Regenerate): - return service.start_job(data.revision, data.apply_draft) + return service.start_job(data.revision, data.apply_draft, data.incremental) @app.post('/api/stop') def shutdown(): @@ -174,11 +175,11 @@ def create_app(service: Finalisation, browser_token: str, stop=lambda: None): class WebSession: - def __init__(self, root: Path, mode: str): + def __init__(self, root: Path, mode: str, *, repository: Path | None = None): self.lease = EvaluationLock(root) self.lease.__enter__() try: - self.service = Finalisation(root, mode, self.lease.token, self.lease.stream.fileno()) + self.service = Finalisation(root, mode, self.lease.token, self.lease.stream.fileno(), repository=repository) if not self.service.copies(): raise ValueError('Lisez les annotations manuscrites dans ce mode avant d’ouvrir la finalisation web.') self.token = secrets.token_urlsafe(32) diff --git a/copienator/reviewed_cache.py b/copienator/reviewed_cache.py new file mode 100644 index 0000000..a73d91d --- /dev/null +++ b/copienator/reviewed_cache.py @@ -0,0 +1,71 @@ +"""Content-based caches for saved-review rendering and return publication.""" +from dataclasses import asdict +from hashlib import sha256 +import json +from pathlib import Path +from copienator import atomic_write_json, configuration, read_json, general_remarks +from copienator.annotation_read_cache import AnnotationReadCache, _files_digest +from copienator.annotation_modifications import APPLIED, read_instructions +from copienator.custom_remarks import load_remarks, copy_key +from copienator.return_answers import load_return_answer_options +from copienator.review_snapshot import FILENAME + + +def output_options(root): + return (load_return_answer_options(root), configuration.RETURN_ANSWERS_ENABLED, + configuration.RETURN_JPEG_ENABLED, configuration.RETURN_PDF_ENABLED) + + +def signature(payload): + return sha256(json.dumps(payload, sort_keys=True, default=str).encode()).hexdigest() + + +class ReviewedReadCache(AnnotationReadCache): + state_file = '.reviewed-render-state.json' + + def __init__(self, workspace, mode, directories): + self.workspace, self.mode, self.signatures = workspace, mode, {} + root = workspace.root + shared = [root / 'labels'] + for folder in ('Text2', 'Sol2'): + shared.extend((root / folder).glob('*.pdf')) + common = (_files_digest(shared), configuration.LATEX_ANOT_BEFORE, configuration.LATEX_ANOT_AFTER) + remarks, general = load_remarks(root), general_remarks.load_remarks(root) + applied = root / mode / APPLIED + instructions = read_instructions(applied.read_text(), mode) if applied.is_file() else [] + for directory in directories: + cid = directory.name[5:] + saved = read_json(directory / FILENAME) + paths = [directory / FILENAME, directory / 'score.json'] + for item in saved['data'].values(): + pdf = Path(item['pdf_path']) + pdf = pdf if pdf.is_absolute() else root / pdf + paths.extend((pdf, pdf.with_suffix('.layout.json'))) + paths.extend(directory / note['file'] for note in saved['notes'].values() if note['file']) + self.signatures[cid] = signature((1, common, _files_digest(paths), + remarks.get(copy_key(cid), {}), general.get(copy_key(cid), []), + [asdict(i) for i in instructions if i.copy_id == cid])) + + +class ReturnCache: + def __init__(self, root, source, destination): + self.path = source / '.return-publication-state.json' + self.destination = destination + paths = [source / 'score.json', source / 'info.json'] + paths.extend(source.glob('*.jpg')) + paths.extend(source.glob('*.pdf')) + for folder in ('Text2', 'Sol2'): + paths.extend((root / folder).glob('*.pdf')) + self.signature = signature((1, str(destination), _files_digest(paths), output_options(root))) + + def unchanged(self): + try: + state = read_json(self.path) + return (state['signature'] == self.signature and bool(state['outputs']) + and all((self.destination / name).is_file() for name in state['outputs'])) + except (OSError, ValueError, KeyError, TypeError): + return False + + def remember(self): + outputs = [str(p.relative_to(self.destination)) for p in self.destination.rglob('*') if p.is_file()] + atomic_write_json(self.path, {'signature': self.signature, 'outputs': outputs}) diff --git a/copienator/web_static/assets/index-B8v-OSfB.js b/copienator/web_static/assets/index-B8v-OSfB.js deleted file mode 100644 index 5231325..0000000 --- a/copienator/web_static/assets/index-B8v-OSfB.js +++ /dev/null @@ -1,15 +0,0 @@ -(function(){const G=document.createElement("link").relList;if(G&&G.supports&&G.supports("modulepreload"))return;for(const q of document.querySelectorAll('link[rel="modulepreload"]'))y(q);new MutationObserver(q=>{for(const $ of q)if($.type==="childList")for(const rl of $.addedNodes)rl.tagName==="LINK"&&rl.rel==="modulepreload"&&y(rl)}).observe(document,{childList:!0,subtree:!0});function Y(q){const $={};return q.integrity&&($.integrity=q.integrity),q.referrerPolicy&&($.referrerPolicy=q.referrerPolicy),q.crossOrigin==="use-credentials"?$.credentials="include":q.crossOrigin==="anonymous"?$.credentials="omit":$.credentials="same-origin",$}function y(q){if(q.ep)return;q.ep=!0;const $=Y(q);fetch(q.href,$)}})();var zs={exports:{}},nn={};var lv;function ih(){if(lv)return nn;lv=1;var _=Symbol.for("react.transitional.element"),G=Symbol.for("react.fragment");function Y(y,q,$){var rl=null;if($!==void 0&&(rl=""+$),q.key!==void 0&&(rl=""+q.key),"key"in q){$={};for(var Gl in q)Gl!=="key"&&($[Gl]=q[Gl])}else $=q;return q=$.ref,{$$typeof:_,type:y,key:rl,ref:q!==void 0?q:null,props:$}}return nn.Fragment=G,nn.jsx=Y,nn.jsxs=Y,nn}var tv;function ch(){return tv||(tv=1,zs.exports=ih()),zs.exports}var d=ch(),_s={exports:{}},Z={};var uv;function fh(){if(uv)return Z;uv=1;var _=Symbol.for("react.transitional.element"),G=Symbol.for("react.portal"),Y=Symbol.for("react.fragment"),y=Symbol.for("react.strict_mode"),q=Symbol.for("react.profiler"),$=Symbol.for("react.consumer"),rl=Symbol.for("react.context"),Gl=Symbol.for("react.forward_ref"),ul=Symbol.for("react.suspense"),Dl=Symbol.for("react.memo"),R=Symbol.for("react.lazy"),b=Symbol.for("react.activity"),M=Symbol.for("react.view_transition"),_l=Symbol.iterator;function Xl(s){return s===null||typeof s!="object"?null:(s=_l&&s[_l]||s["@@iterator"],typeof s=="function"?s:null)}var Ul={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},il=Object.assign,et={};function Ol(s,E,D){this.props=s,this.context=E,this.refs=et,this.updater=D||Ul}Ol.prototype.isReactComponent={},Ol.prototype.setState=function(s,E){if(typeof s!="object"&&typeof s!="function"&&s!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,s,E,"setState")},Ol.prototype.forceUpdate=function(s){this.updater.enqueueForceUpdate(this,s,"forceUpdate")};function gt(){}gt.prototype=Ol.prototype;function Ql(s,E,D){this.props=s,this.context=E,this.refs=et,this.updater=D||Ul}var at=Ql.prototype=new gt;at.constructor=Ql,il(at,Ol.prototype),at.isPureReactComponent=!0;var xl=Array.isArray;function K(){}var F={H:null,A:null,T:null,S:null},Vl=Object.prototype.hasOwnProperty;function Nl(s,E,D){var j=D.ref;return{$$typeof:_,type:s,key:E,ref:j!==void 0?j:null,props:D}}function pl(s,E){return Nl(s.type,E,s.props)}function Ll(s){return typeof s=="object"&&s!==null&&s.$$typeof===_}function jt(s){var E={"=":"=0",":":"=2"};return"$"+s.replace(/[=:]/g,function(D){return E[D]})}var L=/\/+/g;function hl(s,E){return typeof s=="object"&&s!==null&&s.key!=null?jt(""+s.key):E.toString(36)}function C(s){switch(s.status){case"fulfilled":return s.value;case"rejected":throw s.reason;default:switch(typeof s.status=="string"?s.then(K,K):(s.status="pending",s.then(function(E){s.status==="pending"&&(s.status="fulfilled",s.value=E)},function(E){s.status==="pending"&&(s.status="rejected",s.reason=E)})),s.status){case"fulfilled":return s.value;case"rejected":throw s.reason}}throw s}function B(s,E,D,j,k){var al=typeof s;(al==="undefined"||al==="boolean")&&(s=null);var sl=!1;if(s===null)sl=!0;else switch(al){case"bigint":case"string":case"number":sl=!0;break;case"object":switch(s.$$typeof){case _:case G:sl=!0;break;case R:return sl=s._init,B(sl(s._payload),E,D,j,k)}}if(sl)return k=k(s),sl=j===""?"."+hl(s,0):j,xl(k)?(D="",sl!=null&&(D=sl.replace(L,"$&/")+"/"),B(k,E,D,"",function(nu){return nu})):k!=null&&(Ll(k)&&(k=pl(k,D+(k.key==null||s&&s.key===k.key?"":(""+k.key).replace(L,"$&/")+"/")+sl)),E.push(k)),1;sl=0;var x=j===""?".":j+":";if(xl(s))for(var V=0;V>>1,el=C[cl];if(0>>1;clq(N,X))sq(E,N)?(C[cl]=E,C[s]=X,cl=s):(C[cl]=N,C[O]=X,cl=O);else if(sq(E,X))C[cl]=E,C[s]=X,cl=s;else break l}}return B}function q(C,B){var X=C.sortIndex-B.sortIndex;return X!==0?X:C.id-B.id}if(_.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var $=performance;_.unstable_now=function(){return $.now()}}else{var rl=Date,Gl=rl.now();_.unstable_now=function(){return rl.now()-Gl}}var ul=[],Dl=[],R=1,b=null,M=3,_l=!1,Xl=!1,Ul=!1,il=!1,et=typeof setTimeout=="function"?setTimeout:null,Ol=typeof clearTimeout=="function"?clearTimeout:null,gt=typeof setImmediate<"u"?setImmediate:null;function Ql(C){for(var B=Y(Dl);B!==null;){if(B.callback===null)y(Dl);else if(B.startTime<=C)y(Dl),B.sortIndex=B.expirationTime,G(ul,B);else break;B=Y(Dl)}}function at(C){if(Ul=!1,Ql(C),!Xl)if(Y(ul)!==null)Xl=!0,xl||(xl=!0,Ll());else{var B=Y(Dl);B!==null&&hl(at,B.startTime-C)}}var xl=!1,K=-1,F=5,Vl=-1;function Nl(){return il?!0:!(_.unstable_now()-VlC&&Nl());){var cl=b.callback;if(typeof cl=="function"){b.callback=null,M=b.priorityLevel;var el=cl(b.expirationTime<=C);if(C=_.unstable_now(),typeof el=="function"){b.callback=el,Ql(C),B=!0;break t}b===Y(ul)&&y(ul),Ql(C)}else y(ul);b=Y(ul)}if(b!==null)B=!0;else{var ot=Y(Dl);ot!==null&&hl(at,ot.startTime-C),B=!1}}break l}finally{b=null,M=X,_l=!1}B=void 0}}finally{B?Ll():xl=!1}}}var Ll;if(typeof gt=="function")Ll=function(){gt(pl)};else if(typeof MessageChannel<"u"){var jt=new MessageChannel,L=jt.port2;jt.port1.onmessage=pl,Ll=function(){L.postMessage(null)}}else Ll=function(){et(pl,0)};function hl(C,B){K=et(function(){C(_.unstable_now())},B)}_.unstable_IdlePriority=5,_.unstable_ImmediatePriority=1,_.unstable_LowPriority=4,_.unstable_NormalPriority=3,_.unstable_Profiling=null,_.unstable_UserBlockingPriority=2,_.unstable_cancelCallback=function(C){C.callback=null},_.unstable_forceFrameRate=function(C){0>C||125cl?(C.sortIndex=X,G(Dl,C),Y(ul)===null&&C===Y(Dl)&&(Ul?(Ol(K),K=-1):Ul=!0,hl(at,X-cl))):(C.sortIndex=el,G(ul,C),Xl||_l||(Xl=!0,xl||(xl=!0,Ll()))),C},_.unstable_shouldYield=Nl,_.unstable_wrapCallback=function(C){var B=M;return function(){var X=M;M=B;try{return C.apply(this,arguments)}finally{M=X}}}})(As)),As}var nv;function oh(){return nv||(nv=1,Ns.exports=sh()),Ns.exports}var Cs={exports:{}},ut={};var iv;function rh(){if(iv)return ut;iv=1;var _=Ds();function G(R){var b="https://react.dev/errors/"+R;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(_)}catch(G){console.error(G)}}return _(),Cs.exports=rh(),Cs.exports}var fv;function vh(){if(fv)return cn;fv=1;var _=oh(),G=Ds(),Y=dh();function y(l){var t="https://react.dev/errors/"+l;if(1be||(l.current=Xi[be],Xi[be]=null,be--)}function Tl(l,t){be++,Xi[be]=l.current,l.current=t}var wt=Jt(null),ra=Jt(null),Eu=Jt(null),sn=Jt(null);function on(l,t){switch(Tl(Eu,t),Tl(ra,l),Tl(wt,null),t.nodeType){case 9:case 11:l=(l=t.documentElement)&&(l=l.namespaceURI)?s0(l):0;break;default:if(l=t.tagName,t=t.namespaceURI)t=s0(t),l=o0(t,l);else switch(l){case"svg":l=1;break;case"math":l=2;break;default:l=0}}Fl(wt),Tl(wt,l)}function Te(){Fl(wt),Fl(ra),Fl(Eu)}function Qi(l){var t=l.memoizedState;t!==null&&(ca._currentValue=t.memoizedState,Tl(sn,l)),t=wt.current;var u=o0(t,l.type);t!==u&&(Tl(ra,l),Tl(wt,u))}function rn(l){ra.current===l&&(Fl(wt),Fl(ra)),sn.current===l&&(Fl(sn),ca._currentValue=nu)}var Vi,js;function zu(l){if(Vi===void 0)try{throw Error()}catch(u){var t=u.stack.trim().match(/\n( *(at )?)/);Vi=t&&t[1]||"",js=-1)":-1a||f[e]!==m[a]){var S=` -`+f[e].replace(" at new "," at ");return l.displayName&&S.includes("")&&(S=S.replace("",l.displayName)),S}while(1<=e&&0<=a);break}}}finally{Zi=!1,Error.prepareStackTrace=u}return(u=l?l.displayName||l.name:"")?zu(u):""}function ov(l,t){switch(l.tag){case 26:case 27:case 5:return zu(l.type);case 16:return zu("Lazy");case 13:return l.child!==t&&t!==null?zu("Suspense Fallback"):zu("Suspense");case 19:return zu("SuspenseList");case 0:case 15:return Li(l.type,!1);case 11:return Li(l.type.render,!1);case 1:return Li(l.type,!0);case 31:return zu("Activity");case 30:return zu("ViewTransition");default:return""}}function Ms(l){try{var t="",u=null;do t+=ov(l,u),u=l,l=l.return;while(l);return t}catch(e){return` -Error generating stack: `+e.message+` -`+e.stack}}var Ki=Object.prototype.hasOwnProperty,Ji=_.unstable_scheduleCallback,wi=_.unstable_cancelCallback,rv=_.unstable_shouldYield,dv=_.unstable_requestPaint,St=_.unstable_now,vv=_.unstable_getCurrentPriorityLevel,Us=_.unstable_ImmediatePriority,ps=_.unstable_UserBlockingPriority,dn=_.unstable_NormalPriority,mv=_.unstable_LowPriority,Rs=_.unstable_IdlePriority,yv=_.log,hv=_.unstable_setDisableYieldValue,da=null,bt=null;function _u(l){if(typeof yv=="function"&&hv(l),bt&&typeof bt.setStrictMode=="function")try{bt.setStrictMode(da,l)}catch{}}var Tt=Math.clz32?Math.clz32:bv,gv=Math.log,Sv=Math.LN2;function bv(l){return l>>>=0,l===0?32:31-(gv(l)/Sv|0)|0}var vn=256,mn=262144,yn=4194304;function Wu(l){var t=l&42;if(t!==0)return t;switch(l&-l){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return l&-l;case 262144:case 524288:case 1048576:case 2097152:return l&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return l&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return l}}function hn(l,t,u){var e=l.pendingLanes;if(e===0)return 0;var a=0,n=l.suspendedLanes,i=l.pingedLanes;l=l.warmLanes;var c=e&134217727;return c!==0?(e=c&~n,e!==0?a=Wu(e):(i&=c,i!==0?a=Wu(i):u||(u=c&~l,u!==0&&(a=Wu(u))))):(c=e&~n,c!==0?a=Wu(c):i!==0?a=Wu(i):u||(u=e&~l,u!==0&&(a=Wu(u)))),a===0?0:t!==0&&t!==a&&(t&n)===0&&(n=a&-a,u=t&-t,n>=u||n===32&&(u&4194048)!==0)?t:a}function va(l,t){return(l.pendingLanes&~(l.suspendedLanes&~l.pingedLanes)&t)===0}function xs(l,t){(t&8)!==0&&(t|=t&32);var u=l.entangledLanes;if(u!==0)for(l=l.entanglements,u&=t;0u;u++)t.push(l);return t}function ma(l,t){l.pendingLanes|=t,t!==268435456&&(l.suspendedLanes=0,l.pingedLanes=0,l.warmLanes=0)}function Ev(l,t,u,e,a,n){var i=l.pendingLanes;l.pendingLanes=u,l.suspendedLanes=0,l.pingedLanes=0,l.warmLanes=0,l.expiredLanes&=u,l.entangledLanes&=u,l.errorRecoveryDisabledLanes&=u,l.shellSuspendCounter=0;var c=l.entanglements,f=l.expirationTimes,m=l.hiddenUpdates;for(u=i&~u;0"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),ac=!1;if(fu)try{var Sa={};Object.defineProperty(Sa,"passive",{get:function(){ac=!0}}),window.addEventListener("test",Sa,Sa),window.removeEventListener("test",Sa,Sa)}catch{ac=!1}var Ou=null,nc=null,zn=null;function ao(){if(zn)return zn;var l,t=nc,u=t.length,e,a="value"in Ou?Ou.value:Ou.textContent,n=a.length;for(l=0;l=Ea),oo=" ",ro=!1;function vo(l,t){switch(l){case"keyup":return em.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function mo(l){return l=l.detail,typeof l=="object"&&"data"in l?l.data:null}var je=!1;function nm(l,t){switch(l){case"compositionend":return mo(t);case"keypress":return t.which!==32?null:(ro=!0,oo);case"textInput":return l=t.data,l===oo&&ro?null:l;default:return null}}function im(l,t){if(je)return l==="compositionend"||!oc&&vo(l,t)?(l=ao(),zn=nc=Ou=null,je=!1,l):null;switch(l){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1"u")return null;try{return l.activeElement||l.body}catch{return l.body}}function zo(l){for(;l&&l.firstChild;)l=l.firstChild;return l}function _o(l,t){var u=zo(l);l=0;for(var e;u;){if(u.nodeType===3){if(e=l+u.textContent.length,l<=t&&e>=t)return{node:u,offset:t-l};l=e}l:{for(;u;){if(u.nextSibling){u=u.nextSibling;break l}u=u.parentNode}u=void 0}u=zo(u)}}function Oo(l,t){return l&&t?l===t?!0:l&&l.nodeType===3?!1:t&&t.nodeType===3?Oo(l,t.parentNode):"contains"in l?l.contains(t):l.compareDocumentPosition?!!(l.compareDocumentPosition(t)&16):!1:!1}function No(l){l=l!=null&&l.ownerDocument!=null&&l.ownerDocument.defaultView!=null?l.ownerDocument.defaultView:window;for(var t=vc(l.document);t instanceof l.HTMLIFrameElement;){try{var u=typeof t.contentWindow.location.href=="string"}catch{u=!1}if(u)l=t.contentWindow;else break;t=vc(l.document)}return t}function mc(l){var t=l&&l.nodeName&&l.nodeName.toLowerCase();return t&&(t==="input"&&(l.type==="text"||l.type==="search"||l.type==="tel"||l.type==="url"||l.type==="password")||t==="textarea"||l.contentEditable==="true")}var mm=fu&&"documentMode"in document&&11>=document.documentMode,Me=null,yc=null,Na=null,hc=!1;function Ao(l,t,u){var e=u.window===u?u.document:u.nodeType===9?u:u.ownerDocument;hc||Me==null||Me!==vc(e)||(e=Me,"selectionStart"in e&&mc(e)?e={start:e.selectionStart,end:e.selectionEnd}:(e=(e.ownerDocument&&e.ownerDocument.defaultView||window).getSelection(),e={anchorNode:e.anchorNode,anchorOffset:e.anchorOffset,focusNode:e.focusNode,focusOffset:e.focusOffset}),Na&&Oa(Na,e)||(Na=e,e=Ci(yc,"onSelect"),0>=i,a-=i,Ft=1<<32-Tt(t)+a|u<Q?(Bl=H,H=null):Bl=H.sibling;var nl=r(v,H,h[Q],T);if(nl===null){H===null&&(H=Bl);break}l&&H&&nl.alternate===null&&t(v,H),o=n(nl,o,Q),tl===null?U=nl:tl.sibling=nl,tl=nl,H=Bl}if(Q===h.length)return u(v,H),W&&du(v,Q),U;if(H===null){for(;QQ?(Bl=H,H=null):Bl=H.sibling;var Fu=r(v,H,nl.value,T);if(Fu===null){H===null&&(H=Bl);break}l&&H&&Fu.alternate===null&&t(v,H),o=n(Fu,o,Q),tl===null?U=Fu:tl.sibling=Fu,tl=Fu,H=Bl}if(nl.done)return u(v,H),W&&du(v,Q),U;if(H===null){for(;!nl.done;Q++,nl=h.next())nl=z(v,nl.value,T),nl!==null&&(o=n(nl,o,Q),tl===null?U=nl:tl.sibling=nl,tl=nl);return W&&du(v,Q),U}for(H=e(H);!nl.done;Q++,nl=h.next())nl=g(H,v,Q,nl.value,T),nl!==null&&(l&&(Bl=nl.alternate,Bl!==null&&H.delete(Bl.key===null?Q:Bl.key)),o=n(nl,o,Q),tl===null?U=nl:tl.sibling=nl,tl=nl);return l&&H.forEach(function(nh){return t(v,nh)}),W&&du(v,Q),U}function w(v,o,h,T){if(typeof h=="object"&&h!==null&&h.type===pl&&h.key===null&&h.props.ref===void 0&&(h=h.props.children),typeof h=="object"&&h!==null){switch(h.$$typeof){case Vl:l:{for(var U=h.key;o!==null;){if(o.key===U){if(U=h.type,U===pl){if(o.tag===7){u(v,o.sibling),T=a(o,h.props.children),Mu(T,h),T.return=v,v=T;break l}}else if(o.elementType===U||typeof U=="object"&&U!==null&&U.$$typeof===el&&se(U)===o.type){u(v,o.sibling),T=a(o,h.props),Mu(T,h),T.return=v,v=T;break l}u(v,o);break}else t(v,o);o=o.sibling}h.type===pl?(T=ue(h.props.children,v.mode,T,h.key),Mu(T,h),T.return=v,v=T):(T=pn(h.type,h.key,h.props,null,v.mode,T),Mu(T,h),T.return=v,v=T)}return i(v);case Nl:l:{for(U=h.key;o!==null;){if(o.key===U)if(o.tag===4&&o.stateNode.containerInfo===h.containerInfo&&o.stateNode.implementation===h.implementation){u(v,o.sibling),T=a(o,h.children||[]),T.return=v,v=T;break l}else{u(v,o);break}else t(v,o);o=o.sibling}T=_c(h,v.mode,T),T.return=v,v=T}return i(v);case el:return h=se(h),w(v,o,h,T)}if(sl(h))return A(v,o,h,T);if(j(h)){if(U=j(h),typeof U!="function")throw Error(y(150));return h=U.call(h),p(v,o,h,T)}if(typeof h.then=="function")return w(v,o,Vn(h),T);if(h.$$typeof===hl)return w(v,o,Bn(v,h),T);Zn(v,h)}return typeof h=="string"&&h!==""||typeof h=="number"||typeof h=="bigint"?(h=""+h,o!==null&&o.tag===6?(u(v,o.sibling),T=a(o,h),T.return=v,v=T):(u(v,o),T=zc(h,v.mode,T),T.return=v,v=T),i(v)):u(v,o)}return function(v,o,h,T){try{Ua=0;var U=w(v,o,h,T);return Ge=null,U}catch(H){if(H===Be||H===Xn)throw H;var tl=dt(29,H,null,v.mode);return tl.lanes=T,tl.return=v,tl}}}var re=Wo(!0),ko=Wo(!1),Uu=!1;function Rc(l){l.updateQueue={baseState:l.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function xc(l,t){l=l.updateQueue,t.updateQueue===l&&(t.updateQueue={baseState:l.baseState,firstBaseUpdate:l.firstBaseUpdate,lastBaseUpdate:l.lastBaseUpdate,shared:l.shared,callbacks:null})}function pu(l){return{lane:l,tag:0,payload:null,callback:null,next:null}}function Ru(l,t,u){var e=l.updateQueue;if(e===null)return null;if(e=e.shared,(ol&2)!==0){var a=e.pending;return a===null?t.next=t:(t.next=a.next,a.next=t),e.pending=t,t=Un(l),xo(l,null,u),t}return Mn(l,e,t,u),Un(l)}function pa(l,t,u){if(t=t.updateQueue,t!==null&&(t=t.shared,(u&4194048)!==0)){var e=t.lanes;e&=l.pendingLanes,u|=e,t.lanes=u,Ys(l,u)}}function Hc(l,t){var u=l.updateQueue,e=l.alternate;if(e!==null&&(e=e.updateQueue,u===e)){var a=null,n=null;if(u=u.firstBaseUpdate,u!==null){do{var i={lane:u.lane,tag:u.tag,payload:u.payload,callback:null,next:null};n===null?a=n=i:n=n.next=i,u=u.next}while(u!==null);n===null?a=n=t:n=n.next=t}else a=n=t;u={baseState:e.baseState,firstBaseUpdate:a,lastBaseUpdate:n,shared:e.shared,callbacks:e.callbacks},l.updateQueue=u;return}l=u.lastBaseUpdate,l===null?u.firstBaseUpdate=t:l.next=t,u.lastBaseUpdate=t}var qc=!1;function Ra(){if(qc){var l=Ye;if(l!==null)throw l}}function xa(l,t,u,e){qc=!1;var a=l.updateQueue;Uu=!1;var n=a.firstBaseUpdate,i=a.lastBaseUpdate,c=a.shared.pending;if(c!==null){a.shared.pending=null;var f=c,m=f.next;f.next=null,i===null?n=m:i.next=m,i=f;var S=l.alternate;S!==null&&(S=S.updateQueue,c=S.lastBaseUpdate,c!==i&&(c===null?S.firstBaseUpdate=m:c.next=m,S.lastBaseUpdate=f))}if(n!==null){var z=a.baseState;i=0,S=m=f=null,c=n;do{var r=c.lane&-536870913,g=r!==c.lane;if(g?(ll&r)===r:(e&r)===r){r!==0&&r===ce&&(qc=!0),S!==null&&(S=S.next={lane:0,tag:c.tag,payload:c.payload,callback:null,next:null});l:{var A=l,p=c;r=t;var w=u;switch(p.tag){case 1:if(A=p.payload,typeof A=="function"){z=A.call(w,z,r);break l}z=A;break l;case 3:A.flags=A.flags&-65537|128;case 0:if(A=p.payload,r=typeof A=="function"?A.call(w,z,r):A,r==null)break l;z=K({},z,r);break l;case 2:Uu=!0}}r=c.callback,r!==null&&(l.flags|=64,g&&(l.flags|=8192),g=a.callbacks,g===null?a.callbacks=[r]:g.push(r))}else g={lane:r,tag:c.tag,payload:c.payload,callback:c.callback,next:null},S===null?(m=S=g,f=z):S=S.next=g,i|=r;if(c=c.next,c===null){if(c=a.shared.pending,c===null)break;g=c,c=g.next,g.next=null,a.lastBaseUpdate=g,a.shared.pending=null}}while(!0);S===null&&(f=z),a.baseState=f,a.firstBaseUpdate=m,a.lastBaseUpdate=S,n===null&&(a.shared.lanes=0),Xu|=i,l.lanes=i,l.memoizedState=z}}function Io(l,t){if(typeof l!="function")throw Error(y(191,l));l.call(t)}function Po(l,t){var u=l.callbacks;if(u!==null)for(l.callbacks=null,l=0;ln?n:8;var i=x.T,c={};c.types=i!==null?i.types:null,x.T=c,uf(l,!1,t,u);try{var f=a(),m=x.S;if(m!==null&&m(c,f),f!==null&&typeof f=="object"&&typeof f.then=="function"){var S=Nm(f,e);Ba(l,t,S,Ct(l))}else Ba(l,t,e,Ct(l))}catch(z){Ba(l,t,{then:function(){},status:"rejected",reason:z},Ct())}finally{V.p=n,i!==null&&c.types!==null&&(i.types=c.types),x.T=i}}function Um(){}function lf(l,t,u,e){if(l.tag!==5)throw Error(y(476));var a=Ur(l).queue;Mr(l,a,t,nu,u===null?Um:function(){return pr(l),u(e)})}function Ur(l){var t=l.memoizedState;if(t!==null)return t;t={memoizedState:nu,baseState:nu,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:hu,lastRenderedState:nu},next:null};var u={};return t.next={memoizedState:u,baseState:u,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:hu,lastRenderedState:u},next:null},l.memoizedState=t,l=l.alternate,l!==null&&(l.memoizedState=t),t}function pr(l){var t=Ur(l);t.next===null&&(t=l.alternate.memoizedState),Ba(l,t.next.queue,{},Ct())}function tf(){return kl(ca)}function Rr(){return Rl().memoizedState}function xr(){return Rl().memoizedState}function pm(l){for(var t=l.return;t!==null;){switch(t.tag){case 24:case 3:var u=Ct();l=pu(u);var e=Ru(t,l,u);e!==null&&(ht(e,t,u),pa(e,t,u)),t={cache:jc()},l.payload=t;return}t=t.return}}function Rm(l,t,u){var e=Ct();u={lane:e,revertLane:0,gesture:null,action:u,hasEagerState:!1,eagerState:null,next:null},Pn(l)?qr(t,u):(u=Tc(l,t,u,e),u!==null&&(ht(u,l,e),Yr(u,t,e)))}function Hr(l,t,u){var e=Ct();Ba(l,t,u,e)}function Ba(l,t,u,e){var a={lane:e,revertLane:0,gesture:null,action:u,hasEagerState:!1,eagerState:null,next:null};if(Pn(l))qr(t,a);else{var n=l.alternate;if(l.lanes===0&&(n===null||n.lanes===0)&&(n=t.lastRenderedReducer,n!==null))try{var i=t.lastRenderedState,c=n(i,u);if(a.hasEagerState=!0,a.eagerState=c,zt(c,i))return Mn(l,t,a,0),bl===null&&jn(),!1}catch{}if(u=Tc(l,t,a,e),u!==null)return ht(u,l,e),Yr(u,t,e),!0}return!1}function uf(l,t,u,e){if(e={lane:2,revertLane:wf(),gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null},Pn(l)){if(t)throw Error(y(479))}else t=Tc(l,u,e,2),t!==null&&ht(t,l,2)}function Pn(l){var t=l.alternate;return l===J||t!==null&&t===J}function qr(l,t){Xe=Jn=!0;var u=l.pending;u===null?t.next=t:(t.next=u.next,u.next=t),l.pending=t}function Yr(l,t,u){if((u&4194048)!==0){var e=t.lanes;e&=l.pendingLanes,u|=e,t.lanes=u,Ys(l,u)}}var li={readContext:kl,use:Fn,useCallback:jl,useContext:jl,useEffect:jl,useImperativeHandle:jl,useLayoutEffect:jl,useInsertionEffect:jl,useMemo:jl,useReducer:jl,useRef:jl,useState:jl,useDebugValue:jl,useDeferredValue:jl,useTransition:jl,useSyncExternalStore:jl,useId:jl,useHostTransitionStatus:jl,useFormState:jl,useActionState:jl,useOptimistic:jl,useMemoCache:jl,useCacheRefresh:jl,useEffectEvent:jl},Br={readContext:kl,use:Fn,useCallback:function(l,t){return ct().memoizedState=[l,t===void 0?null:t],l},useContext:kl,useEffect:Er,useImperativeHandle:function(l,t,u){u=u!=null?u.concat([l]):null,kn(4194308,4,Nr.bind(null,t,l),u)},useLayoutEffect:function(l,t){return kn(4194308,4,l,t)},useInsertionEffect:function(l,t){kn(4,2,l,t)},useMemo:function(l,t){var u=ct();t=t===void 0?null:t;var e=l();if(de){_u(!0);try{l()}finally{_u(!1)}}return u.memoizedState=[e,t],e},useReducer:function(l,t,u){var e=ct();if(u!==void 0){var a=u(t);if(de){_u(!0);try{u(t)}finally{_u(!1)}}}else a=t;return e.memoizedState=e.baseState=a,l={pending:null,lanes:0,dispatch:null,lastRenderedReducer:l,lastRenderedState:a},e.queue=l,l=l.dispatch=Rm.bind(null,J,l),[e.memoizedState,l]},useRef:function(l){var t=ct();return l={current:l},t.memoizedState=l},useState:function(l){l=Fc(l);var t=l.queue,u=Hr.bind(null,J,t);return t.dispatch=u,[l.memoizedState,u]},useDebugValue:Ic,useDeferredValue:function(l,t){var u=ct();return Pc(u,l,t)},useTransition:function(){var l=Fc(!1);return l=Mr.bind(null,J,l.queue,!0,!1),ct().memoizedState=l,[!1,l]},useSyncExternalStore:function(l,t,u){var e=J,a=ct();if(W){if(u===void 0)throw Error(y(407));u=u()}else{if(u=t(),bl===null)throw Error(y(349));(ll&127)!==0||nr(e,t,u)}a.memoizedState=u;var n={value:u,getSnapshot:t};return a.queue=n,Er(cr.bind(null,e,n,l),[l]),e.flags|=2048,Ve(9,{destroy:void 0},ir.bind(null,e,n,u,t),null),u},useId:function(){var l=ct(),t=bl.identifierPrefix;if(W){var u=Wt,e=Ft;u=(e&~(1<<32-Tt(e)-1)).toString(32)+u,t="_"+t+"R_"+u,u=wn++,0<\/script>",n=n.removeChild(n.firstChild);break;case"select":n=typeof e.is=="string"?i.createElement("select",{is:e.is}):i.createElement("select"),e.multiple?n.multiple=!0:e.size&&(n.size=e.size);break;default:n=typeof e.is=="string"?i.createElement(a,{is:e.is}):i.createElement(a)}}n[Wl]=t,n[rt]=e;l:for(i=t.child;i!==null;){if(i.tag===5||i.tag===6)n.appendChild(i.stateNode);else if(i.tag!==4&&i.tag!==27&&i.child!==null){i.child.return=i,i=i.child;continue}if(i===t)break l;for(;i.sibling===null;){if(i.return===null||i.return===t)break l;i=i.return}i.sibling.return=i.return,i=i.sibling}t.stateNode=n;l:switch(tt(n,a,e),a){case"button":case"input":case"select":case"textarea":e=!!e.autoFocus;break l;case"img":e=!0;break l;default:e=!1}e&&Su(t)}}return zl(t),t.subtreeFlags&=-33554433,hf(t,t.type,l===null?null:l.memoizedProps,t.pendingProps,u),null;case 6:if(l&&t.stateNode!=null)l.memoizedProps!==e&&Su(t);else{if(typeof e!="string"&&t.stateNode===null)throw Error(y(166));if(l=Eu.current,qe(t)){if(l=t.stateNode,u=t.memoizedProps,e=null,a=Jl,a!==null)switch(a.tag){case 27:case 5:e=a.memoizedProps}l[Wl]=t,l=!!(l.nodeValue===u||e!==null&&e.suppressHydrationWarning===!0||c0(l.nodeValue,u)),l||Du(t,!0)}else l=ka(l).createTextNode(e),l[Wl]=t,t.stateNode=l}return zl(t),null;case 31:if(u=t.memoizedState,l===null||l.memoizedState!==null){if(e=qe(t),u!==null){if(l===null){if(!e)throw Error(y(318));if(l=t.memoizedState,l=l!==null?l.dehydrated:null,!l)throw Error(y(557));l[Wl]=t}else ee(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;zl(t),l=!1}else u=Ac(),l!==null&&l.memoizedState!==null&&(l.memoizedState.hydrationErrors=u),l=!0;if(!l)return t.flags&256?(_t(t),t):(_t(t),null);if((t.flags&128)!==0)throw Error(y(558))}return zl(t),null;case 13:if(e=t.memoizedState,l===null||l.memoizedState!==null&&l.memoizedState.dehydrated!==null){if(a=qe(t),e!==null&&e.dehydrated!==null){if(l===null){if(!a)throw Error(y(318));if(a=t.memoizedState,a=a!==null?a.dehydrated:null,!a)throw Error(y(317));a[Wl]=t}else ee(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;zl(t),a=!1}else a=Ac(),l!==null&&l.memoizedState!==null&&(l.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(_t(t),t):(_t(t),null)}return _t(t),(t.flags&128)!==0?(t.lanes=u,t):(u=e!==null,l=l!==null&&l.memoizedState!==null,u&&(e=t.child,a=null,e.alternate!==null&&e.alternate.memoizedState!==null&&e.alternate.memoizedState.cachePool!==null&&(a=e.alternate.memoizedState.cachePool.pool),n=null,e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(n=e.memoizedState.cachePool.pool),n!==a&&(e.flags|=2048)),u!==l&&u&&(t.child.flags|=8192),ii(t,t.updateQueue),zl(t),null);case 4:return Te(),l===null&&kf(t.stateNode.containerInfo),t.flags|=67108864,zl(t),null;case 10:return mu(t.type),zl(t),null;case 19:if(Xc(t),e=t.memoizedState,e===null)return zl(t),null;if(a=(t.flags&128)!==0,n=e.rendering,n===null)if(a)Xa(e,!1);else{if(Ml!==0||l!==null&&(l.flags&128)!==0)for(l=t.child;l!==null;){if(n=Kn(l),n!==null){for(t.flags|=128,Xa(e,!1),l=n.updateQueue,t.updateQueue=l,ii(t,l),t.subtreeFlags=0,l=u,u=t.child;u!==null;)Ho(u,l),u=u.sibling;return Ha(t,Pl.current&1|2),W&&du(t,e.treeForkCount),t.child}l=l.sibling}e.tail!==null&&St()>Si&&(t.flags|=128,a=!0,Xa(e,!1),t.lanes=4194304)}else{if(!a)if(l=Kn(n),l!==null){if(t.flags|=128,a=!0,l=l.updateQueue,t.updateQueue=l,ii(t,l),Xa(e,!0),e.tail===null&&e.tailMode!=="collapsed"&&e.tailMode!=="visible"&&!n.alternate&&!W)return zl(t),null}else 2*St()-e.renderingStartTime>Si&&u!==536870912&&(t.flags|=128,a=!0,Xa(e,!1),t.lanes=4194304);e.isBackwards?(n.sibling=t.child,t.child=n):(l=e.last,l!==null?l.sibling=n:t.child=n,e.last=n)}if(e.tail!==null){l=e.tail;l:{for(u=l;u!==null;){if(u.alternate!==null){u=!1;break l}u=u.sibling}u=!0}return e.rendering=l,e.tail=l.sibling,e.renderingStartTime=St(),l.sibling=null,n=Pl.current,n=a?n&1|2:n&1,e.tailMode==="visible"||e.tailMode==="collapsed"||!u||W?Ha(t,n):(u=n,Tl(Il,t),Tl(Pl,u),nt===null&&(nt=t)),W&&du(t,e.treeForkCount),l}return zl(t),null;case 22:case 23:return _t(t),Bc(),e=t.memoizedState!==null,l!==null?l.memoizedState!==null!==e&&(t.flags|=8192):e&&(t.flags|=8192),e?(u&536870912)!==0&&(t.flags&128)===0&&(zl(t),t.subtreeFlags&6&&(t.flags|=8192)):zl(t),u=t.updateQueue,u!==null&&ii(t,u.retryQueue),u=null,l!==null&&l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(u=l.memoizedState.cachePool.pool),e=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(e=t.memoizedState.cachePool.pool),e!==u&&(t.flags|=2048),l!==null&&Fl(fe),null;case 24:return u=null,l!==null&&(u=l.memoizedState.cache),t.memoizedState.cache!==u&&(t.flags|=2048),mu(Hl),zl(t),null;case 25:return null;case 30:return t.flags|=33554432,zl(t),null}throw Error(y(156,t.tag))}function Xm(l,t){switch(Oc(t),t.tag){case 1:return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 3:return mu(Hl),Te(),l=t.flags,(l&65536)!==0&&(l&128)===0?(t.flags=l&-65537|128,t):null;case 26:case 27:case 5:return rn(t),null;case 31:if(t.memoizedState!==null){if(_t(t),t.alternate===null)throw Error(y(340));ee()}return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 13:if(_t(t),l=t.memoizedState,l!==null&&l.dehydrated!==null){if(t.alternate===null)throw Error(y(340));ee()}return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 19:return Xc(t),l=t.flags,l&65536?(t.flags=l&-65537|128,l=t.memoizedState,l!==null&&(l.rendering=null,l.tail=null),t.flags|=4,t):null;case 4:return Te(),null;case 10:return mu(t.type),null;case 22:case 23:return _t(t),Bc(),l!==null&&Fl(fe),l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 24:return mu(Hl),null;case 25:return null;default:return null}}function sd(l,t){switch(Oc(t),t.tag){case 3:mu(Hl),Te();break;case 26:case 27:case 5:rn(t);break;case 4:Te();break;case 31:t.memoizedState!==null&&_t(t);break;case 13:_t(t);break;case 19:Xc(t);break;case 10:mu(t.type);break;case 22:case 23:_t(t),Bc(),l!==null&&Fl(fe);break;case 24:mu(Hl)}}function Qa(l,t){try{var u=t.updateQueue,e=u!==null?u.lastEffect:null;if(e!==null){var a=e.next;u=a;do{if((u.tag&l)===l){e=void 0;var n=u.create,i=u.inst;e=n(),i.destroy=e}u=u.next}while(u!==a)}}catch(c){ml(t,t.return,c)}}function Yu(l,t,u){try{var e=t.updateQueue,a=e!==null?e.lastEffect:null;if(a!==null){var n=a.next;e=n;do{if((e.tag&l)===l){var i=e.inst,c=i.destroy;if(c!==void 0){i.destroy=void 0,a=t;var f=u,m=c;try{m()}catch(S){ml(a,f,S)}}}e=e.next}while(e!==n)}}catch(S){ml(t,t.return,S)}}function od(l){var t=l.updateQueue;if(t!==null){var u=l.stateNode;try{Po(t,u)}catch(e){ml(l,l.return,e)}}}function rd(l,t,u){u.props=ve(l.type,l.memoizedProps),u.state=l.memoizedState;try{u.componentWillUnmount()}catch(e){ml(l,t,e)}}function kt(l,t){try{var u=l.ref;if(u!==null){switch(l.tag){case 26:case 27:case 5:var e=l.stateNode;break;case 30:var a=l.stateNode,n=su(l.memoizedProps,a);(a.ref===null||a.ref.name!==n)&&(a.ref=S0(n)),e=a.ref;break;case 7:if(l.stateNode===null){var i=new Dt(l);b(l.child,!1,My,i,void 0,void 0),l.stateNode=i}e=l.stateNode;break;default:e=l.stateNode}typeof u=="function"?l.refCleanup=u(e):u.current=e}}catch(c){ml(l,t,c)}}function lt(l,t){var u=l.ref,e=l.refCleanup;if(u!==null)if(typeof e=="function")try{e()}catch(a){ml(l,t,a)}finally{l.refCleanup=null,l=l.alternate,l!=null&&(l.refCleanup=null)}else if(typeof u=="function")try{u(null)}catch(a){ml(l,t,a)}else u.current=null}function ci(l,t){if((l.tag===5||l.tag===27||l.tag===6)&&l.alternate===null&&t!==null)for(var u=0;u title"))),tt(e,t,u),e[Wl]=l,Kl(e),t=e;break l;case"link":if(n=H0("link","href",a).get(t+(u.href||""))){for(i=0;iw&&(i=w,w=p,p=i);var v=_o(c,p),o=_o(c,w);if(v&&o&&(g.rangeCount!==1||g.anchorNode!==v.node||g.anchorOffset!==v.offset||g.focusNode!==o.node||g.focusOffset!==o.offset)){var h=z.createRange();h.setStart(v.node,v.offset),g.removeAllRanges(),p>w?(g.addRange(h),g.extend(o.node,o.offset)):(h.setEnd(o.node,o.offset),g.addRange(h))}}}}for(z=[],g=c;g=g.parentNode;)g.nodeType===1&&z.push({element:g,left:g.scrollLeft,top:g.scrollTop});for(typeof c.focus=="function"&&c.focus(),c=0;cu?32:u,x.T=null,u=Yf,Yf=null;var n=Lt,i=eu;if(Cl=0,ge=Lt=null,eu=0,(ol&6)!==0)throw Error(y(331));var c=ol;if(ol|=4,xd(n.current),Ud(n,n.current,i,u),ol=c,$a(0,!1),bt&&typeof bt.onPostCommitFiberRoot=="function")try{bt.onPostCommitFiberRoot(da,n)}catch{}return!0}finally{V.p=a,x.T=e,Fd(l,t)}}function Wd(l,t,u){t=pt(u,t),t=nf(l.stateNode,t,2),l=Ru(l,t,2),l!==null&&(ma(l,2),au(l))}function ml(l,t,u){if(l.tag===3)Wd(l,l,u);else for(;t!==null;){if(t.tag===3){Wd(t,l,u);break}else if(t.tag===1){var e=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof e.componentDidCatch=="function"&&(Qu===null||!Qu.has(e))){l=pt(u,l),u=Jr(2),e=Ru(t,u,2),e!==null&&(wr(u,e,t,l),ma(e,2),au(e));break}}t=t.return}}function Lf(l,t,u){var e=l.pingCache;if(e===null){e=l.pingCache=new Lm;var a=new Set;e.set(t,a)}else a=e.get(t),a===void 0&&(a=new Set,e.set(t,a));a.has(u)||(xf=!0,a.add(u),l=Im.bind(null,l,t,u),t.then(l,l))}function Im(l,t,u){var e=l.pingCache;e!==null&&e.delete(t),l.pingedLanes|=l.suspendedLanes&u,l.warmLanes&=~u,bl===l&&(ll&u)===u&&((Ml===4||Ml===3&&(ll&62914560)===ll&&300>St()-gi)&&(ol&2)===0?Pe(l,0):hi|=u,$e===ll&&($e=0)),au(l)}function kd(l,t){t===0&&(t=Hs()),l=te(l,t),l!==null&&(ma(l,t),au(l))}function Pm(l){var t=l.memoizedState,u=0;t!==null&&(u=t.retryLane),kd(l,u)}function ly(l,t){var u=0;switch(l.tag){case 31:case 13:var e=l.stateNode,a=l.memoizedState;a!==null&&(u=a.retryLane);break;case 19:e=l.stateNode;break;case 22:e=l.stateNode._retryCache;break;default:throw Error(y(314))}e!==null&&e.delete(t),kd(l,u)}function ty(l,t){return Ji(l,t)}var ta=null,ua=null,Kf=!1,Ni=!1,Jf=!1,Zu=0;function au(l){l!==ua&&l.next===null&&(ua===null?ta=ua=l:ua=ua.next=l),Ni=!0,Kf||(Kf=!0,ey())}function $a(l,t){if(!Jf&&Ni){Jf=!0;do for(var u=!1,e=ta;e!==null;){if(l!==0){var a=e.pendingLanes;if(a===0)var n=0;else{var i=e.suspendedLanes,c=e.pingedLanes;n=(1<<31-Tt(42|l)+1)-1,n&=a&~(i&~c),n=n&201326741?n&201326741|1:n?n|2:0}n!==0&&(u=!0,t0(e,n))}else n=ll,n=hn(e,e===bl?n:0,e.cancelPendingCommit!==null||e.timeoutHandle!==-1),(n&3)===0||va(e,n)||(u=!0,t0(e,n));e=e.next}while(u);Jf=!1}}function uy(){Id()}function Id(){Ni=Kf=!1;var l=0;Zu!==0&&my()&&(l=Zu);for(var t=St(),u=null,e=ta;e!==null;){var a=e.next,n=Pd(e,t);n===0?(e.next=null,u===null?ta=a:u.next=a,a===null&&(ua=u)):(u=e,(l!==0||(n&3)!==0)&&(Ni=!0)),e=a}Cl!==0&&Cl!==5||$a(l),Zu!==0&&(Zu=0)}function Pd(l,t){for(var u=l.suspendedLanes,e=l.pingedLanes,a=l.expirationTimes,n=l.pendingLanes&-62914561;0c)break;var S=f.transferSize,z=f.initiatorType;S&&f0(z)&&(f=f.responseEnd,i+=S*(fMi){p.length=A;break}h=new Promise(Ty.bind(h)),p.push(h)}}}if(0"u"?null:document;function U0(l,t,u){var e=aa;if(e&&typeof t=="string"&&t){var a=Mt(t);a='link[rel="'+l+'"][href="'+a+'"]',typeof u=="string"&&(a+='[crossorigin="'+u+'"]'),M0.has(a)||(M0.add(a),l={rel:l,crossOrigin:u,href:t},e.querySelector(a)===null&&(t=e.createElement("link"),tt(t,"link",l),Kl(t),e.head.appendChild(t)))}}function Gy(l){Tu.D(l),U0("dns-prefetch",l,null)}function Xy(l,t){Tu.C(l,t),U0("preconnect",l,t)}function Qy(l,t,u){Tu.L(l,t,u);var e=aa;if(e&&l&&t){var a='link[rel="preload"][as="'+Mt(t)+'"]';t==="image"&&u&&u.imageSrcSet?(a+='[imagesrcset="'+Mt(u.imageSrcSet)+'"]',typeof u.imageSizes=="string"&&(a+='[imagesizes="'+Mt(u.imageSizes)+'"]')):a+='[href="'+Mt(l)+'"]';var n=a;switch(t){case"style":n=na(l);break;case"script":n=ia(l)}if(!(Bt.has(n)||(l=K({rel:"preload",href:t==="image"&&u&&u.imageSrcSet?void 0:l,as:t},u),Bt.set(n,l),e.querySelector(a)!==null||t==="style"&&e.querySelector(Pa(n))||t==="script"&&e.querySelector(ln(n))))){var i=e.createElement("link");tt(i,"link",l),t==="style"&&(i[gn]=!0,i.onload=i.onerror=function(){Zs(i)}),Kl(i),e.head.appendChild(i)}}}function Vy(l,t){Tu.m(l,t);var u=aa;if(u&&l){var e=t&&typeof t.as=="string"?t.as:"script",a='link[rel="modulepreload"][as="'+Mt(e)+'"][href="'+Mt(l)+'"]',n=a;switch(e){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":n=ia(l)}if(!Bt.has(n)&&(l=K({rel:"modulepreload",href:l},t),Bt.set(n,l),u.querySelector(a)===null)){switch(e){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(u.querySelector(ln(n)))return}e=u.createElement("link"),tt(e,"link",l),Kl(e),u.head.appendChild(e)}}}function Zy(l,t,u){Tu.S(l,t,u);var e=aa;if(e&&l){var a=_e(e).hoistableStyles,n=na(l);t=t||"default";var i=a.get(n);if(!i){var c={loading:0,preload:null};if(i=e.querySelector(Pa(n)))c.loading=5;else{l=K({rel:"stylesheet",href:l,"data-precedence":t},u),(u=Bt.get(n))&&vs(l,u);var f=i=e.createElement("link");Kl(f),tt(f,"link",l),f._p=new Promise(function(m,S){f.onload=m,f.onerror=S}),f.addEventListener("load",function(){c.loading|=1}),f.addEventListener("error",function(){c.loading|=2}),c.loading|=4,Di(i,t,e)}i={type:"stylesheet",instance:i,count:1,state:c},a.set(n,i)}}}function Ly(l,t){Tu.X(l,t);var u=aa;if(u&&l){var e=_e(u).hoistableScripts,a=ia(l),n=e.get(a);n||(n=u.querySelector(ln(a)),n||(l=K({src:l,async:!0},t),(t=Bt.get(a))&&ms(l,t),n=u.createElement("script"),Kl(n),tt(n,"link",l),u.head.appendChild(n)),n={type:"script",instance:n,count:1,state:null},e.set(a,n))}}function Ky(l,t){Tu.M(l,t);var u=aa;if(u&&l){var e=_e(u).hoistableScripts,a=ia(l),n=e.get(a);n||(n=u.querySelector(ln(a)),n||(l=K({src:l,async:!0,type:"module"},t),(t=Bt.get(a))&&ms(l,t),n=u.createElement("script"),Kl(n),tt(n,"link",l),u.head.appendChild(n)),n={type:"script",instance:n,count:1,state:null},e.set(a,n))}}function p0(l,t,u,e){var a=(a=Eu.current)?Ia(a):null;if(!a)throw Error(y(446));switch(l){case"meta":case"title":return null;case"style":return typeof u.precedence=="string"&&typeof u.href=="string"?(u=na(u.href),t=_e(a).hoistableStyles,e=t.get(u),e||(e={type:"style",instance:null,count:0,state:null},t.set(u,e)),e):{type:"void",instance:null,count:0,state:null};case"link":if(u.rel==="stylesheet"&&typeof u.href=="string"&&typeof u.precedence=="string"){l=na(u.href);var n=_e(a).hoistableStyles,i=n.get(l);if(i||(a=a.ownerDocument||a,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},n.set(l,i),(n=a.querySelector(Pa(l)))?n._p||(i.instance=n,i.state.loading=5):(n=Bt.get(l),n||(n={rel:"preload",as:"style",href:u.href,crossOrigin:u.crossOrigin,integrity:u.integrity,media:u.media,hrefLang:u.hrefLang,referrerPolicy:u.referrerPolicy},Bt.set(l,n)),Jy(a,l,n,i.state))),t&&e===null)throw Error(y(528,""));return i}if(t&&e!==null)throw Error(y(529,""));return null;case"script":return t=u.async,u=u.src,typeof u=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(u=ia(u),t=_e(a).hoistableScripts,e=t.get(u),e||(e={type:"script",instance:null,count:0,state:null},t.set(u,e)),e):{type:"void",instance:null,count:0,state:null};default:throw Error(y(444,l))}}function na(l){return'href="'+Mt(l)+'"'}function Pa(l){return'link[rel="stylesheet"]['+l+"]"}function R0(l){return K({},l,{"data-precedence":l.precedence,precedence:null})}function Jy(l,t,u,e){if(t=l.querySelector('link[rel="preload"][as="style"]['+t+"]")){if(t[gn]!==!0){e.loading=1;return}}else t=l.createElement("link"),t[gn]=!0,t.onload=t.onerror=Zs.bind(null,t),tt(t,"link",u),Kl(t),l.head.appendChild(t);e.preload=t,t.addEventListener("load",function(){return e.loading|=1}),t.addEventListener("error",function(){return e.loading|=2})}function ia(l){return'[src="'+Mt(l)+'"]'}function ln(l){return"script[async]"+l}function x0(l,t,u){if(t.count++,t.instance===null)switch(t.type){case"style":var e=l.querySelector('style[data-href~="'+Mt(u.href)+'"]');if(e)return t.instance=e,Kl(e),e;var a=K({},u,{"data-href":u.href,"data-precedence":u.precedence,href:null,precedence:null});return e=(l.ownerDocument||l).createElement("style"),Kl(e),tt(e,"style",a),Di(e,u.precedence,l),t.instance=e;case"stylesheet":a=na(u.href);var n=l.querySelector(Pa(a));if(n)return t.state.loading|=4,t.instance=n,Kl(n),n;e=R0(u),(a=Bt.get(a))&&vs(e,a),n=(l.ownerDocument||l).createElement("link"),Kl(n);var i=n;return i._p=new Promise(function(c,f){i.onload=c,i.onerror=f}),tt(n,"link",e),t.state.loading|=4,Di(n,u.precedence,l),t.instance=n;case"script":return n=ia(u.src),(a=l.querySelector(ln(n)))?(t.instance=a,Kl(a),a):(e=u,(a=Bt.get(n))&&(e=K({},u),ms(e,a)),l=l.ownerDocument||l,a=l.createElement("script"),Kl(a),tt(a,"link",e),l.head.appendChild(a),t.instance=a);case"void":return null;default:throw Error(y(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(e=t.instance,t.state.loading|=4,Di(e,u.precedence,l));return t.instance}function Di(l,t,u){for(var e=u.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),a=e.length?e[e.length-1]:null,n=a,i=0;i title"):null)}function wy(l,t,u){if(u===1||t.itemProp!=null)return!1;switch(l){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;return t.rel==="stylesheet"?(l=t.disabled,typeof t.precedence=="string"&&l==null):!0;case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function q0(l,t){return l==="img"&&t.src!=null&&t.src!==""&&t.onLoad==null&&t.loading!=="lazy"}function Y0(l){return!(l.type==="stylesheet"&&(l.state.loading&3)===0)}function B0(l){return(l.width||100)*(l.height||100)*(typeof devicePixelRatio=="number"?devicePixelRatio:1)*.25}function G0(l,t){typeof t.decode=="function"&&(l.imgCount++,t.complete||(l.imgBytes+=B0(t),l.suspenseyImages.push(t)),l=Wy.bind(l),t.decode().then(l,l))}function $y(l,t,u,e){if(u.type==="stylesheet"&&(typeof e.media!="string"||matchMedia(e.media).matches!==!1)&&(u.state.loading&4)===0){if(u.instance===null){var a=na(e.href),n=t.querySelector(Pa(a));if(n){t=n._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(l.count++,l=tn.bind(l),t.then(l,l)),u.state.loading|=4,u.instance=n,Kl(n);return}n=t.ownerDocument||t,e=R0(e),(a=Bt.get(a))&&vs(e,a),n=n.createElement("link"),Kl(n);var i=n;i._p=new Promise(function(c,f){i.onload=c,i.onerror=f}),tt(n,"link",e),u.instance=n}l.stylesheets===null&&(l.stylesheets=new Map),l.stylesheets.set(u,t),(t=u.state.preload)&&(u.state.loading&3)===0&&(l.count++,u=tn.bind(l),t.addEventListener("load",u),t.addEventListener("error",u))}}var Mi=0;function Fy(l,t){return l.stylesheets&&l.count===0&&pi(l,l.stylesheets),0Mi?50:800)+t);return l.unsuspend=u,function(){l.unsuspend=null,clearTimeout(e),clearTimeout(a)}}:null}function X0(l){if(l.count===0&&(l.imgCount===0||!l.waitingForImages)){if(l.stylesheets)pi(l,l.stylesheets);else if(l.unsuspend){var t=l.unsuspend;l.unsuspend=null,t()}}}function tn(){this.count--,X0(this)}function Wy(){this.imgCount--,X0(this)}var Ui=null;function pi(l,t){l.stylesheets=null,l.unsuspend!==null&&(l.count++,Ui=new Map,t.forEach(ky,l),Ui=null,tn.call(l))}function ky(l,t){if(!(t.state.loading&4)){var u=Ui.get(l);if(u)var e=u.get(null);else{u=new Map,Ui.set(l,u);for(var a=l.querySelectorAll("link[data-precedence],style[data-precedence]"),n=0;n"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(_)}catch(G){console.error(G)}}return _(),Os.exports=vh(),Os.exports}var yh=mh();async function oa(_,G){const Y=await fetch("/api/"+_,G===void 0?{}:{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(G)});if(!Y.ok){let y;try{const q=await Y.json();y=typeof q.detail=="string"?q.detail:JSON.stringify(q.detail)}catch{y=await Y.text().catch(()=>Y.statusText)}throw new Error(y||"Le serveur ne répond pas.")}return Y.json()}const Gi=(_,G,Y=!1,y="")=>"/api/image?"+new URLSearchParams({copy:_,label:G,body:String(Y),v:y}),fn=(_,G,Y="")=>"/api/document?"+new URLSearchParams({copy:_,kind:G,label:Y}),Gt=(_,G="",Y="")=>JSON.stringify([_,G,Y]);function hh(){const[_,G]=Sl.useState(null),[Y,y]=Sl.useState(""),[q,$]=Sl.useState(""),[rl,Gl]=Sl.useState(""),[ul,Dl]=Sl.useState(""),[R,b]=Sl.useState(20),[M,_l]=Sl.useState({}),[Xl,Ul]=Sl.useState(!1),[il,et]=Sl.useState(!1),[Ol,gt]=Sl.useState(null),[Ql,at]=Sl.useState(null),[xl,K]=Sl.useState(!1),F=async()=>{try{G(await oa("state")),y("")}catch(O){y(String(O))}};Sl.useEffect(()=>{F()},[]),Sl.useEffect(()=>{const O=N=>{Object.keys(M).length&&(N.preventDefault(),N.returnValue="")};return window.addEventListener("beforeunload",O),()=>window.removeEventListener("beforeunload",O)},[M]),Sl.useEffect(()=>{if(!_?.job.running)return;const O=setInterval(async()=>{try{const N=await oa("job");G(s=>s&&{...s,job:N}),N.running||(await F(),$(N.status==="success"?"Les sorties ont été régénérées.":"La régénération est incomplète. Consultez le journal."))}catch(N){y(String(N))}},1e3);return()=>clearInterval(O)},[_?.job.running]);const Vl=(O,N,s,E)=>M[Gt(O,N,s)]?.value??E,Nl=(O,N,s,E)=>_l(D=>({...D,[Gt(O,N,s)]:{kind:O,copy:N,label:s,value:E}})),pl=async O=>{if(!_)return;Ul(!0),y("");let N=_;try{for(const s of O){const E=M[s];E&&(N=await oa("change",{...E,revision:N.revision}),G(N),_l(D=>{const j={...D};return delete j[s],j}))}$("Modifications enregistrées.")}catch(s){y(String(s))}finally{Ul(!1)}},Ll=async()=>{if(_){Ul(!0),y("");try{const O=await oa("regenerate",{revision:_.revision,apply_draft:il});G({..._,job:O}),$("")}catch(O){y(String(O))}finally{Ul(!1)}}},jt=async()=>{try{await oa("stop",{}),K(!0)}catch(O){y(String(O))}};if(xl)return d.jsxs("main",{className:"end",children:[d.jsx("h1",{children:"Session terminée"}),d.jsx("p",{children:"Vous pouvez reprendre le travail dans Copienator."})]});if(!_)return d.jsxs("main",{className:"end",children:[d.jsx("h1",{children:"Copienator"}),d.jsx("p",{children:Y||"Chargement de la finalisation…"}),d.jsx("button",{onClick:F,children:"Réessayer"})]});const L=Xl||_.job.running,hl=Object.keys(M).length,C=Vl("draft","","",_.draft),B=_.draft.trim()!==_.applied.trim(),X=_.copies.filter(O=>!rl||Number(O.id)===Number(rl)),cl=X.flatMap(O=>O.answers.filter(N=>!ul||N.label===ul).map(N=>({c:O,a:N}))),el=new Map;_.copies.forEach(O=>el.set(O.name.toLowerCase(),(el.get(O.name.toLowerCase())||0)+1));const ot=_.copies.filter(O=>O.name.toLowerCase()==="unknown"||(el.get(O.name.toLowerCase())||0)>1);return d.jsxs(d.Fragment,{children:[d.jsxs("header",{inert:!!Ol||!!Ql,children:[d.jsxs("div",{className:"brand",children:["C",d.jsx("span",{children:"Copienator"})]}),d.jsxs("div",{className:"heading",children:[d.jsxs("div",{className:"eyebrow",children:["FINALISATION · ",_.mode]}),d.jsx("h1",{children:_.evaluation})]}),d.jsx("button",{className:"quiet",disabled:L||!!hl,onClick:jt,children:"Fermer et reprendre dans le GUI"})]}),d.jsxs("main",{inert:!!Ol||!!Ql,children:[d.jsxs("section",{className:"toolbar",children:[d.jsxs("div",{children:[d.jsx("h2",{children:"Vérifier les copies"}),d.jsx("p",{children:"Retrouvez une copie, une question, ou leur intersection."})]}),d.jsxs("div",{className:"filters",children:[d.jsxs("label",{children:["Copie",d.jsx("input",{type:"text",inputMode:"numeric",list:"copies",placeholder:"Toutes les copies",value:rl,onChange:O=>{Gl(O.target.value.replace(/\D/g,"")),b(20)}})]}),d.jsx("datalist",{id:"copies",children:_.copies.map(O=>d.jsx("option",{value:O.id,children:O.name},O.id))}),d.jsxs("label",{children:["Label",d.jsxs("select",{value:ul,onChange:O=>{Dl(O.target.value),b(20)},children:[d.jsx("option",{value:"",children:"Tous les labels"}),_.labels.map(O=>d.jsx("option",{children:O},O))]})]}),d.jsx("button",{onClick:()=>{Gl(""),Dl(""),b(20)},children:"Réinitialiser"})]})]}),Y&&d.jsxs("div",{role:"alert",className:"alert",children:[Y,d.jsx("button",{onClick:F,children:"Recharger les données"}),d.jsx("small",{children:"Les saisies non enregistrées restent dans la page."})]}),q&&d.jsx("p",{role:"status",className:"notice",children:q}),d.jsxs("section",{className:"publish",children:[d.jsxs("div",{children:[d.jsx("strong",{children:_.job.running?"Régénération en cours…":hl?`${hl} modification(s) non enregistrée(s)`:_.dirty?"Enregistré · sorties à régénérer":"Modifications enregistrées"}),d.jsx("small",{children:"Les sorties comprennent les images, PDF et le dossier A Rendre configurés."})]}),d.jsx("button",{disabled:L||!hl,onClick:()=>pl(Object.keys(M)),children:"Tout enregistrer"}),hl>0&&d.jsx("button",{disabled:L,onClick:()=>_l({}),children:"Annuler les saisies"}),d.jsxs("label",{className:"check",children:[d.jsx("input",{type:"checkbox",checked:il,disabled:L,onChange:O=>et(O.target.checked)}),"Appliquer aussi le brouillon de transferts",B?" (différent du résultat actuel)":""]}),d.jsx("button",{className:"primary",disabled:L||!!hl,onClick:Ll,children:"Régénérer les sorties"})]}),d.jsxs("fieldset",{disabled:L,children:[d.jsxs("details",{className:"panel",children:[d.jsxs("summary",{children:["Identités et remarques générales ",d.jsxs("span",{children:[ot.length," nom(s) à vérifier"]})]}),d.jsx("p",{children:"Les remarques sont composées en LaTeX. Leur ordre est celui de la liste."}),X.map(O=>{const N=Vl("general",O.id,"",O.general),s=E=>Nl("general",O.id,"",E);return d.jsxs("section",{className:"identity",children:[d.jsxs("div",{className:"identity-name",children:[d.jsxs("strong",{children:["Copie ",O.id]}),d.jsxs("label",{children:["Nom",d.jsx("input",{value:Vl("name",O.id,"",O.name),onChange:E=>Nl("name",O.id,"",E.target.value)})]}),ot.includes(O)&&d.jsx("span",{className:"badge warning",children:"Nom à vérifier"}),d.jsx("a",{target:"_blank",rel:"noreferrer",href:fn(O.id,"original"),children:"Voir l’originale ↗"}),d.jsx("button",{disabled:!M[Gt("name",O.id)],onClick:()=>pl([Gt("name",O.id)]),children:"Enregistrer le nom"})]}),d.jsxs("div",{className:"general",children:[N.map((E,D)=>d.jsxs("div",{className:"remark-row",children:[d.jsx("textarea",{"aria-label":`Remarque générale ${D+1}, copie ${O.id}`,value:E,onChange:j=>s(N.map((k,al)=>D===al?j.target.value:k))}),d.jsx("button",{disabled:D===0,"aria-label":"Monter",onClick:()=>{const j=[...N];[j[D-1],j[D]]=[j[D],j[D-1]],s(j)},children:"↑"}),d.jsx("button",{disabled:D===N.length-1,"aria-label":"Descendre",onClick:()=>{const j=[...N];[j[D+1],j[D]]=[j[D],j[D+1]],s(j)},children:"↓"}),d.jsx("button",{onClick:()=>s(N.filter((j,k)=>k!==D)),children:"Supprimer"})]},D)),d.jsx("button",{onClick:()=>s([...N,""]),children:"+ Remarque générale"}),d.jsx("button",{disabled:!M[Gt("general",O.id)],onClick:()=>pl([Gt("general",O.id)]),children:"Enregistrer les remarques"})]})]},O.id)})]}),d.jsxs("details",{className:"panel",children:[d.jsxs("summary",{children:["Transferts et coupes ",d.jsx("span",{children:B?"Brouillon non appliqué":"Brouillon identique aux modifications appliquées"})]}),d.jsx("p",{children:"Les en-têtes et scores restent à leur label. Enregistrer un brouillon ne l’applique pas. Pour annuler un transfert, retirez sa ligne puis régénérez en cochant « Appliquer aussi le brouillon »."}),d.jsx("div",{className:"draft-list",children:C.split(` -`).map((O,N,s)=>O.trim()&&!O.trim().startsWith("###")?d.jsxs("div",{className:"draft-row",children:[d.jsx("code",{children:O}),d.jsx("button",{"aria-label":`Monter l’instruction ${N}`,disabled:N===0||s[N-1].startsWith("###"),onClick:()=>{const E=[...s];[E[N-1],E[N]]=[E[N],E[N-1]],Nl("draft","","",E.join(` -`))},children:"↑"}),d.jsx("button",{"aria-label":`Descendre l’instruction ${N}`,disabled:N===s.length-1||!s[N+1].trim(),onClick:()=>{const E=[...s];[E[N+1],E[N]]=[E[N],E[N+1]],Nl("draft","","",E.join(` -`))},children:"↓"}),d.jsx("button",{onClick:()=>Nl("draft","","",s.filter((E,D)=>D!==N).join(` -`)),children:"Retirer"})]},N):null)}),d.jsxs("details",{children:[d.jsx("summary",{children:"Éditer les instructions en texte"}),d.jsx("textarea",{className:"instructions","aria-label":"Brouillon des transferts",value:C,onChange:O=>Nl("draft","","",O.target.value)})]}),d.jsx("button",{disabled:!M[Gt("draft")],onClick:()=>pl([Gt("draft")]),children:"Enregistrer le brouillon"}),d.jsxs("details",{children:[d.jsx("summary",{children:"Instructions actuellement appliquées"}),d.jsx("pre",{children:_.applied})]})]}),d.jsxs("div",{className:"results",children:[d.jsxs("h2",{children:[cl.length," réponse",cl.length!==1?"s":""]}),d.jsx("span",{children:!rl&&!ul?"Vue d’ensemble · sélectionnez une copie ou un label pour cibler la vérification":"Images annotées après lecture manuscrite"})]}),d.jsx("div",{className:"answer-grid",children:cl.slice(0,R).map(({c:O,a:N})=>d.jsxs("article",{className:"answer",children:[d.jsxs("div",{className:"card-heading",children:[d.jsxs("div",{children:[d.jsxs("span",{className:"eyebrow",children:["COPIE ",O.id," · ",O.name]}),d.jsx("h3",{children:N.label})]}),d.jsx("span",{className:"badge",children:N.info.present?N.info.not_empty?N.info.touched?"Dans le PDF":"Hors PDF filtré":"Réponse vide":"Absente"})]}),d.jsx("div",{className:"image-space",children:N.image?d.jsxs("button",{className:"image-button","aria-label":`Agrandir copie ${O.id} ${N.label}`,onClick:()=>at({copy:O.id,label:N.label}),children:[d.jsx("img",{loading:"lazy",src:Gi(O.id,N.label,!1,_.revision),alt:`Réponse annotée — copie ${O.id}, ${N.label}`}),d.jsx("span",{children:"Agrandir ↗"})]}):d.jsx("p",{className:"empty",children:"Aucune image pour ce label."})}),d.jsxs("div",{className:"answer-form",children:[d.jsxs("label",{children:["Score",d.jsx("input",{inputMode:"decimal",value:Vl("score",O.id,N.label,N.score),onChange:s=>Nl("score",O.id,N.label,s.target.value)})]}),d.jsxs("label",{children:["Remarque personnelle",d.jsx("textarea",{placeholder:"Ajouter une remarque (LaTeX accepté)",value:Vl("remark",O.id,N.label,N.remark),onChange:s=>Nl("remark",O.id,N.label,s.target.value)})]})]}),d.jsxs("div",{className:"card-actions",children:[d.jsx("button",{disabled:!M[Gt("score",O.id,N.label)]&&!M[Gt("remark",O.id,N.label)],onClick:()=>pl([Gt("score",O.id,N.label),Gt("remark",O.id,N.label)]),children:"Enregistrer"}),d.jsx("button",{disabled:!N.editableBody,onClick:()=>gt({copy:O.id,label:N.label}),children:"Couper / transférer"}),d.jsx("a",{href:fn(O.id,"context",N.label),target:"_blank",rel:"noreferrer",children:"Contexte ↗"}),d.jsx("a",{href:fn(O.id,"question",N.label),target:"_blank",rel:"noreferrer",children:"Énoncé ↗"}),d.jsx("a",{href:fn(O.id,"solution",N.label),target:"_blank",rel:"noreferrer",children:"Corrigé ↗"}),d.jsx("a",{href:fn(O.id,"output"),target:"_blank",rel:"noreferrer",children:"PDF final ↗"})]})]},O.id+"|"+N.label))}),cl.length===0&&d.jsx("p",{className:"empty",children:"Aucune réponse ne correspond à ces filtres."}),cl.length>R&&d.jsx("button",{className:"load-more",onClick:()=>b(R+20),children:"Afficher les 20 suivantes"})]}),(_.job.log||_.job.running)&&d.jsxs("details",{className:"panel",open:_.job.status==="failed",children:[d.jsxs("summary",{children:["Journal de régénération · ",_.job.status==="failed"?"Échec / résultat incomplet":_.job.running?"En cours":"Terminée"]}),d.jsx("pre",{className:"log",children:_.job.log})]})]}),Ol&&d.jsx(Sh,{copy:Ol.copy,source:Ol.label,labels:_.labels,mode:_.mode,revision:_.revision,draft:C,close:()=>gt(null),accept:O=>{Nl("draft","","",O),gt(null),$("Instruction ajoutée au brouillon. Enregistrez-le avant de l’appliquer.")}}),Ql&&d.jsx(gh,{copy:Ql.copy,label:Ql.label,revision:_.revision,close:()=>at(null)})]})}function gh({copy:_,label:G,revision:Y,close:y}){const[q,$]=Sl.useState(100);return Sl.useEffect(()=>{const rl=Gl=>{Gl.key==="Escape"&&y()};return window.addEventListener("keydown",rl),()=>window.removeEventListener("keydown",rl)},[]),d.jsx("div",{className:"overlay",children:d.jsxs("section",{className:"modal viewer",role:"dialog","aria-modal":"true","aria-label":`Copie ${_} ${G}`,children:[d.jsxs("div",{className:"modal-head",children:[d.jsxs("h2",{children:["Copie ",_," · ",G]}),d.jsxs("label",{children:["Zoom ",d.jsx("input",{type:"range",min:"40",max:"200",value:q,onChange:rl=>$(Number(rl.target.value))}),q,"%"]}),d.jsx("button",{autoFocus:!0,onClick:y,children:"Fermer"})]}),d.jsx("div",{className:"zoom-scroll",children:d.jsx("img",{src:Gi(_,G,!1,Y),alt:`Copie ${_}, ${G}`,style:{width:q+"%",maxWidth:"none"}})})]})})}function Sh({copy:_,source:G,labels:Y,mode:y,revision:q,draft:$,close:rl,accept:Gl}){const[ul,Dl]=Sl.useState(Y.find(L=>L!==G)||""),[R,b]=Sl.useState("cut"),[M,_l]=Sl.useState(50),[Xl,Ul]=Sl.useState("1"),[il,et]=Sl.useState(">"),[Ol,gt]=Sl.useState(!1),[Ql,at]=Sl.useState(""),[xl,K]=Sl.useState(null),[F,Vl]=Sl.useState(!1),Nl=R==="cut"?`c{${M}}${Xl}${il}`:R,pl=`Copie${_} ${G} ${Nl} ${Ol?"|":""}${ul}${Ol?"":"|"}`,Ll=$.trimEnd()+` -`+pl+` -`;Sl.useEffect(()=>K(null),[ul,R,M,Xl,il,Ol,$]);const jt=async()=>{Vl(!0),at("");try{K(await oa("preview",{copy:_,source:G,target:ul,text:Ll}))}catch(L){at(String(L))}finally{Vl(!1)}};return d.jsx("div",{className:"overlay",children:d.jsxs("section",{className:"modal",role:"dialog","aria-modal":"true","aria-label":"Couper ou transférer une réponse",children:[d.jsxs("div",{className:"modal-head",children:[d.jsxs("div",{children:[d.jsxs("span",{className:"eyebrow",children:["COPIE ",_," · ",y]}),d.jsx("h2",{children:"Couper ou transférer"})]}),d.jsx("button",{autoFocus:!0,onClick:rl,children:"Fermer"})]}),d.jsx("p",{children:"Seul le corps de la réponse est déplacé. Cliquez sur l’image source pour placer la coupe."}),Ql&&d.jsx("p",{role:"alert",className:"alert",children:Ql}),d.jsxs("div",{className:"cut-controls",children:[d.jsxs("label",{children:["Destination",d.jsx("select",{value:ul,onChange:L=>Dl(L.target.value),children:Y.filter(L=>L!==G).map(L=>d.jsx("option",{children:L},L))})]}),d.jsxs("label",{children:["Opération",d.jsxs("select",{value:R,onChange:L=>b(L.target.value),children:[d.jsx("option",{value:"cut",children:"Couper la source"}),d.jsx("option",{value:"x>",children:"Déplacer et ajouter"}),d.jsx("option",{value:"->",children:"Copier et ajouter"}),d.jsx("option",{value:"xx",children:"Déplacer et remplacer"}),d.jsx("option",{value:"-x",children:"Copier et remplacer"}),d.jsx("option",{value:"xs",children:"Vider la source"}),d.jsx("option",{value:"sx",children:"Vider la cible"}),d.jsx("option",{value:"ss",children:"Conserver les deux"})]})]}),R==="cut"&&d.jsxs(d.Fragment,{children:[d.jsxs("label",{children:["Coupe : ",M,"%",d.jsx("input",{type:"range",min:"1",max:"99",step:"0.1",value:M,onChange:L=>_l(Number(L.target.value))})]}),d.jsxs("label",{children:["Conserver à la source",d.jsxs("select",{value:Xl,onChange:L=>Ul(L.target.value),children:[d.jsx("option",{value:"1",children:"La partie haute"}),d.jsx("option",{value:"2",children:"La partie basse"})]})]}),d.jsxs("label",{children:["À la destination",d.jsxs("select",{value:il,onChange:L=>et(L.target.value),children:[d.jsx("option",{value:">",children:"Ajouter le fragment"}),d.jsx("option",{value:"x",children:"Remplacer le corps"})]})]})]}),d.jsxs("label",{className:"check",children:[d.jsx("input",{type:"checkbox",checked:Ol,onChange:L=>gt(L.target.checked)}),"Placer avant la cible"]})]}),d.jsxs("div",{className:"compare",children:[d.jsxs("div",{children:[d.jsxs("h3",{children:["Source · ",G]}),d.jsxs("div",{className:"cut-image",onClick:L=>{if(R==="cut"){const hl=L.currentTarget.getBoundingClientRect();_l(Math.min(99,Math.max(1,Math.round((L.clientY-hl.top)/hl.height*1e3)/10)))}},children:[d.jsx("img",{src:Gi(_,G,!0,q),alt:"Corps source sans en-tête"}),R==="cut"&&d.jsx("div",{className:"cut-line",style:{top:M+"%"},children:d.jsxs("span",{children:[M,"%"]})})]})]}),d.jsxs("div",{children:[d.jsxs("h3",{children:["Cible · ",ul]}),d.jsx(bh,{copy:_,label:ul,revision:q},ul)]})]}),d.jsx("code",{className:"instruction-line",children:pl}),d.jsxs("div",{className:"modal-actions",children:[d.jsx("button",{disabled:F||!ul,onClick:jt,children:F?"Calcul de l’aperçu…":"Aperçu du résultat"}),d.jsx("button",{className:"primary",disabled:!xl||F,onClick:()=>Gl(Ll),children:"Ajouter au brouillon"})]}),xl&&d.jsxs(d.Fragment,{children:[d.jsx("h3",{children:"Résultat proposé après toutes les instructions du brouillon"}),d.jsx("div",{className:"compare",children:[G,ul].map(L=>d.jsxs("div",{children:[d.jsx("h4",{children:L}),xl[L]?d.jsx("img",{src:xl[L],alt:"Aperçu "+L}):d.jsx("p",{className:"empty",children:"Corps vide"})]},L))})]}),d.jsx("p",{className:"muted",children:"Une instruction par source ; une cible ne peut pas être source. Modifiez ou retirez une instruction existante dans le panneau « Transferts et coupes »."})]})})}function bh({copy:_,label:G,revision:Y}){const[y,q]=Sl.useState(!1);return y?d.jsx("p",{className:"empty",children:"Pas de corps existant. Le transfert peut remplir cette cible."}):d.jsx("img",{src:Gi(_,G,!0,Y),alt:"Corps cible sans en-tête",onError:()=>q(!0)})}yh.createRoot(document.getElementById("root")).render(d.jsx(hh,{})); diff --git a/copienator/web_static/assets/index-D6hPIrMO.js b/copienator/web_static/assets/index-D6hPIrMO.js new file mode 100644 index 0000000..ea279f5 --- /dev/null +++ b/copienator/web_static/assets/index-D6hPIrMO.js @@ -0,0 +1,15 @@ +(function(){const X=document.createElement("link").relList;if(X&&X.supports&&X.supports("modulepreload"))return;for(const B of document.querySelectorAll('link[rel="modulepreload"]'))h(B);new MutationObserver(B=>{for(const $ of B)if($.type==="childList")for(const sl of $.addedNodes)sl.tagName==="LINK"&&sl.rel==="modulepreload"&&h(sl)}).observe(document,{childList:!0,subtree:!0});function G(B){const $={};return B.integrity&&($.integrity=B.integrity),B.referrerPolicy&&($.referrerPolicy=B.referrerPolicy),B.crossOrigin==="use-credentials"?$.credentials="include":B.crossOrigin==="anonymous"?$.credentials="omit":$.credentials="same-origin",$}function h(B){if(B.ep)return;B.ep=!0;const $=G(B);fetch(B.href,$)}})();var zs={exports:{}},cn={};var lv;function iy(){if(lv)return cn;lv=1;var N=Symbol.for("react.transitional.element"),X=Symbol.for("react.fragment");function G(h,B,$){var sl=null;if($!==void 0&&(sl=""+$),B.key!==void 0&&(sl=""+B.key),"key"in B){$={};for(var Bl in B)Bl!=="key"&&($[Bl]=B[Bl])}else $=B;return B=$.ref,{$$typeof:N,type:h,key:sl,ref:B!==void 0?B:null,props:$}}return cn.Fragment=X,cn.jsx=G,cn.jsxs=G,cn}var tv;function cy(){return tv||(tv=1,zs.exports=iy()),zs.exports}var r=cy(),Ns={exports:{}},L={};var ev;function fy(){if(ev)return L;ev=1;var N=Symbol.for("react.transitional.element"),X=Symbol.for("react.portal"),G=Symbol.for("react.fragment"),h=Symbol.for("react.strict_mode"),B=Symbol.for("react.profiler"),$=Symbol.for("react.consumer"),sl=Symbol.for("react.context"),Bl=Symbol.for("react.forward_ref"),el=Symbol.for("react.suspense"),Al=Symbol.for("react.memo"),R=Symbol.for("react.lazy"),T=Symbol.for("react.activity"),M=Symbol.for("react.view_transition"),zl=Symbol.iterator;function Gl(o){return o===null||typeof o!="object"?null:(o=zl&&o[zl]||o["@@iterator"],typeof o=="function"?o:null)}var Dl={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},il=Object.assign,et={};function Nl(o,O,x){this.props=o,this.context=O,this.refs=et,this.updater=x||Dl}Nl.prototype.isReactComponent={},Nl.prototype.setState=function(o,O){if(typeof o!="object"&&typeof o!="function"&&o!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,o,O,"setState")},Nl.prototype.forceUpdate=function(o){this.updater.enqueueForceUpdate(this,o,"forceUpdate")};function St(){}St.prototype=Nl.prototype;function Xl(o,O,x){this.props=o,this.context=O,this.refs=et,this.updater=x||Dl}var ut=Xl.prototype=new St;ut.constructor=Xl,il(ut,Nl.prototype),ut.isPureReactComponent=!0;var Rl=Array.isArray;function K(){}var k={H:null,A:null,T:null,S:null},it=Object.prototype.hasOwnProperty;function Jl(o,O,x){var H=x.ref;return{$$typeof:N,type:o,key:O,ref:H!==void 0?H:null,props:x}}function wl(o,O){return Jl(o.type,O,o.props)}function Ml(o){return typeof o=="object"&&o!==null&&o.$$typeof===N}function at(o){var O={"=":"=0",":":"=2"};return"$"+o.replace(/[=:]/g,function(x){return O[x]})}var Z=/\/+/g;function gl(o,O){return typeof o=="object"&&o!==null&&o.key!=null?at(""+o.key):O.toString(36)}function j(o){switch(o.status){case"fulfilled":return o.value;case"rejected":throw o.reason;default:switch(typeof o.status=="string"?o.then(K,K):(o.status="pending",o.then(function(O){o.status==="pending"&&(o.status="fulfilled",o.value=O)},function(O){o.status==="pending"&&(o.status="rejected",o.reason=O)})),o.status){case"fulfilled":return o.value;case"rejected":throw o.reason}}throw o}function Q(o,O,x,H,F){var b=typeof o;(b==="undefined"||b==="boolean")&&(o=null);var _=!1;if(o===null)_=!0;else switch(b){case"bigint":case"string":case"number":_=!0;break;case"object":switch(o.$$typeof){case N:case X:_=!0;break;case R:return _=o._init,Q(_(o._payload),O,x,H,F)}}if(_)return F=F(o),_=H===""?"."+gl(o,0):H,Rl(F)?(x="",_!=null&&(x=_.replace(Z,"$&/")+"/"),Q(F,O,x,"",function(ol){return ol})):F!=null&&(Ml(F)&&(F=wl(F,x+(F.key==null||o&&o.key===F.key?"":(""+F.key).replace(Z,"$&/")+"/")+_)),O.push(F)),1;_=0;var A=H===""?".":H+":";if(Rl(o))for(var D=0;D>>1,al=j[ul];if(0>>1;ulB(bt,Y))oB(O,bt)?(j[ul]=O,j[o]=Y,ul=o):(j[ul]=bt,j[pt]=Y,ul=pt);else if(oB(O,Y))j[ul]=O,j[o]=Y,ul=o;else break l}}return Q}function B(j,Q){var Y=j.sortIndex-Q.sortIndex;return Y!==0?Y:j.id-Q.id}if(N.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var $=performance;N.unstable_now=function(){return $.now()}}else{var sl=Date,Bl=sl.now();N.unstable_now=function(){return sl.now()-Bl}}var el=[],Al=[],R=1,T=null,M=3,zl=!1,Gl=!1,Dl=!1,il=!1,et=typeof setTimeout=="function"?setTimeout:null,Nl=typeof clearTimeout=="function"?clearTimeout:null,St=typeof setImmediate<"u"?setImmediate:null;function Xl(j){for(var Q=G(Al);Q!==null;){if(Q.callback===null)h(Al);else if(Q.startTime<=j)h(Al),Q.sortIndex=Q.expirationTime,X(el,Q);else break;Q=G(Al)}}function ut(j){if(Dl=!1,Xl(j),!Gl)if(G(el)!==null)Gl=!0,Rl||(Rl=!0,Ml());else{var Q=G(Al);Q!==null&&gl(ut,Q.startTime-j)}}var Rl=!1,K=-1,k=5,it=-1;function Jl(){return il?!0:!(N.unstable_now()-itj&&Jl());){var ul=T.callback;if(typeof ul=="function"){T.callback=null,M=T.priorityLevel;var al=ul(T.expirationTime<=j);if(j=N.unstable_now(),typeof al=="function"){T.callback=al,Xl(j),Q=!0;break t}T===G(el)&&h(el),Xl(j)}else h(el);T=G(el)}if(T!==null)Q=!0;else{var rt=G(Al);rt!==null&&gl(ut,rt.startTime-j),Q=!1}}break l}finally{T=null,M=Y,zl=!1}Q=void 0}}finally{Q?Ml():Rl=!1}}}var Ml;if(typeof St=="function")Ml=function(){St(wl)};else if(typeof MessageChannel<"u"){var at=new MessageChannel,Z=at.port2;at.port1.onmessage=wl,Ml=function(){Z.postMessage(null)}}else Ml=function(){et(wl,0)};function gl(j,Q){K=et(function(){j(N.unstable_now())},Q)}N.unstable_IdlePriority=5,N.unstable_ImmediatePriority=1,N.unstable_LowPriority=4,N.unstable_NormalPriority=3,N.unstable_Profiling=null,N.unstable_UserBlockingPriority=2,N.unstable_cancelCallback=function(j){j.callback=null},N.unstable_forceFrameRate=function(j){0>j||125ul?(j.sortIndex=Y,X(Al,j),G(el)===null&&j===G(Al)&&(Dl?(Nl(K),K=-1):Dl=!0,gl(ut,Y-ul))):(j.sortIndex=al,X(el,j),Gl||zl||(Gl=!0,Rl||(Rl=!0,Ml()))),j},N.unstable_shouldYield=Jl,N.unstable_wrapCallback=function(j){var Q=M;return function(){var Y=M;M=Q;try{return j.apply(this,arguments)}finally{M=Y}}}})(As)),As}var nv;function oy(){return nv||(nv=1,Os.exports=sy()),Os.exports}var Cs={exports:{}},tt={};var iv;function ry(){if(iv)return tt;iv=1;var N=js();function X(R){var T="https://react.dev/errors/"+R;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(N)}catch(X){console.error(X)}}return N(),Cs.exports=ry(),Cs.exports}var fv;function vy(){if(fv)return fn;fv=1;var N=oy(),X=js(),G=dy();function h(l){var t="https://react.dev/errors/"+l;if(1Ft||(l.current=pl[Ft],pl[Ft]=null,Ft--)}function bl(l,t){Ft++,pl[Ft]=l.current,l.current=t}var Wt=Ut(null),da=Ut(null),Ne=Ut(null),on=Ut(null);function rn(l,t){switch(bl(Ne,t),bl(da,l),bl(Wt,null),t.nodeType){case 9:case 11:l=(l=t.documentElement)&&(l=l.namespaceURI)?s0(l):0;break;default:if(l=t.tagName,t=t.namespaceURI)t=s0(t),l=o0(t,l);else switch(l){case"svg":l=1;break;case"math":l=2;break;default:l=0}}$l(Wt),bl(Wt,l)}function Eu(){$l(Wt),$l(da),$l(Ne)}function Qi(l){var t=l.memoizedState;t!==null&&(fa._currentValue=t.memoizedState,bl(on,l)),t=Wt.current;var e=o0(t,l.type);t!==e&&(bl(da,l),bl(Wt,e))}function dn(l){da.current===l&&($l(Wt),$l(da)),on.current===l&&($l(on),fa._currentValue=ol)}var Vi,Ds;function _e(l){if(Vi===void 0)try{throw Error()}catch(e){var t=e.stack.trim().match(/\n( *(at )?)/);Vi=t&&t[1]||"",Ds=-1)":-1a||f[u]!==m[a]){var S=` +`+f[u].replace(" at new "," at ");return l.displayName&&S.includes("")&&(S=S.replace("",l.displayName)),S}while(1<=u&&0<=a);break}}}finally{Zi=!1,Error.prepareStackTrace=e}return(e=l?l.displayName||l.name:"")?_e(e):""}function ov(l,t){switch(l.tag){case 26:case 27:case 5:return _e(l.type);case 16:return _e("Lazy");case 13:return l.child!==t&&t!==null?_e("Suspense Fallback"):_e("Suspense");case 19:return _e("SuspenseList");case 0:case 15:return Li(l.type,!1);case 11:return Li(l.type.render,!1);case 1:return Li(l.type,!0);case 31:return _e("Activity");case 30:return _e("ViewTransition");default:return""}}function Ms(l){try{var t="",e=null;do t+=ov(l,e),e=l,l=l.return;while(l);return t}catch(u){return` +Error generating stack: `+u.message+` +`+u.stack}}var Ki=Object.prototype.hasOwnProperty,Ji=N.unstable_scheduleCallback,wi=N.unstable_cancelCallback,rv=N.unstable_shouldYield,dv=N.unstable_requestPaint,Tt=N.unstable_now,vv=N.unstable_getCurrentPriorityLevel,ps=N.unstable_ImmediatePriority,Us=N.unstable_UserBlockingPriority,vn=N.unstable_NormalPriority,mv=N.unstable_LowPriority,Rs=N.unstable_IdlePriority,hv=N.log,yv=N.unstable_setDisableYieldValue,va=null,Et=null;function Oe(l){if(typeof hv=="function"&&yv(l),Et&&typeof Et.setStrictMode=="function")try{Et.setStrictMode(va,l)}catch{}}var zt=Math.clz32?Math.clz32:bv,gv=Math.log,Sv=Math.LN2;function bv(l){return l>>>=0,l===0?32:31-(gv(l)/Sv|0)|0}var mn=256,hn=262144,yn=4194304;function Ie(l){var t=l&42;if(t!==0)return t;switch(l&-l){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return l&-l;case 262144:case 524288:case 1048576:case 2097152:return l&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return l&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return l}}function gn(l,t,e){var u=l.pendingLanes;if(u===0)return 0;var a=0,n=l.suspendedLanes,i=l.pingedLanes;l=l.warmLanes;var c=u&134217727;return c!==0?(u=c&~n,u!==0?a=Ie(u):(i&=c,i!==0?a=Ie(i):e||(e=c&~l,e!==0&&(a=Ie(e))))):(c=u&~n,c!==0?a=Ie(c):i!==0?a=Ie(i):e||(e=u&~l,e!==0&&(a=Ie(e)))),a===0?0:t!==0&&t!==a&&(t&n)===0&&(n=a&-a,e=t&-t,n>=e||n===32&&(e&4194048)!==0)?t:a}function ma(l,t){return(l.pendingLanes&~(l.suspendedLanes&~l.pingedLanes)&t)===0}function xs(l,t){(t&8)!==0&&(t|=t&32);var e=l.entangledLanes;if(e!==0)for(l=l.entanglements,e&=t;0e;e++)t.push(l);return t}function ha(l,t){l.pendingLanes|=t,t!==268435456&&(l.suspendedLanes=0,l.pingedLanes=0,l.warmLanes=0)}function Ev(l,t,e,u,a,n){var i=l.pendingLanes;l.pendingLanes=e,l.suspendedLanes=0,l.pingedLanes=0,l.warmLanes=0,l.expiredLanes&=e,l.entangledLanes&=e,l.errorRecoveryDisabledLanes&=e,l.shellSuspendCounter=0;var c=l.entanglements,f=l.expirationTimes,m=l.hiddenUpdates;for(e=i&~e;0"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),ac=!1;if(oe)try{var ba={};Object.defineProperty(ba,"passive",{get:function(){ac=!0}}),window.addEventListener("test",ba,ba),window.removeEventListener("test",ba,ba)}catch{ac=!1}var Ae=null,nc=null,Nn=null;function ao(){if(Nn)return Nn;var l,t=nc,e=t.length,u,a="value"in Ae?Ae.value:Ae.textContent,n=a.length;for(l=0;l=za),oo=" ",ro=!1;function vo(l,t){switch(l){case"keyup":return um.indexOf(t.keyCode)!==-1;case"keydown":return t.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function mo(l){return l=l.detail,typeof l=="object"&&"data"in l?l.data:null}var Mu=!1;function nm(l,t){switch(l){case"compositionend":return mo(t);case"keypress":return t.which!==32?null:(ro=!0,oo);case"textInput":return l=t.data,l===oo&&ro?null:l;default:return null}}function im(l,t){if(Mu)return l==="compositionend"||!oc&&vo(l,t)?(l=ao(),Nn=nc=Ae=null,Mu=!1,l):null;switch(l){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1"u")return null;try{return l.activeElement||l.body}catch{return l.body}}function zo(l){for(;l&&l.firstChild;)l=l.firstChild;return l}function No(l,t){var e=zo(l);l=0;for(var u;e;){if(e.nodeType===3){if(u=l+e.textContent.length,l<=t&&u>=t)return{node:e,offset:t-l};l=u}l:{for(;e;){if(e.nextSibling){e=e.nextSibling;break l}e=e.parentNode}e=void 0}e=zo(e)}}function _o(l,t){return l&&t?l===t?!0:l&&l.nodeType===3?!1:t&&t.nodeType===3?_o(l,t.parentNode):"contains"in l?l.contains(t):l.compareDocumentPosition?!!(l.compareDocumentPosition(t)&16):!1:!1}function Oo(l){l=l!=null&&l.ownerDocument!=null&&l.ownerDocument.defaultView!=null?l.ownerDocument.defaultView:window;for(var t=vc(l.document);t instanceof l.HTMLIFrameElement;){try{var e=typeof t.contentWindow.location.href=="string"}catch{e=!1}if(e)l=t.contentWindow;else break;t=vc(l.document)}return t}function mc(l){var t=l&&l.nodeName&&l.nodeName.toLowerCase();return t&&(t==="input"&&(l.type==="text"||l.type==="search"||l.type==="tel"||l.type==="url"||l.type==="password")||t==="textarea"||l.contentEditable==="true")}var mm=oe&&"documentMode"in document&&11>=document.documentMode,pu=null,hc=null,Aa=null,yc=!1;function Ao(l,t,e){var u=e.window===e?e.document:e.nodeType===9?e:e.ownerDocument;yc||pu==null||pu!==vc(u)||(u=pu,"selectionStart"in u&&mc(u)?u={start:u.selectionStart,end:u.selectionEnd}:(u=(u.ownerDocument&&u.ownerDocument.defaultView||window).getSelection(),u={anchorNode:u.anchorNode,anchorOffset:u.anchorOffset,focusNode:u.focusNode,focusOffset:u.focusOffset}),Aa&&Oa(Aa,u)||(Aa=u,u=ji(hc,"onSelect"),0>=i,a-=i,It=1<<32-zt(t)+a|e<V?(Yl=q,q=null):Yl=q.sibling;var nl=d(v,q,y[V],E);if(nl===null){q===null&&(q=Yl);break}l&&q&&nl.alternate===null&&t(v,q),s=n(nl,s,V),tl===null?p=nl:tl.sibling=nl,tl=nl,q=Yl}if(V===y.length)return e(v,q),W&&me(v,V),p;if(q===null){for(;VV?(Yl=q,q=null):Yl=q.sibling;var ke=d(v,q,nl.value,E);if(ke===null){q===null&&(q=Yl);break}l&&q&&ke.alternate===null&&t(v,q),s=n(ke,s,V),tl===null?p=ke:tl.sibling=ke,tl=ke,q=Yl}if(nl.done)return e(v,q),W&&me(v,V),p;if(q===null){for(;!nl.done;V++,nl=y.next())nl=z(v,nl.value,E),nl!==null&&(s=n(nl,s,V),tl===null?p=nl:tl.sibling=nl,tl=nl);return W&&me(v,V),p}for(q=u(q);!nl.done;V++,nl=y.next())nl=g(q,v,V,nl.value,E),nl!==null&&(l&&(Yl=nl.alternate,Yl!==null&&q.delete(Yl.key===null?V:Yl.key)),s=n(nl,s,V),tl===null?p=nl:tl.sibling=nl,tl=nl);return l&&q.forEach(function(ny){return t(v,ny)}),W&&me(v,V),p}function w(v,s,y,E){if(typeof y=="object"&&y!==null&&y.type===wl&&y.key===null&&y.props.ref===void 0&&(y=y.props.children),typeof y=="object"&&y!==null){switch(y.$$typeof){case it:l:{for(var p=y.key;s!==null;){if(s.key===p){if(p=y.type,p===wl){if(s.tag===7){e(v,s.sibling),E=a(s,y.props.children),Ue(E,y),E.return=v,v=E;break l}}else if(s.elementType===p||typeof p=="object"&&p!==null&&p.$$typeof===al&&ru(p)===s.type){e(v,s.sibling),E=a(s,y.props),Ue(E,y),E.return=v,v=E;break l}e(v,s);break}else t(v,s);s=s.sibling}y.type===wl?(E=au(y.props.children,v.mode,E,y.key),Ue(E,y),E.return=v,v=E):(E=Rn(y.type,y.key,y.props,null,v.mode,E),Ue(E,y),E.return=v,v=E)}return i(v);case Jl:l:{for(p=y.key;s!==null;){if(s.key===p)if(s.tag===4&&s.stateNode.containerInfo===y.containerInfo&&s.stateNode.implementation===y.implementation){e(v,s.sibling),E=a(s,y.children||[]),E.return=v,v=E;break l}else{e(v,s);break}else t(v,s);s=s.sibling}E=Nc(y,v.mode,E),E.return=v,v=E}return i(v);case al:return y=ru(y),w(v,s,y,E)}if(_(y))return C(v,s,y,E);if(H(y)){if(p=H(y),typeof p!="function")throw Error(h(150));return y=p.call(y),U(v,s,y,E)}if(typeof y.then=="function")return w(v,s,Zn(y),E);if(y.$$typeof===gl)return w(v,s,Gn(v,y),E);Ln(v,y)}return typeof y=="string"&&y!==""||typeof y=="number"||typeof y=="bigint"?(y=""+y,s!==null&&s.tag===6?(e(v,s.sibling),E=a(s,y),E.return=v,v=E):(e(v,s),E=zc(y,v.mode,E),E.return=v,v=E),i(v)):e(v,s)}return function(v,s,y,E){try{Ua=0;var p=w(v,s,y,E);return Xu=null,p}catch(q){if(q===Gu||q===Qn)throw q;var tl=vt(29,q,null,v.mode);return tl.lanes=E,tl.return=v,tl}}}var vu=Wo(!0),ko=Wo(!1),Re=!1;function Rc(l){l.updateQueue={baseState:l.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function xc(l,t){l=l.updateQueue,t.updateQueue===l&&(t.updateQueue={baseState:l.baseState,firstBaseUpdate:l.firstBaseUpdate,lastBaseUpdate:l.lastBaseUpdate,shared:l.shared,callbacks:null})}function xe(l){return{lane:l,tag:0,payload:null,callback:null,next:null}}function He(l,t,e){var u=l.updateQueue;if(u===null)return null;if(u=u.shared,(fl&2)!==0){var a=u.pending;return a===null?t.next=t:(t.next=a.next,a.next=t),u.pending=t,t=Un(l),xo(l,null,e),t}return pn(l,u,t,e),Un(l)}function Ra(l,t,e){if(t=t.updateQueue,t!==null&&(t=t.shared,(e&4194048)!==0)){var u=t.lanes;u&=l.pendingLanes,e|=u,t.lanes=e,Ys(l,e)}}function Hc(l,t){var e=l.updateQueue,u=l.alternate;if(u!==null&&(u=u.updateQueue,e===u)){var a=null,n=null;if(e=e.firstBaseUpdate,e!==null){do{var i={lane:e.lane,tag:e.tag,payload:e.payload,callback:null,next:null};n===null?a=n=i:n=n.next=i,e=e.next}while(e!==null);n===null?a=n=t:n=n.next=t}else a=n=t;e={baseState:u.baseState,firstBaseUpdate:a,lastBaseUpdate:n,shared:u.shared,callbacks:u.callbacks},l.updateQueue=e;return}l=e.lastBaseUpdate,l===null?e.firstBaseUpdate=t:l.next=t,e.lastBaseUpdate=t}var qc=!1;function xa(){if(qc){var l=Bu;if(l!==null)throw l}}function Ha(l,t,e,u){qc=!1;var a=l.updateQueue;Re=!1;var n=a.firstBaseUpdate,i=a.lastBaseUpdate,c=a.shared.pending;if(c!==null){a.shared.pending=null;var f=c,m=f.next;f.next=null,i===null?n=m:i.next=m,i=f;var S=l.alternate;S!==null&&(S=S.updateQueue,c=S.lastBaseUpdate,c!==i&&(c===null?S.firstBaseUpdate=m:c.next=m,S.lastBaseUpdate=f))}if(n!==null){var z=a.baseState;i=0,S=m=f=null,c=n;do{var d=c.lane&-536870913,g=d!==c.lane;if(g?(ll&d)===d:(u&d)===d){d!==0&&d===su&&(qc=!0),S!==null&&(S=S.next={lane:0,tag:c.tag,payload:c.payload,callback:null,next:null});l:{var C=l,U=c;d=t;var w=e;switch(U.tag){case 1:if(C=U.payload,typeof C=="function"){z=C.call(w,z,d);break l}z=C;break l;case 3:C.flags=C.flags&-65537|128;case 0:if(C=U.payload,d=typeof C=="function"?C.call(w,z,d):C,d==null)break l;z=K({},z,d);break l;case 2:Re=!0}}d=c.callback,d!==null&&(l.flags|=64,g&&(l.flags|=8192),g=a.callbacks,g===null?a.callbacks=[d]:g.push(d))}else g={lane:d,tag:c.tag,payload:c.payload,callback:c.callback,next:null},S===null?(m=S=g,f=z):S=S.next=g,i|=d;if(c=c.next,c===null){if(c=a.shared.pending,c===null)break;g=c,c=g.next,g.next=null,a.lastBaseUpdate=g,a.shared.pending=null}}while(!0);S===null&&(f=z),a.baseState=f,a.firstBaseUpdate=m,a.lastBaseUpdate=S,n===null&&(a.shared.lanes=0),Ve|=i,l.lanes=i,l.memoizedState=z}}function Io(l,t){if(typeof l!="function")throw Error(h(191,l));l.call(t)}function Po(l,t){var e=l.callbacks;if(e!==null)for(l.callbacks=null,l=0;ln?n:8;var i=A.T,c={};c.types=i!==null?i.types:null,A.T=c,ef(l,!1,t,e);try{var f=a(),m=A.S;if(m!==null&&m(c,f),f!==null&&typeof f=="object"&&typeof f.then=="function"){var S=Om(f,u);Ga(l,t,S,Dt(l))}else Ga(l,t,u,Dt(l))}catch(z){Ga(l,t,{then:function(){},status:"rejected",reason:z},Dt())}finally{D.p=n,i!==null&&c.types!==null&&(i.types=c.types),A.T=i}}function pm(){}function lf(l,t,e,u){if(l.tag!==5)throw Error(h(476));var a=pr(l).queue;Mr(l,a,t,ol,e===null?pm:function(){return Ur(l),e(u)})}function pr(l){var t=l.memoizedState;if(t!==null)return t;t={memoizedState:ol,baseState:ol,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Se,lastRenderedState:ol},next:null};var e={};return t.next={memoizedState:e,baseState:e,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Se,lastRenderedState:e},next:null},l.memoizedState=t,l=l.alternate,l!==null&&(l.memoizedState=t),t}function Ur(l){var t=pr(l);t.next===null&&(t=l.alternate.memoizedState),Ga(l,t.next.queue,{},Dt())}function tf(){return Wl(fa)}function Rr(){return Ul().memoizedState}function xr(){return Ul().memoizedState}function Um(l){for(var t=l.return;t!==null;){switch(t.tag){case 24:case 3:var e=Dt();l=xe(e);var u=He(t,l,e);u!==null&&(gt(u,t,e),Ra(u,t,e)),t={cache:Dc()},l.payload=t;return}t=t.return}}function Rm(l,t,e){var u=Dt();e={lane:u,revertLane:0,gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null},li(l)?qr(t,e):(e=Tc(l,t,e,u),e!==null&&(gt(e,l,u),Yr(e,t,u)))}function Hr(l,t,e){var u=Dt();Ga(l,t,e,u)}function Ga(l,t,e,u){var a={lane:u,revertLane:0,gesture:null,action:e,hasEagerState:!1,eagerState:null,next:null};if(li(l))qr(t,a);else{var n=l.alternate;if(l.lanes===0&&(n===null||n.lanes===0)&&(n=t.lastRenderedReducer,n!==null))try{var i=t.lastRenderedState,c=n(i,e);if(a.hasEagerState=!0,a.eagerState=c,_t(c,i))return pn(l,t,a,0),Sl===null&&Mn(),!1}catch{}if(e=Tc(l,t,a,u),e!==null)return gt(e,l,u),Yr(e,t,u),!0}return!1}function ef(l,t,e,u){if(u={lane:2,revertLane:wf(),gesture:null,action:u,hasEagerState:!1,eagerState:null,next:null},li(l)){if(t)throw Error(h(479))}else t=Tc(l,e,u,2),t!==null&>(t,l,2)}function li(l){var t=l.alternate;return l===J||t!==null&&t===J}function qr(l,t){Qu=wn=!0;var e=l.pending;e===null?t.next=t:(t.next=e.next,e.next=t),l.pending=t}function Yr(l,t,e){if((e&4194048)!==0){var u=t.lanes;u&=l.pendingLanes,e|=u,t.lanes=e,Ys(l,e)}}var ti={readContext:Wl,use:Wn,useCallback:Cl,useContext:Cl,useEffect:Cl,useImperativeHandle:Cl,useLayoutEffect:Cl,useInsertionEffect:Cl,useMemo:Cl,useReducer:Cl,useRef:Cl,useState:Cl,useDebugValue:Cl,useDeferredValue:Cl,useTransition:Cl,useSyncExternalStore:Cl,useId:Cl,useHostTransitionStatus:Cl,useFormState:Cl,useActionState:Cl,useOptimistic:Cl,useMemoCache:Cl,useCacheRefresh:Cl,useEffectEvent:Cl},Br={readContext:Wl,use:Wn,useCallback:function(l,t){return ft().memoizedState=[l,t===void 0?null:t],l},useContext:Wl,useEffect:Er,useImperativeHandle:function(l,t,e){e=e!=null?e.concat([l]):null,In(4194308,4,Or.bind(null,t,l),e)},useLayoutEffect:function(l,t){return In(4194308,4,l,t)},useInsertionEffect:function(l,t){In(4,2,l,t)},useMemo:function(l,t){var e=ft();t=t===void 0?null:t;var u=l();if(mu){Oe(!0);try{l()}finally{Oe(!1)}}return e.memoizedState=[u,t],u},useReducer:function(l,t,e){var u=ft();if(e!==void 0){var a=e(t);if(mu){Oe(!0);try{e(t)}finally{Oe(!1)}}}else a=t;return u.memoizedState=u.baseState=a,l={pending:null,lanes:0,dispatch:null,lastRenderedReducer:l,lastRenderedState:a},u.queue=l,l=l.dispatch=Rm.bind(null,J,l),[u.memoizedState,l]},useRef:function(l){var t=ft();return l={current:l},t.memoizedState=l},useState:function(l){l=Fc(l);var t=l.queue,e=Hr.bind(null,J,t);return t.dispatch=e,[l.memoizedState,e]},useDebugValue:Ic,useDeferredValue:function(l,t){var e=ft();return Pc(e,l,t)},useTransition:function(){var l=Fc(!1);return l=Mr.bind(null,J,l.queue,!0,!1),ft().memoizedState=l,[!1,l]},useSyncExternalStore:function(l,t,e){var u=J,a=ft();if(W){if(e===void 0)throw Error(h(407));e=e()}else{if(e=t(),Sl===null)throw Error(h(349));(ll&127)!==0||nr(u,t,e)}a.memoizedState=e;var n={value:e,getSnapshot:t};return a.queue=n,Er(cr.bind(null,u,n,l),[l]),u.flags|=2048,Zu(9,{destroy:void 0},ir.bind(null,u,n,e,t),null),e},useId:function(){var l=ft(),t=Sl.identifierPrefix;if(W){var e=Pt,u=It;e=(u&~(1<<32-zt(u)-1)).toString(32)+e,t="_"+t+"R_"+e,e=$n++,0<\/script>",n=n.removeChild(n.firstChild);break;case"select":n=typeof u.is=="string"?i.createElement("select",{is:u.is}):i.createElement("select"),u.multiple?n.multiple=!0:u.size&&(n.size=u.size);break;default:n=typeof u.is=="string"?i.createElement(a,{is:u.is}):i.createElement(a)}}n[Fl]=t,n[dt]=u;l:for(i=t.child;i!==null;){if(i.tag===5||i.tag===6)n.appendChild(i.stateNode);else if(i.tag!==4&&i.tag!==27&&i.child!==null){i.child.return=i,i=i.child;continue}if(i===t)break l;for(;i.sibling===null;){if(i.return===null||i.return===t)break l;i=i.return}i.sibling.return=i.return,i=i.sibling}t.stateNode=n;l:switch(lt(n,a,u),a){case"button":case"input":case"select":case"textarea":u=!!u.autoFocus;break l;case"img":u=!0;break l;default:u=!1}u&&Te(t)}}return El(t),t.subtreeFlags&=-33554433,yf(t,t.type,l===null?null:l.memoizedProps,t.pendingProps,e),null;case 6:if(l&&t.stateNode!=null)l.memoizedProps!==u&&Te(t);else{if(typeof u!="string"&&t.stateNode===null)throw Error(h(166));if(l=Ne.current,Yu(t)){if(l=t.stateNode,e=t.memoizedProps,u=null,a=Zl,a!==null)switch(a.tag){case 27:case 5:u=a.memoizedProps}l[Fl]=t,l=!!(l.nodeValue===e||u!==null&&u.suppressHydrationWarning===!0||c0(l.nodeValue,e)),l||Me(t,!0)}else l=Ia(l).createTextNode(u),l[Fl]=t,t.stateNode=l}return El(t),null;case 31:if(e=t.memoizedState,l===null||l.memoizedState!==null){if(u=Yu(t),e!==null){if(l===null){if(!u)throw Error(h(318));if(l=t.memoizedState,l=l!==null?l.dehydrated:null,!l)throw Error(h(557));l[Fl]=t}else nu(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;El(t),l=!1}else e=Ac(),l!==null&&l.memoizedState!==null&&(l.memoizedState.hydrationErrors=e),l=!0;if(!l)return t.flags&256?(Ot(t),t):(Ot(t),null);if((t.flags&128)!==0)throw Error(h(558))}return El(t),null;case 13:if(u=t.memoizedState,l===null||l.memoizedState!==null&&l.memoizedState.dehydrated!==null){if(a=Yu(t),u!==null&&u.dehydrated!==null){if(l===null){if(!a)throw Error(h(318));if(a=t.memoizedState,a=a!==null?a.dehydrated:null,!a)throw Error(h(317));a[Fl]=t}else nu(),(t.flags&128)===0&&(t.memoizedState=null),t.flags|=4;El(t),a=!1}else a=Ac(),l!==null&&l.memoizedState!==null&&(l.memoizedState.hydrationErrors=a),a=!0;if(!a)return t.flags&256?(Ot(t),t):(Ot(t),null)}return Ot(t),(t.flags&128)!==0?(t.lanes=e,t):(e=u!==null,l=l!==null&&l.memoizedState!==null,e&&(u=t.child,a=null,u.alternate!==null&&u.alternate.memoizedState!==null&&u.alternate.memoizedState.cachePool!==null&&(a=u.alternate.memoizedState.cachePool.pool),n=null,u.memoizedState!==null&&u.memoizedState.cachePool!==null&&(n=u.memoizedState.cachePool.pool),n!==a&&(u.flags|=2048)),e!==l&&e&&(t.child.flags|=8192),ci(t,t.updateQueue),El(t),null);case 4:return Eu(),l===null&&kf(t.stateNode.containerInfo),t.flags|=67108864,El(t),null;case 10:return ye(t.type),El(t),null;case 19:if(Xc(t),u=t.memoizedState,u===null)return El(t),null;if(a=(t.flags&128)!==0,n=u.rendering,n===null)if(a)Qa(u,!1);else{if(jl!==0||l!==null&&(l.flags&128)!==0)for(l=t.child;l!==null;){if(n=Jn(l),n!==null){for(t.flags|=128,Qa(u,!1),l=n.updateQueue,t.updateQueue=l,ci(t,l),t.subtreeFlags=0,l=e,e=t.child;e!==null;)Ho(e,l),e=e.sibling;return qa(t,Il.current&1|2),W&&me(t,u.treeForkCount),t.child}l=l.sibling}u.tail!==null&&Tt()>bi&&(t.flags|=128,a=!0,Qa(u,!1),t.lanes=4194304)}else{if(!a)if(l=Jn(n),l!==null){if(t.flags|=128,a=!0,l=l.updateQueue,t.updateQueue=l,ci(t,l),Qa(u,!0),u.tail===null&&u.tailMode!=="collapsed"&&u.tailMode!=="visible"&&!n.alternate&&!W)return El(t),null}else 2*Tt()-u.renderingStartTime>bi&&e!==536870912&&(t.flags|=128,a=!0,Qa(u,!1),t.lanes=4194304);u.isBackwards?(n.sibling=t.child,t.child=n):(l=u.last,l!==null?l.sibling=n:t.child=n,u.last=n)}if(u.tail!==null){l=u.tail;l:{for(e=l;e!==null;){if(e.alternate!==null){e=!1;break l}e=e.sibling}e=!0}return u.rendering=l,u.tail=l.sibling,u.renderingStartTime=Tt(),l.sibling=null,n=Il.current,n=a?n&1|2:n&1,u.tailMode==="visible"||u.tailMode==="collapsed"||!e||W?qa(t,n):(e=n,bl(kl,t),bl(Il,e),nt===null&&(nt=t)),W&&me(t,u.treeForkCount),l}return El(t),null;case 22:case 23:return Ot(t),Bc(),u=t.memoizedState!==null,l!==null?l.memoizedState!==null!==u&&(t.flags|=8192):u&&(t.flags|=8192),u?(e&536870912)!==0&&(t.flags&128)===0&&(El(t),t.subtreeFlags&6&&(t.flags|=8192)):El(t),e=t.updateQueue,e!==null&&ci(t,e.retryQueue),e=null,l!==null&&l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(e=l.memoizedState.cachePool.pool),u=null,t.memoizedState!==null&&t.memoizedState.cachePool!==null&&(u=t.memoizedState.cachePool.pool),u!==e&&(t.flags|=2048),l!==null&&$l(ou),null;case 24:return e=null,l!==null&&(e=l.memoizedState.cache),t.memoizedState.cache!==e&&(t.flags|=2048),ye(xl),El(t),null;case 25:return null;case 30:return t.flags|=33554432,El(t),null}throw Error(h(156,t.tag))}function Xm(l,t){switch(_c(t),t.tag){case 1:return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 3:return ye(xl),Eu(),l=t.flags,(l&65536)!==0&&(l&128)===0?(t.flags=l&-65537|128,t):null;case 26:case 27:case 5:return dn(t),null;case 31:if(t.memoizedState!==null){if(Ot(t),t.alternate===null)throw Error(h(340));nu()}return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 13:if(Ot(t),l=t.memoizedState,l!==null&&l.dehydrated!==null){if(t.alternate===null)throw Error(h(340));nu()}return l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 19:return Xc(t),l=t.flags,l&65536?(t.flags=l&-65537|128,l=t.memoizedState,l!==null&&(l.rendering=null,l.tail=null),t.flags|=4,t):null;case 4:return Eu(),null;case 10:return ye(t.type),null;case 22:case 23:return Ot(t),Bc(),l!==null&&$l(ou),l=t.flags,l&65536?(t.flags=l&-65537|128,t):null;case 24:return ye(xl),null;case 25:return null;default:return null}}function sd(l,t){switch(_c(t),t.tag){case 3:ye(xl),Eu();break;case 26:case 27:case 5:dn(t);break;case 4:Eu();break;case 31:t.memoizedState!==null&&Ot(t);break;case 13:Ot(t);break;case 19:Xc(t);break;case 10:ye(t.type);break;case 22:case 23:Ot(t),Bc(),l!==null&&$l(ou);break;case 24:ye(xl)}}function Va(l,t){try{var e=t.updateQueue,u=e!==null?e.lastEffect:null;if(u!==null){var a=u.next;e=a;do{if((e.tag&l)===l){u=void 0;var n=e.create,i=e.inst;u=n(),i.destroy=u}e=e.next}while(e!==a)}}catch(c){ml(t,t.return,c)}}function Ge(l,t,e){try{var u=t.updateQueue,a=u!==null?u.lastEffect:null;if(a!==null){var n=a.next;u=n;do{if((u.tag&l)===l){var i=u.inst,c=i.destroy;if(c!==void 0){i.destroy=void 0,a=t;var f=e,m=c;try{m()}catch(S){ml(a,f,S)}}}u=u.next}while(u!==n)}}catch(S){ml(t,t.return,S)}}function od(l){var t=l.updateQueue;if(t!==null){var e=l.stateNode;try{Po(t,e)}catch(u){ml(l,l.return,u)}}}function rd(l,t,e){e.props=hu(l.type,l.memoizedProps),e.state=l.memoizedState;try{e.componentWillUnmount()}catch(u){ml(l,t,u)}}function le(l,t){try{var e=l.ref;if(e!==null){switch(l.tag){case 26:case 27:case 5:var u=l.stateNode;break;case 30:var a=l.stateNode,n=re(l.memoizedProps,a);(a.ref===null||a.ref.name!==n)&&(a.ref=S0(n)),u=a.ref;break;case 7:if(l.stateNode===null){var i=new Mt(l);T(l.child,!1,Mh,i,void 0,void 0),l.stateNode=i}u=l.stateNode;break;default:u=l.stateNode}typeof e=="function"?l.refCleanup=e(u):e.current=u}}catch(c){ml(l,t,c)}}function Pl(l,t){var e=l.ref,u=l.refCleanup;if(e!==null)if(typeof u=="function")try{u()}catch(a){ml(l,t,a)}finally{l.refCleanup=null,l=l.alternate,l!=null&&(l.refCleanup=null)}else if(typeof e=="function")try{e(null)}catch(a){ml(l,t,a)}else e.current=null}function fi(l,t){if((l.tag===5||l.tag===27||l.tag===6)&&l.alternate===null&&t!==null)for(var e=0;e title"))),lt(u,t,e),u[Fl]=l,Vl(u),t=u;break l;case"link":if(n=H0("link","href",a).get(t+(e.href||""))){for(i=0;iw&&(i=w,w=U,U=i);var v=No(c,U),s=No(c,w);if(v&&s&&(g.rangeCount!==1||g.anchorNode!==v.node||g.anchorOffset!==v.offset||g.focusNode!==s.node||g.focusOffset!==s.offset)){var y=z.createRange();y.setStart(v.node,v.offset),g.removeAllRanges(),U>w?(g.addRange(y),g.extend(s.node,s.offset)):(y.setEnd(s.node,s.offset),g.addRange(y))}}}}for(z=[],g=c;g=g.parentNode;)g.nodeType===1&&z.push({element:g,left:g.scrollLeft,top:g.scrollTop});for(typeof c.focus=="function"&&c.focus(),c=0;ce?32:e,A.T=null,e=Yf,Yf=null;var n=wt,i=ie;if(Ol=0,bu=wt=null,ie=0,(fl&6)!==0)throw Error(h(331));var c=fl;if(fl|=4,xd(n.current),pd(n,n.current,i,e),fl=c,Fa(0,!1),Et&&typeof Et.onPostCommitFiberRoot=="function")try{Et.onPostCommitFiberRoot(va,n)}catch{}return!0}finally{D.p=a,A.T=u,Fd(l,t)}}function Wd(l,t,e){t=Ht(e,t),t=nf(l.stateNode,t,2),l=He(l,t,2),l!==null&&(ha(l,2),ce(l))}function ml(l,t,e){if(l.tag===3)Wd(l,l,e);else for(;t!==null;){if(t.tag===3){Wd(t,l,e);break}else if(t.tag===1){var u=t.stateNode;if(typeof t.type.getDerivedStateFromError=="function"||typeof u.componentDidCatch=="function"&&(Ze===null||!Ze.has(u))){l=Ht(e,l),e=Jr(2),u=He(t,e,2),u!==null&&(wr(e,u,t,l),ha(u,2),ce(u));break}}t=t.return}}function Lf(l,t,e){var u=l.pingCache;if(u===null){u=l.pingCache=new Lm;var a=new Set;u.set(t,a)}else a=u.get(t),a===void 0&&(a=new Set,u.set(t,a));a.has(e)||(xf=!0,a.add(e),l=Im.bind(null,l,t,e),t.then(l,l))}function Im(l,t,e){var u=l.pingCache;u!==null&&u.delete(t),l.pingedLanes|=l.suspendedLanes&e,l.warmLanes&=~e,Sl===l&&(ll&e)===e&&((jl===4||jl===3&&(ll&62914560)===ll&&300>Tt()-Si)&&(fl&2)===0?la(l,0):gi|=e,Fu===ll&&(Fu=0)),ce(l)}function kd(l,t){t===0&&(t=Hs()),l=uu(l,t),l!==null&&(ha(l,t),ce(l))}function Pm(l){var t=l.memoizedState,e=0;t!==null&&(e=t.retryLane),kd(l,e)}function lh(l,t){var e=0;switch(l.tag){case 31:case 13:var u=l.stateNode,a=l.memoizedState;a!==null&&(e=a.retryLane);break;case 19:u=l.stateNode;break;case 22:u=l.stateNode._retryCache;break;default:throw Error(h(314))}u!==null&&u.delete(t),kd(l,e)}function th(l,t){return Ji(l,t)}var ea=null,ua=null,Kf=!1,Ai=!1,Jf=!1,Ke=0;function ce(l){l!==ua&&l.next===null&&(ua===null?ea=ua=l:ua=ua.next=l),Ai=!0,Kf||(Kf=!0,uh())}function Fa(l,t){if(!Jf&&Ai){Jf=!0;do for(var e=!1,u=ea;u!==null;){if(l!==0){var a=u.pendingLanes;if(a===0)var n=0;else{var i=u.suspendedLanes,c=u.pingedLanes;n=(1<<31-zt(42|l)+1)-1,n&=a&~(i&~c),n=n&201326741?n&201326741|1:n?n|2:0}n!==0&&(e=!0,t0(u,n))}else n=ll,n=gn(u,u===Sl?n:0,u.cancelPendingCommit!==null||u.timeoutHandle!==-1),(n&3)===0||ma(u,n)||(e=!0,t0(u,n));u=u.next}while(e);Jf=!1}}function eh(){Id()}function Id(){Ai=Kf=!1;var l=0;Ke!==0&&mh()&&(l=Ke);for(var t=Tt(),e=null,u=ea;u!==null;){var a=u.next,n=Pd(u,t);n===0?(u.next=null,e===null?ea=a:e.next=a,a===null&&(ua=e)):(e=u,(l!==0||(n&3)!==0)&&(Ai=!0)),u=a}Ol!==0&&Ol!==5||Fa(l),Ke!==0&&(Ke=0)}function Pd(l,t){for(var e=l.suspendedLanes,u=l.pingedLanes,a=l.expirationTimes,n=l.pendingLanes&-62914561;0c)break;var S=f.transferSize,z=f.initiatorType;S&&f0(z)&&(f=f.responseEnd,i+=S*(fpi){U.length=C;break}y=new Promise(Th.bind(y)),U.push(y)}}}if(0"u"?null:document;function p0(l,t,e){var u=na;if(u&&typeof t=="string"&&t){var a=Rt(t);a='link[rel="'+l+'"][href="'+a+'"]',typeof e=="string"&&(a+='[crossorigin="'+e+'"]'),M0.has(a)||(M0.add(a),l={rel:l,crossOrigin:e,href:t},u.querySelector(a)===null&&(t=u.createElement("link"),lt(t,"link",l),Vl(t),u.head.appendChild(t)))}}function Gh(l){ze.D(l),p0("dns-prefetch",l,null)}function Xh(l,t){ze.C(l,t),p0("preconnect",l,t)}function Qh(l,t,e){ze.L(l,t,e);var u=na;if(u&&l&&t){var a='link[rel="preload"][as="'+Rt(t)+'"]';t==="image"&&e&&e.imageSrcSet?(a+='[imagesrcset="'+Rt(e.imageSrcSet)+'"]',typeof e.imageSizes=="string"&&(a+='[imagesizes="'+Rt(e.imageSizes)+'"]')):a+='[href="'+Rt(l)+'"]';var n=a;switch(t){case"style":n=ia(l);break;case"script":n=ca(l)}if(!(Qt.has(n)||(l=K({rel:"preload",href:t==="image"&&e&&e.imageSrcSet?void 0:l,as:t},e),Qt.set(n,l),u.querySelector(a)!==null||t==="style"&&u.querySelector(ln(n))||t==="script"&&u.querySelector(tn(n))))){var i=u.createElement("link");lt(i,"link",l),t==="style"&&(i[Sn]=!0,i.onload=i.onerror=function(){Zs(i)}),Vl(i),u.head.appendChild(i)}}}function Vh(l,t){ze.m(l,t);var e=na;if(e&&l){var u=t&&typeof t.as=="string"?t.as:"script",a='link[rel="modulepreload"][as="'+Rt(u)+'"][href="'+Rt(l)+'"]',n=a;switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":n=ca(l)}if(!Qt.has(n)&&(l=K({rel:"modulepreload",href:l},t),Qt.set(n,l),e.querySelector(a)===null)){switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(e.querySelector(tn(n)))return}u=e.createElement("link"),lt(u,"link",l),Vl(u),e.head.appendChild(u)}}}function Zh(l,t,e){ze.S(l,t,e);var u=na;if(u&&l){var a=_u(u).hoistableStyles,n=ia(l);t=t||"default";var i=a.get(n);if(!i){var c={loading:0,preload:null};if(i=u.querySelector(ln(n)))c.loading=5;else{l=K({rel:"stylesheet",href:l,"data-precedence":t},e),(e=Qt.get(n))&&vs(l,e);var f=i=u.createElement("link");Vl(f),lt(f,"link",l),f._p=new Promise(function(m,S){f.onload=m,f.onerror=S}),f.addEventListener("load",function(){c.loading|=1}),f.addEventListener("error",function(){c.loading|=2}),c.loading|=4,Di(i,t,u)}i={type:"stylesheet",instance:i,count:1,state:c},a.set(n,i)}}}function Lh(l,t){ze.X(l,t);var e=na;if(e&&l){var u=_u(e).hoistableScripts,a=ca(l),n=u.get(a);n||(n=e.querySelector(tn(a)),n||(l=K({src:l,async:!0},t),(t=Qt.get(a))&&ms(l,t),n=e.createElement("script"),Vl(n),lt(n,"link",l),e.head.appendChild(n)),n={type:"script",instance:n,count:1,state:null},u.set(a,n))}}function Kh(l,t){ze.M(l,t);var e=na;if(e&&l){var u=_u(e).hoistableScripts,a=ca(l),n=u.get(a);n||(n=e.querySelector(tn(a)),n||(l=K({src:l,async:!0,type:"module"},t),(t=Qt.get(a))&&ms(l,t),n=e.createElement("script"),Vl(n),lt(n,"link",l),e.head.appendChild(n)),n={type:"script",instance:n,count:1,state:null},u.set(a,n))}}function U0(l,t,e,u){var a=(a=Ne.current)?Pa(a):null;if(!a)throw Error(h(446));switch(l){case"meta":case"title":return null;case"style":return typeof e.precedence=="string"&&typeof e.href=="string"?(e=ia(e.href),t=_u(a).hoistableStyles,u=t.get(e),u||(u={type:"style",instance:null,count:0,state:null},t.set(e,u)),u):{type:"void",instance:null,count:0,state:null};case"link":if(e.rel==="stylesheet"&&typeof e.href=="string"&&typeof e.precedence=="string"){l=ia(e.href);var n=_u(a).hoistableStyles,i=n.get(l);if(i||(a=a.ownerDocument||a,i={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},n.set(l,i),(n=a.querySelector(ln(l)))?n._p||(i.instance=n,i.state.loading=5):(n=Qt.get(l),n||(n={rel:"preload",as:"style",href:e.href,crossOrigin:e.crossOrigin,integrity:e.integrity,media:e.media,hrefLang:e.hrefLang,referrerPolicy:e.referrerPolicy},Qt.set(l,n)),Jh(a,l,n,i.state))),t&&u===null)throw Error(h(528,""));return i}if(t&&u!==null)throw Error(h(529,""));return null;case"script":return t=e.async,e=e.src,typeof e=="string"&&t&&typeof t!="function"&&typeof t!="symbol"?(e=ca(e),t=_u(a).hoistableScripts,u=t.get(e),u||(u={type:"script",instance:null,count:0,state:null},t.set(e,u)),u):{type:"void",instance:null,count:0,state:null};default:throw Error(h(444,l))}}function ia(l){return'href="'+Rt(l)+'"'}function ln(l){return'link[rel="stylesheet"]['+l+"]"}function R0(l){return K({},l,{"data-precedence":l.precedence,precedence:null})}function Jh(l,t,e,u){if(t=l.querySelector('link[rel="preload"][as="style"]['+t+"]")){if(t[Sn]!==!0){u.loading=1;return}}else t=l.createElement("link"),t[Sn]=!0,t.onload=t.onerror=Zs.bind(null,t),lt(t,"link",e),Vl(t),l.head.appendChild(t);u.preload=t,t.addEventListener("load",function(){return u.loading|=1}),t.addEventListener("error",function(){return u.loading|=2})}function ca(l){return'[src="'+Rt(l)+'"]'}function tn(l){return"script[async]"+l}function x0(l,t,e){if(t.count++,t.instance===null)switch(t.type){case"style":var u=l.querySelector('style[data-href~="'+Rt(e.href)+'"]');if(u)return t.instance=u,Vl(u),u;var a=K({},e,{"data-href":e.href,"data-precedence":e.precedence,href:null,precedence:null});return u=(l.ownerDocument||l).createElement("style"),Vl(u),lt(u,"style",a),Di(u,e.precedence,l),t.instance=u;case"stylesheet":a=ia(e.href);var n=l.querySelector(ln(a));if(n)return t.state.loading|=4,t.instance=n,Vl(n),n;u=R0(e),(a=Qt.get(a))&&vs(u,a),n=(l.ownerDocument||l).createElement("link"),Vl(n);var i=n;return i._p=new Promise(function(c,f){i.onload=c,i.onerror=f}),lt(n,"link",u),t.state.loading|=4,Di(n,e.precedence,l),t.instance=n;case"script":return n=ca(e.src),(a=l.querySelector(tn(n)))?(t.instance=a,Vl(a),a):(u=e,(a=Qt.get(n))&&(u=K({},e),ms(u,a)),l=l.ownerDocument||l,a=l.createElement("script"),Vl(a),lt(a,"link",u),l.head.appendChild(a),t.instance=a);case"void":return null;default:throw Error(h(443,t.type))}else t.type==="stylesheet"&&(t.state.loading&4)===0&&(u=t.instance,t.state.loading|=4,Di(u,e.precedence,l));return t.instance}function Di(l,t,e){for(var u=e.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),a=u.length?u[u.length-1]:null,n=a,i=0;i title"):null)}function wh(l,t,e){if(e===1||t.itemProp!=null)return!1;switch(l){case"meta":case"title":return!0;case"style":if(typeof t.precedence!="string"||typeof t.href!="string"||t.href==="")break;return!0;case"link":if(typeof t.rel!="string"||typeof t.href!="string"||t.href===""||t.onLoad||t.onError)break;return t.rel==="stylesheet"?(l=t.disabled,typeof t.precedence=="string"&&l==null):!0;case"script":if(t.async&&typeof t.async!="function"&&typeof t.async!="symbol"&&!t.onLoad&&!t.onError&&t.src&&typeof t.src=="string")return!0}return!1}function q0(l,t){return l==="img"&&t.src!=null&&t.src!==""&&t.onLoad==null&&t.loading!=="lazy"}function Y0(l){return!(l.type==="stylesheet"&&(l.state.loading&3)===0)}function B0(l){return(l.width||100)*(l.height||100)*(typeof devicePixelRatio=="number"?devicePixelRatio:1)*.25}function G0(l,t){typeof t.decode=="function"&&(l.imgCount++,t.complete||(l.imgBytes+=B0(t),l.suspenseyImages.push(t)),l=Wh.bind(l),t.decode().then(l,l))}function $h(l,t,e,u){if(e.type==="stylesheet"&&(typeof u.media!="string"||matchMedia(u.media).matches!==!1)&&(e.state.loading&4)===0){if(e.instance===null){var a=ia(u.href),n=t.querySelector(ln(a));if(n){t=n._p,t!==null&&typeof t=="object"&&typeof t.then=="function"&&(l.count++,l=en.bind(l),t.then(l,l)),e.state.loading|=4,e.instance=n,Vl(n);return}n=t.ownerDocument||t,u=R0(u),(a=Qt.get(a))&&vs(u,a),n=n.createElement("link"),Vl(n);var i=n;i._p=new Promise(function(c,f){i.onload=c,i.onerror=f}),lt(n,"link",u),e.instance=n}l.stylesheets===null&&(l.stylesheets=new Map),l.stylesheets.set(e,t),(t=e.state.preload)&&(e.state.loading&3)===0&&(l.count++,e=en.bind(l),t.addEventListener("load",e),t.addEventListener("error",e))}}var pi=0;function Fh(l,t){return l.stylesheets&&l.count===0&&Ri(l,l.stylesheets),0pi?50:800)+t);return l.unsuspend=e,function(){l.unsuspend=null,clearTimeout(u),clearTimeout(a)}}:null}function X0(l){if(l.count===0&&(l.imgCount===0||!l.waitingForImages)){if(l.stylesheets)Ri(l,l.stylesheets);else if(l.unsuspend){var t=l.unsuspend;l.unsuspend=null,t()}}}function en(){this.count--,X0(this)}function Wh(){this.imgCount--,X0(this)}var Ui=null;function Ri(l,t){l.stylesheets=null,l.unsuspend!==null&&(l.count++,Ui=new Map,t.forEach(kh,l),Ui=null,en.call(l))}function kh(l,t){if(!(t.state.loading&4)){var e=Ui.get(l);if(e)var u=e.get(null);else{e=new Map,Ui.set(l,e);for(var a=l.querySelectorAll("link[data-precedence],style[data-precedence]"),n=0;n"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(N)}catch(X){console.error(X)}}return N(),_s.exports=vy(),_s.exports}var hy=my();async function ra(N,X){const G=await fetch("/api/"+N,X===void 0?{}:{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(X)});if(!G.ok){let h;try{const B=await G.json();h=typeof B.detail=="string"?B.detail:JSON.stringify(B.detail)}catch{h=await G.text().catch(()=>G.statusText)}throw new Error(h||"Le serveur ne répond pas.")}return G.json()}const Xi=(N,X,G=!1,h="")=>"/api/image?"+new URLSearchParams({copy:N,label:X,body:String(G),v:h}),sn=(N,X,G="")=>"/api/document?"+new URLSearchParams({copy:N,kind:X,label:G}),Vt=(N,X="",G="")=>JSON.stringify([N,X,G]);function yy(){const[N,X]=dl.useState(null),[G,h]=dl.useState(""),[B,$]=dl.useState(""),[sl,Bl]=dl.useState(""),[el,Al]=dl.useState(""),[R,T]=dl.useState(20),[M,zl]=dl.useState({}),[Gl,Dl]=dl.useState(!1),[il,et]=dl.useState(!1),[Nl,St]=dl.useState(null),[Xl,ut]=dl.useState(null),[Rl,K]=dl.useState(!1),[k,it]=dl.useState(!1),[Jl,wl]=dl.useState(!0),Ml=async()=>{try{X(await ra("state")),h("")}catch(b){h(String(b))}};dl.useEffect(()=>{Ml()},[]),dl.useEffect(()=>{const b=_=>{Object.keys(M).length&&(_.preventDefault(),_.returnValue="")};return window.addEventListener("beforeunload",b),()=>window.removeEventListener("beforeunload",b)},[M]),dl.useEffect(()=>{if(!N?.job.running)return;const b=setInterval(async()=>{try{const _=await ra("job");X(A=>A&&{...A,job:_}),_.running||(await Ml(),$(_.status==="success"?"Les sorties ont été régénérées.":"La régénération est incomplète. Consultez le journal."))}catch(_){h(String(_))}},1e3);return()=>clearInterval(b)},[N?.job.running]);const at=(b,_,A,D)=>M[Vt(b,_,A)]?.value??D,Z=(b,_,A,D)=>zl(ol=>({...ol,[Vt(b,_,A)]:{kind:b,copy:_,label:A,value:D}})),gl=async b=>{if(!N)return;Dl(!0),h("");let _=N;try{for(const A of b){const D=M[A];D&&(_=await ra("change",{...D,revision:_.revision}),X(_),zl(ol=>{const pl={...ol};return delete pl[A],pl}))}$("Modifications enregistrées.")}catch(A){h(String(A))}finally{Dl(!1)}},j=async()=>{if(N){Dl(!0),h("");try{const b=await ra("regenerate",{revision:N.revision,apply_draft:il,incremental:Jl});X({...N,job:b}),$("")}catch(b){h(String(b))}finally{Dl(!1)}}},Q=async()=>{try{await ra("stop",{}),K(!0)}catch(b){h(String(b))}};if(Rl)return r.jsxs("main",{className:"end",children:[r.jsx("h1",{children:"Session terminée"}),r.jsx("p",{children:"Vous pouvez reprendre le travail dans Copienator."})]});if(!N)return r.jsxs("main",{className:"end",children:[r.jsx("h1",{children:"Copienator"}),r.jsx("p",{children:G||"Chargement de la finalisation…"}),r.jsx("button",{onClick:Ml,children:"Réessayer"})]});const Y=Gl||N.job.running,ul=Object.keys(M).length,al=at("draft","","",N.draft),rt=N.draft.trim()!==N.applied.trim(),pt=N.copies.filter(b=>!sl||Number(b.id)===Number(sl)),bt=pt.flatMap(b=>b.answers.filter(_=>!el||_.label===el).map(_=>({c:b,a:_}))),o=new Map;N.copies.forEach(b=>o.set(b.name.toLowerCase(),(o.get(b.name.toLowerCase())||0)+1));const O=N.copies.filter(b=>b.name.toLowerCase()==="unknown"||(o.get(b.name.toLowerCase())||0)>1),x=pt.filter(b=>!k||O.includes(b)),H=new Set(N.copies.map(b=>b.name.trim().toLocaleLowerCase("fr"))),F=N.expectedNames?.filter(b=>!H.has(b.trim().toLocaleLowerCase("fr")));return r.jsxs(r.Fragment,{children:[r.jsxs("header",{inert:!!Nl||!!Xl,children:[r.jsxs("div",{className:"brand",children:["C",r.jsx("span",{children:"Copienator"})]}),r.jsxs("div",{className:"heading",children:[r.jsxs("div",{className:"eyebrow",children:["FINALISATION · ",N.mode]}),r.jsx("h1",{children:N.evaluation})]}),r.jsx("button",{className:"quiet",disabled:Y||!!ul,onClick:Q,children:"Fermer et reprendre dans le GUI"})]}),r.jsxs("main",{inert:!!Nl||!!Xl,children:[r.jsxs("section",{className:"toolbar",children:[r.jsxs("div",{children:[r.jsx("h2",{children:"Vérifier les copies"}),r.jsx("p",{children:"Retrouvez une copie, une question, ou leur intersection."})]}),r.jsxs("div",{className:"filters",children:[r.jsxs("label",{children:["Copie",r.jsx("input",{type:"text",inputMode:"numeric",list:"copies",placeholder:"Toutes les copies",value:sl,onChange:b=>{Bl(b.target.value.replace(/\D/g,"")),T(20)}})]}),r.jsx("datalist",{id:"copies",children:N.copies.map(b=>r.jsx("option",{value:b.id,children:b.name},b.id))}),r.jsxs("label",{children:["Label",r.jsxs("select",{value:el,onChange:b=>{Al(b.target.value),T(20)},children:[r.jsx("option",{value:"",children:"Tous les labels"}),N.labels.map(b=>r.jsx("option",{children:b},b))]})]}),r.jsx("button",{onClick:()=>{Bl(""),Al(""),T(20)},children:"Réinitialiser"})]})]}),G&&r.jsxs("div",{role:"alert",className:"alert",children:[G,r.jsx("button",{onClick:Ml,children:"Recharger les données"}),r.jsx("small",{children:"Les saisies non enregistrées restent dans la page."})]}),B&&r.jsx("p",{role:"status",className:"notice",children:B}),r.jsxs("section",{className:"publish",children:[r.jsxs("div",{children:[r.jsx("strong",{children:N.job.running?"Régénération en cours…":ul?`${ul} modification(s) non enregistrée(s)`:N.dirty?"Enregistré · sorties à régénérer":"Modifications enregistrées"}),r.jsx("small",{children:"Les sorties comprennent les images, PDF et le dossier A Rendre configurés."})]}),r.jsx("button",{disabled:Y||!ul,onClick:()=>gl(Object.keys(M)),children:"Tout enregistrer"}),ul>0&&r.jsx("button",{disabled:Y,onClick:()=>zl({}),children:"Annuler les saisies"}),r.jsxs("label",{className:"check",children:[r.jsx("input",{type:"checkbox",checked:il,disabled:Y,onChange:b=>et(b.target.checked)}),"Appliquer aussi le brouillon de transferts",rt?" (différent du résultat actuel)":""]}),r.jsxs("label",{className:"check",children:[r.jsx("input",{type:"checkbox",checked:Jl,disabled:Y,onChange:b=>wl(b.target.checked)}),"Ignorer les copies inchangées"]}),r.jsx("button",{className:"primary",disabled:Y||!!ul,onClick:j,children:"Régénérer les sorties"})]}),r.jsxs("fieldset",{disabled:Y,children:[r.jsxs("details",{className:"panel",children:[r.jsxs("summary",{children:["Identités et remarques générales ",r.jsxs("span",{children:[O.length," nom(s) à vérifier"]})]}),r.jsxs("div",{className:"identity-overview",children:[r.jsxs("strong",{children:["Noms manquants",F?` (${F.length})`:""]}),F===void 0?r.jsx("p",{children:"Liste des noms attendus introuvable (fichier names)."}):F.length?r.jsx("ul",{className:"missing-names",children:F.map(b=>r.jsx("li",{children:b},b))}):r.jsx("p",{children:"Tous les noms attendus sont attribués."}),r.jsxs("label",{className:"check",children:[r.jsx("input",{type:"checkbox",checked:k,onChange:b=>it(b.target.checked)}),"Afficher uniquement les copies « Nom à vérifier »"]})]}),r.jsx("p",{children:"Les remarques sont composées en LaTeX. Leur ordre est celui de la liste."}),x.length===0&&r.jsx("p",{children:"Aucune copie ne correspond aux filtres sélectionnés."}),x.map(b=>{const _=at("general",b.id,"",b.general),A=D=>Z("general",b.id,"",D);return r.jsxs("section",{className:"identity",children:[r.jsxs("div",{className:"identity-name",children:[r.jsxs("strong",{children:["Copie ",b.id]}),r.jsxs("label",{children:["Nom",r.jsx("input",{value:at("name",b.id,"",b.name),onChange:D=>Z("name",b.id,"",D.target.value)})]}),O.includes(b)&&r.jsx("span",{className:"badge warning",children:"Nom à vérifier"}),r.jsx("a",{target:"_blank",rel:"noreferrer",href:sn(b.id,"original"),children:"Voir l’originale ↗"}),r.jsx("button",{disabled:!M[Vt("name",b.id)],onClick:()=>gl([Vt("name",b.id)]),children:"Enregistrer le nom"})]}),r.jsxs("div",{className:"general",children:[_.map((D,ol)=>r.jsxs("div",{className:"remark-row",children:[r.jsx("textarea",{"aria-label":`Remarque générale ${ol+1}, copie ${b.id}`,value:D,onChange:pl=>A(_.map((Ft,Ut)=>ol===Ut?pl.target.value:Ft))}),r.jsx("button",{disabled:ol===0,"aria-label":"Monter",onClick:()=>{const pl=[..._];[pl[ol-1],pl[ol]]=[pl[ol],pl[ol-1]],A(pl)},children:"↑"}),r.jsx("button",{disabled:ol===_.length-1,"aria-label":"Descendre",onClick:()=>{const pl=[..._];[pl[ol+1],pl[ol]]=[pl[ol],pl[ol+1]],A(pl)},children:"↓"}),r.jsx("button",{onClick:()=>A(_.filter((pl,Ft)=>Ft!==ol)),children:"Supprimer"})]},ol)),r.jsx("button",{onClick:()=>A([..._,""]),children:"+ Remarque générale"}),r.jsx("button",{disabled:!M[Vt("general",b.id)],onClick:()=>gl([Vt("general",b.id)]),children:"Enregistrer les remarques"})]})]},b.id)})]}),r.jsxs("details",{className:"panel",children:[r.jsxs("summary",{children:["Transferts et coupes ",r.jsx("span",{children:rt?"Brouillon non appliqué":"Brouillon identique aux modifications appliquées"})]}),r.jsx("p",{children:"Les en-têtes et scores restent à leur label. Enregistrer un brouillon ne l’applique pas. Pour annuler un transfert, retirez sa ligne puis régénérez en cochant « Appliquer aussi le brouillon »."}),r.jsx("div",{className:"draft-list",children:al.split(` +`).map((b,_,A)=>b.trim()&&!b.trim().startsWith("###")?r.jsxs("div",{className:"draft-row",children:[r.jsx("code",{children:b}),r.jsx("button",{"aria-label":`Monter l’instruction ${_}`,disabled:_===0||A[_-1].startsWith("###"),onClick:()=>{const D=[...A];[D[_-1],D[_]]=[D[_],D[_-1]],Z("draft","","",D.join(` +`))},children:"↑"}),r.jsx("button",{"aria-label":`Descendre l’instruction ${_}`,disabled:_===A.length-1||!A[_+1].trim(),onClick:()=>{const D=[...A];[D[_+1],D[_]]=[D[_],D[_+1]],Z("draft","","",D.join(` +`))},children:"↓"}),r.jsx("button",{onClick:()=>Z("draft","","",A.filter((D,ol)=>ol!==_).join(` +`)),children:"Retirer"})]},_):null)}),r.jsxs("details",{children:[r.jsx("summary",{children:"Éditer les instructions en texte"}),r.jsx("textarea",{className:"instructions","aria-label":"Brouillon des transferts",value:al,onChange:b=>Z("draft","","",b.target.value)})]}),r.jsx("button",{disabled:!M[Vt("draft")],onClick:()=>gl([Vt("draft")]),children:"Enregistrer le brouillon"}),r.jsxs("details",{children:[r.jsx("summary",{children:"Instructions actuellement appliquées"}),r.jsx("pre",{children:N.applied})]})]}),r.jsxs("div",{className:"results",children:[r.jsxs("h2",{children:[bt.length," réponse",bt.length!==1?"s":""]}),r.jsx("span",{children:!sl&&!el?"Vue d’ensemble · sélectionnez une copie ou un label pour cibler la vérification":"Images annotées après lecture manuscrite"})]}),r.jsx("div",{className:"answer-grid",children:bt.slice(0,R).map(({c:b,a:_})=>r.jsxs("article",{className:"answer",children:[r.jsxs("div",{className:"card-heading",children:[r.jsxs("div",{children:[r.jsxs("span",{className:"eyebrow",children:["COPIE ",b.id," · ",b.name]}),r.jsx("h3",{children:_.label})]}),r.jsx("span",{className:"badge",children:_.info.present?_.info.not_empty?_.info.touched?"Dans le PDF":"Hors PDF filtré":"Réponse vide":"Absente"})]}),r.jsx("div",{className:"image-space",children:_.image?r.jsxs("button",{className:"image-button","aria-label":`Agrandir copie ${b.id} ${_.label}`,onClick:()=>ut({copy:b.id,label:_.label}),children:[r.jsx("img",{loading:"lazy",src:Xi(b.id,_.label,!1,N.revision),alt:`Réponse annotée — copie ${b.id}, ${_.label}`}),r.jsx("span",{children:"Agrandir ↗"})]}):r.jsx("p",{className:"empty",children:"Aucune image pour ce label."})}),r.jsxs("div",{className:"answer-form",children:[r.jsxs("label",{children:["Score",r.jsx("input",{inputMode:"decimal",value:at("score",b.id,_.label,_.score),onChange:A=>Z("score",b.id,_.label,A.target.value)})]}),r.jsxs("label",{children:["Remarque personnelle",r.jsx("textarea",{placeholder:"Ajouter une remarque (LaTeX accepté)",value:at("remark",b.id,_.label,_.remark),onChange:A=>Z("remark",b.id,_.label,A.target.value)})]})]}),r.jsxs("div",{className:"card-actions",children:[r.jsx("button",{disabled:!M[Vt("score",b.id,_.label)]&&!M[Vt("remark",b.id,_.label)],onClick:()=>gl([Vt("score",b.id,_.label),Vt("remark",b.id,_.label)]),children:"Enregistrer"}),r.jsx("button",{disabled:!_.editableBody,onClick:()=>St({copy:b.id,label:_.label}),children:"Couper / transférer"}),r.jsx("a",{href:sn(b.id,"context",_.label),target:"_blank",rel:"noreferrer",children:"Contexte ↗"}),r.jsx("a",{href:sn(b.id,"question",_.label),target:"_blank",rel:"noreferrer",children:"Énoncé ↗"}),r.jsx("a",{href:sn(b.id,"solution",_.label),target:"_blank",rel:"noreferrer",children:"Corrigé ↗"}),r.jsx("a",{href:sn(b.id,"output"),target:"_blank",rel:"noreferrer",children:"PDF final ↗"})]})]},b.id+"|"+_.label))}),bt.length===0&&r.jsx("p",{className:"empty",children:"Aucune réponse ne correspond à ces filtres."}),bt.length>R&&r.jsx("button",{className:"load-more",onClick:()=>T(R+20),children:"Afficher les 20 suivantes"})]}),(N.job.log||N.job.running)&&r.jsxs("details",{className:"panel",open:N.job.status==="failed",children:[r.jsxs("summary",{children:["Journal de régénération · ",N.job.status==="failed"?"Échec / résultat incomplet":N.job.running?"En cours":"Terminée"]}),r.jsx("pre",{className:"log",children:N.job.log})]})]}),Nl&&r.jsx(Sy,{copy:Nl.copy,source:Nl.label,labels:N.labels,mode:N.mode,revision:N.revision,draft:al,close:()=>St(null),accept:b=>{Z("draft","","",b),St(null),$("Instruction ajoutée au brouillon. Enregistrez-le avant de l’appliquer.")}}),Xl&&r.jsx(gy,{copy:Xl.copy,label:Xl.label,revision:N.revision,close:()=>ut(null)})]})}function gy({copy:N,label:X,revision:G,close:h}){const[B,$]=dl.useState(100);return dl.useEffect(()=>{const sl=Bl=>{Bl.key==="Escape"&&h()};return window.addEventListener("keydown",sl),()=>window.removeEventListener("keydown",sl)},[]),r.jsx("div",{className:"overlay",children:r.jsxs("section",{className:"modal viewer",role:"dialog","aria-modal":"true","aria-label":`Copie ${N} ${X}`,children:[r.jsxs("div",{className:"modal-head",children:[r.jsxs("h2",{children:["Copie ",N," · ",X]}),r.jsxs("label",{children:["Zoom ",r.jsx("input",{type:"range",min:"40",max:"200",value:B,onChange:sl=>$(Number(sl.target.value))}),B,"%"]}),r.jsx("button",{autoFocus:!0,onClick:h,children:"Fermer"})]}),r.jsx("div",{className:"zoom-scroll",children:r.jsx("img",{src:Xi(N,X,!1,G),alt:`Copie ${N}, ${X}`,style:{width:B+"%",maxWidth:"none"}})})]})})}function Sy({copy:N,source:X,labels:G,mode:h,revision:B,draft:$,close:sl,accept:Bl}){const[el,Al]=dl.useState(G.find(Z=>Z!==X)||""),[R,T]=dl.useState("cut"),[M,zl]=dl.useState(50),[Gl,Dl]=dl.useState("1"),[il,et]=dl.useState(">"),[Nl,St]=dl.useState(!1),[Xl,ut]=dl.useState(""),[Rl,K]=dl.useState(null),[k,it]=dl.useState(!1),Jl=R==="cut"?`c{${M}}${Gl}${il}`:R,wl=`Copie${N} ${X} ${Jl} ${Nl?"|":""}${el}${Nl?"":"|"}`,Ml=$.trimEnd()+` +`+wl+` +`;dl.useEffect(()=>K(null),[el,R,M,Gl,il,Nl,$]);const at=async()=>{it(!0),ut("");try{K(await ra("preview",{copy:N,source:X,target:el,text:Ml}))}catch(Z){ut(String(Z))}finally{it(!1)}};return r.jsx("div",{className:"overlay",children:r.jsxs("section",{className:"modal",role:"dialog","aria-modal":"true","aria-label":"Couper ou transférer une réponse",children:[r.jsxs("div",{className:"modal-head",children:[r.jsxs("div",{children:[r.jsxs("span",{className:"eyebrow",children:["COPIE ",N," · ",h]}),r.jsx("h2",{children:"Couper ou transférer"})]}),r.jsx("button",{autoFocus:!0,onClick:sl,children:"Fermer"})]}),r.jsx("p",{children:"Seul le corps de la réponse est déplacé. Cliquez sur l’image source pour placer la coupe."}),Xl&&r.jsx("p",{role:"alert",className:"alert",children:Xl}),r.jsxs("div",{className:"cut-controls",children:[r.jsxs("label",{children:["Destination",r.jsx("select",{value:el,onChange:Z=>Al(Z.target.value),children:G.filter(Z=>Z!==X).map(Z=>r.jsx("option",{children:Z},Z))})]}),r.jsxs("label",{children:["Opération",r.jsxs("select",{value:R,onChange:Z=>T(Z.target.value),children:[r.jsx("option",{value:"cut",children:"Couper la source"}),r.jsx("option",{value:"x>",children:"Déplacer et ajouter"}),r.jsx("option",{value:"->",children:"Copier et ajouter"}),r.jsx("option",{value:"xx",children:"Déplacer et remplacer"}),r.jsx("option",{value:"-x",children:"Copier et remplacer"}),r.jsx("option",{value:"xs",children:"Vider la source"}),r.jsx("option",{value:"sx",children:"Vider la cible"}),r.jsx("option",{value:"ss",children:"Conserver les deux"})]})]}),R==="cut"&&r.jsxs(r.Fragment,{children:[r.jsxs("label",{children:["Coupe : ",M,"%",r.jsx("input",{type:"range",min:"1",max:"99",step:"0.1",value:M,onChange:Z=>zl(Number(Z.target.value))})]}),r.jsxs("label",{children:["Conserver à la source",r.jsxs("select",{value:Gl,onChange:Z=>Dl(Z.target.value),children:[r.jsx("option",{value:"1",children:"La partie haute"}),r.jsx("option",{value:"2",children:"La partie basse"})]})]}),r.jsxs("label",{children:["À la destination",r.jsxs("select",{value:il,onChange:Z=>et(Z.target.value),children:[r.jsx("option",{value:">",children:"Ajouter le fragment"}),r.jsx("option",{value:"x",children:"Remplacer le corps"})]})]})]}),r.jsxs("label",{className:"check",children:[r.jsx("input",{type:"checkbox",checked:Nl,onChange:Z=>St(Z.target.checked)}),"Placer avant la cible"]})]}),r.jsxs("div",{className:"compare",children:[r.jsxs("div",{children:[r.jsxs("h3",{children:["Source · ",X]}),r.jsxs("div",{className:"cut-image",onClick:Z=>{if(R==="cut"){const gl=Z.currentTarget.getBoundingClientRect();zl(Math.min(99,Math.max(1,Math.round((Z.clientY-gl.top)/gl.height*1e3)/10)))}},children:[r.jsx("img",{src:Xi(N,X,!0,B),alt:"Corps source sans en-tête"}),R==="cut"&&r.jsx("div",{className:"cut-line",style:{top:M+"%"},children:r.jsxs("span",{children:[M,"%"]})})]})]}),r.jsxs("div",{children:[r.jsxs("h3",{children:["Cible · ",el]}),r.jsx(by,{copy:N,label:el,revision:B},el)]})]}),r.jsx("code",{className:"instruction-line",children:wl}),r.jsxs("div",{className:"modal-actions",children:[r.jsx("button",{disabled:k||!el,onClick:at,children:k?"Calcul de l’aperçu…":"Aperçu du résultat"}),r.jsx("button",{className:"primary",disabled:!Rl||k,onClick:()=>Bl(Ml),children:"Ajouter au brouillon"})]}),Rl&&r.jsxs(r.Fragment,{children:[r.jsx("h3",{children:"Résultat proposé après toutes les instructions du brouillon"}),r.jsx("div",{className:"compare",children:[X,el].map(Z=>r.jsxs("div",{children:[r.jsx("h4",{children:Z}),Rl[Z]?r.jsx("img",{src:Rl[Z],alt:"Aperçu "+Z}):r.jsx("p",{className:"empty",children:"Corps vide"})]},Z))})]}),r.jsx("p",{className:"muted",children:"Une instruction par source ; une cible ne peut pas être source. Modifiez ou retirez une instruction existante dans le panneau « Transferts et coupes »."})]})})}function by({copy:N,label:X,revision:G}){const[h,B]=dl.useState(!1);return h?r.jsx("p",{className:"empty",children:"Pas de corps existant. Le transfert peut remplir cette cible."}):r.jsx("img",{src:Xi(N,X,!0,G),alt:"Corps cible sans en-tête",onError:()=>B(!0)})}hy.createRoot(document.getElementById("root")).render(r.jsx(yy,{})); diff --git a/copienator/web_static/assets/index-B6ukjHTb.css b/copienator/web_static/assets/index-NHKKhh88.css similarity index 96% rename from copienator/web_static/assets/index-B6ukjHTb.css rename to copienator/web_static/assets/index-NHKKhh88.css index 2e040ef..212c2e7 100644 --- a/copienator/web_static/assets/index-B6ukjHTb.css +++ b/copienator/web_static/assets/index-NHKKhh88.css @@ -1 +1 @@ -:root{font-family:Inter,ui-sans-serif,system-ui,sans-serif;color:#23323a;background:#f3f5f4;font-synthesis:none;font-size:14px}*{box-sizing:border-box}body{margin:0}button,input,select,textarea{font:inherit}button,a,input,select,textarea{outline-offset:3px}button{border:1px solid #c8d3ce;border-radius:7px;background:#fff;color:#244b40;padding:9px 13px;cursor:pointer;font-weight:550}button:hover:not(:disabled){background:#e9f1ed;border-color:#769b88}button:disabled{opacity:.45;cursor:default}.primary{background:#205c48;color:#fff;border-color:#205c48}.primary:hover:not(:disabled){background:#174633;color:#fff}a{color:#21654e;text-decoration:none}a:hover{text-decoration:underline}header{display:flex;align-items:center;gap:32px;padding:20px 36px;border-bottom:1px solid #dbe3de;background:#fff}.brand{display:flex;align-items:center;gap:10px;font-size:23px;font-weight:800;color:#28684f}.brand span{font-size:16px;font-weight:650}.heading{flex:1;border-left:1px solid #dbe3de;padding-left:30px}h1{font-size:22px;margin:3px 0 0}h2{font-size:20px;margin:0 0 8px}h3{font-size:19px;margin:7px 0}p{line-height:1.55;margin:8px 0;color:#56666b}.eyebrow{font-size:11px;letter-spacing:.09em;color:#5c7470;font-weight:650}main{max-width:1540px;margin:auto;padding:30px 36px 60px}.toolbar{display:flex;align-items:end;justify-content:space-between;gap:24px;margin-bottom:24px}.filters{display:flex;gap:12px;align-items:end}label{display:flex;flex-direction:column;gap:6px;color:#405650;font-size:12px;font-weight:600}input,select,textarea{border:1px solid #c5d1cb;border-radius:6px;background:#fff;padding:9px 10px;color:#263d34;font-size:14px;min-width:0}textarea{resize:vertical;min-height:76px;line-height:1.5}input:focus,textarea:focus,select:focus{outline:2px solid #80b69c;border-color:#4d8269}input[type=checkbox]{width:16px;height:16px;accent-color:#205c48}.check{display:flex;flex-direction:row;align-items:center;max-width:310px;font-size:12px;line-height:1.4}.publish{display:flex;align-items:center;gap:16px;background:#e8f0eb;border:1px solid #d0e0d5;border-radius:10px;padding:17px 20px;margin:20px 0}.publish>div{flex:1}.publish small{display:block;margin-top:5px;color:#5b6e64}.panel{padding:18px 20px;background:#fff;border:1px solid #d9e2dd;border-radius:9px;margin-bottom:14px}summary{cursor:pointer;font-weight:600}summary span{float:right;font-size:12px;font-weight:400;color:#65766f}.identity{border-top:1px solid #e1e7e3;padding:18px 0;display:grid;grid-template-columns:280px 1fr;gap:28px}.identity-name{display:flex;flex-direction:column;gap:10px;align-items:start}.identity-name label{width:100%}.general button{margin:5px 6px 0 0}.remark-row{display:flex;align-items:center;gap:6px;margin-bottom:8px}.remark-row textarea{flex:1}.instructions{width:100%;font-family:ui-monospace,monospace;min-height:140px;margin:10px 0}.panel details{margin-top:16px}.results{display:flex;justify-content:space-between;align-items:center;margin:30px 0 12px}.results span{color:#677872;font-size:12px}.answer-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px}.answer{border:1px solid #d9e1dd;background:#fff;border-radius:10px;overflow:hidden}.card-heading{display:flex;justify-content:space-between;align-items:center;padding:18px 20px;gap:12px}.badge{font-size:11px;background:#edf1ee;color:#5a6e62;border-radius:4px;padding:5px 7px;white-space:nowrap}.warning{background:#fff2d8;color:#8a620b}.image-space{height:290px;overflow:hidden;background:#e7ece9;border-top:1px solid #e2e8e3;border-bottom:1px solid #e2e8e3;display:flex;justify-content:center;align-items:start;padding:12px}.image-button{position:relative;border:0;padding:0;background:#fff;width:100%;height:100%;overflow:hidden;border-radius:0}.image-button img{width:100%;display:block}.image-button span{position:absolute;bottom:8px;right:8px;background:#203d32e8;color:#fff;border-radius:5px;padding:7px 10px;font-size:12px}.answer-form{display:grid;grid-template-columns:88px 1fr;gap:15px;padding:18px 20px 10px}.card-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:8px 20px 20px}.card-actions a{font-size:12px}.empty{padding:32px;color:#77877e;font-style:italic;text-align:center}.load-more{display:block;margin:24px auto}.alert{background:#fff0eb;color:#8f3827;border:1px solid #e9b6a9;border-radius:7px;padding:12px;display:flex;gap:12px;align-items:center}.alert small{font-size:12px}.notice{color:#216044}.muted{font-size:12px}fieldset{padding:0;margin:0;border:0;min-width:0}.overlay{position:fixed;inset:0;background:#142d23b8;z-index:10;display:flex;align-items:center;justify-content:center;padding:24px}.modal{width:min(1300px,100%);max-height:94vh;overflow:auto;border-radius:12px;background:#f8faf8;padding:24px;box-shadow:0 24px 80px #001c2e55}.modal-head{display:flex;justify-content:space-between;align-items:center;gap:20px}.cut-controls{display:flex;gap:15px;flex-wrap:wrap;margin:20px 0}.compare{display:grid;grid-template-columns:1fr 1fr;gap:24px}.compare>div{min-width:0}.compare img{width:100%;display:block}.cut-image{position:relative;cursor:crosshair}.cut-line{position:absolute;left:0;right:0;height:0;border-top:2px dashed #e15635;pointer-events:none}.cut-line span{position:absolute;right:0;top:0;background:#e15635;color:#fff;padding:3px}.instruction-line{display:block;background:#e7eee9;padding:12px;margin:18px 0;overflow:auto}.modal-actions{display:flex;gap:12px}.viewer{display:flex;flex-direction:column;height:94vh}.zoom-scroll{overflow:auto;flex:1;background:#e2e8e3;margin-top:16px}.zoom-scroll img{display:block}.log{white-space:pre-wrap;background:#15281f;color:#dcecdf;padding:20px;max-height:400px;overflow:auto}.end{max-width:650px;margin:15vh auto}pre{white-space:pre-wrap;overflow-wrap:anywhere}@media(max-width:1000px){header{padding:16px;gap:16px}.brand span{display:none}main{padding:20px}.toolbar,.publish{flex-wrap:wrap}.toolbar>div,.publish>div{width:100%}.answer-grid,.identity{grid-template-columns:1fr}.compare{gap:12px}}@media(max-width:600px){.filters{flex-wrap:wrap}.heading{padding-left:15px}.quiet{max-width:150px}.compare{grid-template-columns:1fr}.overlay{padding:8px}.modal{padding:16px}.remark-row{flex-wrap:wrap}.remark-row textarea{flex-basis:100%}.results span{display:none}}.draft-list{margin:16px 0}.draft-row{display:flex;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid #e2e8e3}.draft-row code{flex:1;overflow-wrap:anywhere}.draft-row button{padding:6px 9px}.publish>div{min-width:190px}@media(max-width:1000px){.publish>div{flex:1 0 100%}} +:root{font-family:Inter,ui-sans-serif,system-ui,sans-serif;color:#23323a;background:#f3f5f4;font-synthesis:none;font-size:14px}*{box-sizing:border-box}body{margin:0}button,input,select,textarea{font:inherit}button,a,input,select,textarea{outline-offset:3px}button{border:1px solid #c8d3ce;border-radius:7px;background:#fff;color:#244b40;padding:9px 13px;cursor:pointer;font-weight:550}button:hover:not(:disabled){background:#e9f1ed;border-color:#769b88}button:disabled{opacity:.45;cursor:default}.primary{background:#205c48;color:#fff;border-color:#205c48}.primary:hover:not(:disabled){background:#174633;color:#fff}a{color:#21654e;text-decoration:none}a:hover{text-decoration:underline}header{display:flex;align-items:center;gap:32px;padding:20px 36px;border-bottom:1px solid #dbe3de;background:#fff}.brand{display:flex;align-items:center;gap:10px;font-size:23px;font-weight:800;color:#28684f}.brand span{font-size:16px;font-weight:650}.heading{flex:1;border-left:1px solid #dbe3de;padding-left:30px}h1{font-size:22px;margin:3px 0 0}h2{font-size:20px;margin:0 0 8px}h3{font-size:19px;margin:7px 0}p{line-height:1.55;margin:8px 0;color:#56666b}.eyebrow{font-size:11px;letter-spacing:.09em;color:#5c7470;font-weight:650}main{max-width:1540px;margin:auto;padding:30px 36px 60px}.toolbar{display:flex;align-items:end;justify-content:space-between;gap:24px;margin-bottom:24px}.filters{display:flex;gap:12px;align-items:end}label{display:flex;flex-direction:column;gap:6px;color:#405650;font-size:12px;font-weight:600}input,select,textarea{border:1px solid #c5d1cb;border-radius:6px;background:#fff;padding:9px 10px;color:#263d34;font-size:14px;min-width:0}textarea{resize:vertical;min-height:76px;line-height:1.5}input:focus,textarea:focus,select:focus{outline:2px solid #80b69c;border-color:#4d8269}input[type=checkbox]{width:16px;height:16px;accent-color:#205c48}.check{display:flex;flex-direction:row;align-items:center;max-width:310px;font-size:12px;line-height:1.4}.publish{display:flex;align-items:center;gap:16px;background:#e8f0eb;border:1px solid #d0e0d5;border-radius:10px;padding:17px 20px;margin:20px 0}.publish>div{flex:1}.publish small{display:block;margin-top:5px;color:#5b6e64}.panel{padding:18px 20px;background:#fff;border:1px solid #d9e2dd;border-radius:9px;margin-bottom:14px}summary{cursor:pointer;font-weight:600}summary span{float:right;font-size:12px;font-weight:400;color:#65766f}.identity{border-top:1px solid #e1e7e3;padding:18px 0;display:grid;grid-template-columns:280px 1fr;gap:28px}.identity-name{display:flex;flex-direction:column;gap:10px;align-items:start}.identity-name label{width:100%}.general button{margin:5px 6px 0 0}.remark-row{display:flex;align-items:center;gap:6px;margin-bottom:8px}.remark-row textarea{flex:1}.instructions{width:100%;font-family:ui-monospace,monospace;min-height:140px;margin:10px 0}.panel details{margin-top:16px}.results{display:flex;justify-content:space-between;align-items:center;margin:30px 0 12px}.results span{color:#677872;font-size:12px}.answer-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px}.answer{border:1px solid #d9e1dd;background:#fff;border-radius:10px;overflow:hidden}.card-heading{display:flex;justify-content:space-between;align-items:center;padding:18px 20px;gap:12px}.badge{font-size:11px;background:#edf1ee;color:#5a6e62;border-radius:4px;padding:5px 7px;white-space:nowrap}.warning{background:#fff2d8;color:#8a620b}.image-space{height:290px;overflow:hidden;background:#e7ece9;border-top:1px solid #e2e8e3;border-bottom:1px solid #e2e8e3;display:flex;justify-content:center;align-items:start;padding:12px}.image-button{position:relative;border:0;padding:0;background:#fff;width:100%;height:100%;overflow:hidden;border-radius:0}.image-button img{width:100%;display:block}.image-button span{position:absolute;bottom:8px;right:8px;background:#203d32e8;color:#fff;border-radius:5px;padding:7px 10px;font-size:12px}.answer-form{display:grid;grid-template-columns:88px 1fr;gap:15px;padding:18px 20px 10px}.card-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px;padding:8px 20px 20px}.card-actions a{font-size:12px}.empty{padding:32px;color:#77877e;font-style:italic;text-align:center}.load-more{display:block;margin:24px auto}.alert{background:#fff0eb;color:#8f3827;border:1px solid #e9b6a9;border-radius:7px;padding:12px;display:flex;gap:12px;align-items:center}.alert small{font-size:12px}.notice{color:#216044}.muted{font-size:12px}fieldset{padding:0;margin:0;border:0;min-width:0}.overlay{position:fixed;inset:0;background:#142d23b8;z-index:10;display:flex;align-items:center;justify-content:center;padding:24px}.modal{width:min(1300px,100%);max-height:94vh;overflow:auto;border-radius:12px;background:#f8faf8;padding:24px;box-shadow:0 24px 80px #001c2e55}.modal-head{display:flex;justify-content:space-between;align-items:center;gap:20px}.cut-controls{display:flex;gap:15px;flex-wrap:wrap;margin:20px 0}.compare{display:grid;grid-template-columns:1fr 1fr;gap:24px}.compare>div{min-width:0}.compare img{width:100%;display:block}.cut-image{position:relative;cursor:crosshair}.cut-line{position:absolute;left:0;right:0;height:0;border-top:2px dashed #e15635;pointer-events:none}.cut-line span{position:absolute;right:0;top:0;background:#e15635;color:#fff;padding:3px}.instruction-line{display:block;background:#e7eee9;padding:12px;margin:18px 0;overflow:auto}.modal-actions{display:flex;gap:12px}.viewer{display:flex;flex-direction:column;height:94vh}.zoom-scroll{overflow:auto;flex:1;background:#e2e8e3;margin-top:16px}.zoom-scroll img{display:block}.log{white-space:pre-wrap;background:#15281f;color:#dcecdf;padding:20px;max-height:400px;overflow:auto}.end{max-width:650px;margin:15vh auto}pre{white-space:pre-wrap;overflow-wrap:anywhere}@media(max-width:1000px){header{padding:16px;gap:16px}.brand span{display:none}main{padding:20px}.toolbar,.publish{flex-wrap:wrap}.toolbar>div,.publish>div{width:100%}.answer-grid,.identity{grid-template-columns:1fr}.compare{gap:12px}}@media(max-width:600px){.filters{flex-wrap:wrap}.heading{padding-left:15px}.quiet{max-width:150px}.compare{grid-template-columns:1fr}.overlay{padding:8px}.modal{padding:16px}.remark-row{flex-wrap:wrap}.remark-row textarea{flex-basis:100%}.results span{display:none}}.draft-list{margin:16px 0}.draft-row{display:flex;align-items:center;gap:8px;padding:8px 0;border-bottom:1px solid #e2e8e3}.draft-row code{flex:1;overflow-wrap:anywhere}.draft-row button{padding:6px 9px}.publish>div{min-width:190px}@media(max-width:1000px){.publish>div{flex:1 0 100%}}.identity-overview{margin-top:18px;padding:16px;background:#f3f6f4;border-radius:7px}.identity-overview .check{max-width:none;margin-top:14px}.missing-names{display:flex;flex-wrap:wrap;gap:6px 24px;padding-left:20px;margin:10px 0 16px} diff --git a/copienator/web_static/index.html b/copienator/web_static/index.html index 9d2c8f6..12444b3 100644 --- a/copienator/web_static/index.html +++ b/copienator/web_static/index.html @@ -1,3 +1,3 @@ -Copienator · Finalisation - +Copienator · Finalisation +
diff --git a/copienator_gui/app.py b/copienator_gui/app.py index 69ecd16..6363180 100644 --- a/copienator_gui/app.py +++ b/copienator_gui/app.py @@ -360,7 +360,12 @@ class CopienatorApp(tk.Tk): top, text="Ouvrir l’énoncé", command=self._open_statement_pdf ) self.open_statement_button.grid(row=0, column=5, padx=(6, 0)) - ttk.Button(top, text="Finalisation web…", command=self._open_finalisation_web).grid(row=0, column=6, padx=(6, 0)) + self.finalisation_web_button = ttk.Button( + top, text="Finalisation web…", command=self._open_finalisation_web, state="disabled" + ) + self.finalisation_web_button.grid(row=0, column=6, padx=(6, 0)) + attach_tooltip(self.finalisation_web_button, + "Disponible après une première lecture des annotations manuscrites (Bnot ou BGnot).") ttk.Button(top, text="Diagnostic…", command=self._show_diagnostics).grid(row=0, column=7, padx=(6, 0)) ttk.Label(top, text="Clé Gemini").grid(row=1, column=0, sticky="w", padx=(0, 8), pady=(7, 0)) @@ -538,6 +543,19 @@ class CopienatorApp(tk.Tk): status = ttk.Label(self, textvariable=self.info_var, anchor="w", relief="sunken", padding=(6, 3)) status.grid(row=3, column=0, sticky="ew") + def _has_finalisation_outputs(self) -> bool: + evaluation = self.state_store.evaluation + if evaluation is None: + return False + # Detect actual read results, including evaluations processed through the CLI. + # Review-sheet generation alone does not create info.json. + return any( + directory.is_dir() and directory.name[5:].isdigit() + and (directory / "score.json").is_file() and (directory / "info.json").is_file() + for mode in ("Bnot", "BGnot") + for directory in (evaluation / mode).glob("Copie*") + ) + def _open_finalisation_web(self) -> None: if self.web_session is not None or self.runner.running or self.active_step_id or self.batch_monitor.active: messagebox.showinfo("Traitement en cours", "Terminez le traitement ou la surveillance en cours avant d’ouvrir la finalisation web.") @@ -545,6 +563,9 @@ class CopienatorApp(tk.Tk): if not self.evaluation: messagebox.showerror("Évaluation absente", "Chargez d’abord une évaluation.") return + if not self._has_finalisation_outputs(): + messagebox.showinfo("Finalisation web", "Exécutez d’abord « Lire les annotations manuscrites ».") + return self._save_current_form() dialog = tk.Toplevel(self) dialog.title("Finalisation web") @@ -615,7 +636,7 @@ class CopienatorApp(tk.Tk): def start(): try: from copienator.finalisation_server import WebSession - self.web_session = WebSession(self.evaluation, mode.get()) + self.web_session = WebSession(self.evaluation, mode.get(), repository=self.repository) except Exception as exc: messagebox.showerror("Finalisation web", str(exc), parent=dialog) return @@ -2417,6 +2438,10 @@ class CopienatorApp(tk.Tk): def _update_controls(self) -> None: running = bool(self.active_step_id) or self.runner.running + self.finalisation_web_button.configure( + state="normal" if not running and self.web_session is None + and not self.batch_monitor.active and self._has_finalisation_outputs() else "disabled" + ) if self.current_step and self.current_step.id == "personal_read": for button in self.review_buttons: button.configure(state="disabled" if running or not self.state_store.evaluation else "normal") diff --git a/docs/finalisation_web.md b/docs/finalisation_web.md index e87ff3d..9d738b8 100644 --- a/docs/finalisation_web.md +++ b/docs/finalisation_web.md @@ -59,6 +59,17 @@ l’appliquer annule le transfert correspondant. Les contraintes existantes rest valables : une instruction par source, une cible ne peut pas être source, aucun déplacement automatique des scores ou des en-têtes. +La case **Ignorer les copies inchangées**, cochée par défaut près du bouton de +régénération, évite de recomposer les copies et dossiers de retour dont les entrées +n’ont pas changé. Une modification de score ou de remarque ne reconstruit que la +copie concernée ; les changements de documents partagés peuvent concerner toute +la classe. Le premier passage établit les empreintes nécessaires. Les changements de noms +seuls sont suivis séparément : ils ne relancent pas la composition des corrections, +même avant ce premier passage. Enregistrer un nom renomme déjà son dossier de +retour existant et ses fichiers principaux. Les fichiers +manquants sont reconstruits et les échecs sont retentés. Décochez cette case pour +forcer une régénération complète. Le journal signale les copies ignorées. + La régénération actualise les réponses, les documents combinés et **A Rendre** selon les options de sortie existantes, en conservant les noms personnalisés. Le journal indique les erreurs et les résultats incomplets. La chaîne s’arrête diff --git a/tests/test_finalisation_web.py b/tests/test_finalisation_web.py index a58336f..e3040ee 100644 --- a/tests/test_finalisation_web.py +++ b/tests/test_finalisation_web.py @@ -58,6 +58,25 @@ class WebTests(unittest.TestCase): self.assertEqual(response.status_code, 200, response.text) return response.json() + def test_names_follow_gui_repository_even_when_package_is_elsewhere(self): + repository = self.root / 'application-folder' + repository.mkdir() + (repository / 'names').write_text('Alice\nBob\n', encoding='utf-8') + service = Finalisation(self.root, 'Bnot', 'token', repository=repository) + self.assertEqual(service.state()['expectedNames'], ['Alice', 'Bob']) + (self.root / 'names').write_text('Claire\n', encoding='utf-8') + self.assertEqual(service.state()['expectedNames'], ['Claire']) + + def test_expected_names_use_local_roster_and_refresh_after_name_save(self): + (self.root / 'names').write_text('Alice\nBob\nAlice\n\n', encoding='utf-8') + state = self.client.get('/api/state').json() + self.assertEqual(state['expectedNames'], ['Alice', 'Bob']) + state = self.save('name', 'Alice') + self.assertEqual(state['copies'][0]['name'], 'Alice') + self.assertEqual(state['expectedNames'], ['Alice', 'Bob']) + (self.root / 'names').write_text('', encoding='utf-8') + self.assertEqual(self.service.state()['expectedNames'], []) + def test_session_origin_and_paths(self): outsider = TestClient(create_app(self.service, 'browser-token')) self.assertEqual(outsider.get('/api/state').status_code, 403) @@ -164,6 +183,35 @@ class WebTests(unittest.TestCase): self.assertEqual(len(calls), 1) self.assertEqual(self.service.job['status'], 'failed') + def test_names_only_skip_rendering_before_first_cache_and_after_restart(self): + from copienator.review_snapshot import stage + output = self.root / 'Bnot/Copie01' + data = {'Ex 1': {'pdf_path': self.root/'Copies/Copie01/Ex 1.pdf', + 'result': {'score': 3, 'feedback': []}, 'coordinates': [0, 0]}} + with staged_files(output) as staging: + stage(output, staging, data, {}, engine='standard', bnote={'images': []}) + self.save('name', 'Alice') + self.assertFalse((output / '.reviewed-render-state.json').exists()) + reopened = Finalisation(self.root, 'Bnot', 'token') + calls = [] + class Process: + def __init__(self, command, **kwargs): + calls.append(command[3]) + self.stdout = StringIO('done\n') + def __enter__(self): return self + def __exit__(self, *args): pass + def wait(self): return 0 + with patch('copienator.finalisation.subprocess.Popen', Process): + reopened._regenerate(False) + self.assertEqual(calls, ['giving-names']) + self.save('name', 'Bob') + # A score edited outside the session must invalidate the names-only shortcut. + set_score(output/'score.json', 'Ex 1', '1') + calls.clear() + with patch('copienator.finalisation.subprocess.Popen', Process): + self.service._regenerate(False) + self.assertEqual(calls, ['regenerate-reviewed', 'giving-names']) + def test_os_lock_blocks_cli_and_releases(self): with EvaluationLock(self.root): with self.assertRaises(CliError): @@ -256,6 +304,33 @@ class SnapshotTests(unittest.TestCase): @unittest.skipUnless(os.environ.get('DISPLAY'), 'Tk requires a display') class WebGuiTests(unittest.TestCase): + def test_web_button_requires_read_outputs_and_remains_enabled_when_stale(self): + from copienator_gui.app import CopienatorApp + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + (root / 'Copies').mkdir() + (root / 'labels').write_text('Ex 1\n') + app = CopienatorApp(Path.cwd(), False, root) + self.addCleanup(app.destroy) + def state(): + app._update_controls() + return str(app.finalisation_web_button.cget('state')) + self.assertEqual(state(), 'disabled') + output = root / 'BGnot/Copie01' + output.mkdir(parents=True) + atomic_write_json(output/'bnote.json', {'images': []}) + self.assertEqual(state(), 'disabled') + seed(root, 'BGnot') + self.assertEqual(state(), 'normal') + app.state_store.update_step('read_annotations', status='stale') + self.assertEqual(state(), 'normal') + app.active_step_id = 'read_annotations' + self.assertEqual(state(), 'disabled') + app.active_step_id = None + self.assertEqual(state(), 'normal') + app.state_store.evaluation = None + self.assertEqual(state(), 'disabled') + def test_modal_lock_and_return_to_existing_workflow(self): from copienator_gui.app import CopienatorApp from copienator.finalisation_server import WebSession @@ -295,3 +370,90 @@ class WebGuiTests(unittest.TestCase): self.assertIsNone(app.web_session) self.assertIsNone(app.grab_current()) self.assertEqual(app.state_store.step('read_annotations')['status'], 'stale') + + +class IncrementalReviewedTests(unittest.TestCase): + def test_only_changed_copies_render_and_missing_outputs_are_retried(self): + from copienator.commands import regenerate_reviewed, annotating + from copienator.review_snapshot import stage + from copienator.custom_remarks import set_remark + import shutil + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + seed(root, 'BGnot') + pdf = root / 'Copies/Copie01/Ex 1.pdf' + pdf.write_bytes(b'answer') + data = {'Ex 1': {'pdf_path':pdf, 'result':{'score':3,'feedback':[]},'coordinates':[0,0]}} + output = root / 'BGnot/Copie01' + with staged_files(output) as staging: + stage(output, staging, data, {}, engine='grouped') + shutil.copytree(output, root / 'BGnot/Copie02') + workspace = EvaluationWorkspace(root) + with patch.object(annotating, 'make_base_image', return_value=(Image.new('RGB',(100,100),'white'),0,0)), \ + patch.object(annotating, 'compose_label_image', return_value=(Image.new('RGB',(100,120),'white'),20)) as compose, \ + patch('copienator.commands.reading_grouped_annotations.get_extra_pdfs_as_images', return_value=[]): + def run(count): + compose.reset_mock() + self.assertEqual(regenerate_reviewed.run(workspace,'BGnot',incremental=True), 0) + self.assertEqual(compose.call_count,count) + run(2) + run(0) + set_score(output/'score.json','Ex 1','2') + run(1) + run(0) + set_remark(root,'01','Ex 1','Justifier.') + run(1) + set_remark(root,'01','Ex 1','') + run(1) + (output/'Ex 1.jpg').unlink() + run(1) + (root/'Text2').mkdir() + (root/'Text2/Ex 1.pdf').write_bytes(b'changed question') + run(2) + run(0) + self.assertEqual(regenerate_reviewed.run(workspace,'BGnot'),0) + self.assertEqual(compose.call_count,2) + + def test_incremental_transfers_apply_changes_and_undo_without_repeating(self): + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + seed(root) + workspace = EvaluationWorkspace(root) + from copienator.annotation_modifications import rebuild + with patch.object(modify_annotations, 'rebuild', wraps=rebuild) as render: + def run(text, count): + (root / DRAFT).write_text('### Source: Bnot\n' + text) + render.reset_mock() + self.assertEqual(modify_annotations.run(workspace, annotation_dir='Bnot', incremental=True), 0) + self.assertEqual(render.call_count, count) + run('Copie01 Ex 1 c{40}1> Ex 2|\n', 1) + run('Copie01 Ex 1 c{40}1> Ex 2|\n', 0) + run('Copie01 Ex 1 c{50}1> Ex 2|\n', 1) + run('', 1) + run('', 0) + self.assertEqual(Image.open(root/'Bnot/Copie01/Ex 1.jpg').height,120) + + @patch('copienator.commands.giving_names.configuration.RETURN_ANSWERS_ENABLED', False) + def test_return_publication_skips_unchanged_and_repairs_missing_files(self): + import shutil + with tempfile.TemporaryDirectory() as temporary: + root = Path(temporary) + seed(root) + shutil.copytree(root/'Bnot/Copie01',root/'Bnot/Copie02') + atomic_write_json(root/'Copies/Copie02.json',{'name':'Bob'}) + atomic_write_json(root/'Copies/Copie01.json',{'name':'Alice'}) + workspace = EvaluationWorkspace(root) + from copienator.return_answers import publish_answer_returns + with patch.object(giving_names,'publish_answer_returns',wraps=publish_answer_returns) as publish: + def run(count): + publish.reset_mock() + self.assertEqual(giving_names.prepare_named_returns(workspace,'Bnot',incremental=True),0) + self.assertEqual(publish.call_count,count) + run(2) + run(0) + set_score(root/'Bnot/Copie01/score.json','Ex 1','1') + run(1) + run(0) + (root/'A Rendre/Bob (02)/info.json').unlink() + run(1) + self.assertTrue((root/'A Rendre/Bob (02)/info.json').is_file()) diff --git a/web/src/main.tsx b/web/src/main.tsx index 27fe632..7be9f75 100644 --- a/web/src/main.tsx +++ b/web/src/main.tsx @@ -5,7 +5,7 @@ import './style.css'; type Answer = {label:string;score:string;remark:string;image:boolean;editableBody:boolean;info:{present?:boolean;not_empty?:boolean;touched?:boolean}}; type Copy = {id:string;name:string;general:string[];answers:Answer[]}; type Job = {running:boolean;status:string;log:string}; -type State = {evaluation:string;mode:string;labels:string[];copies:Copy[];draft:string;applied:string;revision:string;dirty:boolean;job:Job}; +type State = {evaluation:string;mode:string;labels:string[];copies:Copy[];expectedNames:string[]|null;draft:string;applied:string;revision:string;dirty:boolean;job:Job}; type Edit = {kind:string;copy:string;label:string;value:string|string[]}; async function api(path:string, data?:unknown) { const response=await fetch('/api/'+path, data===undefined?{}:{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify(data)}); @@ -22,6 +22,8 @@ function App(){ const [edits,setEdits]=useState>({}),[busy,setBusy]=useState(false),[applyDraft,setApplyDraft]=useState(false); const [cut,setCut]=useState<{copy:string;label:string}|null>(null),[zoom,setZoom]=useState<{copy:string;label:string}|null>(null); const [stopped,setStopped]=useState(false); + const [onlyNameIssues,setOnlyNameIssues]=useState(false); + const [incremental,setIncremental]=useState(true); const refresh=async()=>{try{setState(await api('state'));setError('')}catch(e){setError(String(e))}}; useEffect(()=>{void refresh()},[]); useEffect(()=>{const protect=(e:BeforeUnloadEvent)=>{if(Object.keys(edits).length){e.preventDefault();e.returnValue=''}};window.addEventListener('beforeunload',protect);return()=>window.removeEventListener('beforeunload',protect)},[edits]); @@ -29,7 +31,7 @@ function App(){ const value=(kind:string,copy:string,label:string,fallback:string|string[])=>edits[keyOf(kind,copy,label)]?.value??fallback; const edit=(kind:string,copy:string,label:string,v:string|string[])=>setEdits(old=>({...old,[keyOf(kind,copy,label)]:{kind,copy,label,value:v}})); const save=async(keys:string[])=>{if(!state)return;setBusy(true);setError('');let latest=state;try{for(const key of keys){const change=edits[key];if(!change)continue;latest=await api('change',{...change,revision:latest.revision});setState(latest);setEdits(old=>{const next={...old};delete next[key];return next})}setNotice('Modifications enregistrées.')}catch(e){setError(String(e))}finally{setBusy(false)}}; - const regenerate=async()=>{if(!state)return;setBusy(true);setError('');try{const job=await api('regenerate',{revision:state.revision,apply_draft:applyDraft});setState({...state,job});setNotice('')}catch(e){setError(String(e))}finally{setBusy(false)}}; + const regenerate=async()=>{if(!state)return;setBusy(true);setError('');try{const job=await api('regenerate',{revision:state.revision,apply_draft:applyDraft,incremental});setState({...state,job});setNotice('')}catch(e){setError(String(e))}finally{setBusy(false)}}; const stop=async()=>{try{await api('stop',{});setStopped(true)}catch(e){setError(String(e))}}; if(stopped)return

Session terminée

Vous pouvez reprendre le travail dans Copienator.

; if(!state)return

Copienator

{error||'Chargement de la finalisation…'}

; @@ -41,15 +43,18 @@ function App(){ const cards=matches.flatMap(c=>c.answers.filter(a=>!labelFilter||a.label===labelFilter).map(a=>({c,a}))); const names=new Map();state.copies.forEach(c=>names.set(c.name.toLowerCase(),(names.get(c.name.toLowerCase())||0)+1)); const issues=state.copies.filter(c=>c.name.toLowerCase()==='unknown'||(names.get(c.name.toLowerCase())||0)>1); + const identityMatches=matches.filter(c=>!onlyNameIssues||issues.includes(c)); + const assignedNames=new Set(state.copies.map(c=>c.name.trim().toLocaleLowerCase('fr'))); + const missingNames=state.expectedNames?.filter(name=>!assignedNames.has(name.trim().toLocaleLowerCase('fr'))); return <>
CCopienator
FINALISATION · {state.mode}

{state.evaluation}

Vérifier les copies

Retrouvez une copie, une question, ou leur intersection.

{state.copies.map(c=>)}
{error&&
{error}Les saisies non enregistrées restent dans la page.
} {notice&&

{notice}

} -
{state.job.running?'Régénération en cours…':pending?`${pending} modification(s) non enregistrée(s)`:state.dirty?'Enregistré · sorties à régénérer':'Modifications enregistrées'}Les sorties comprennent les images, PDF et le dossier A Rendre configurés.
{pending>0&&}
+
{state.job.running?'Régénération en cours…':pending?`${pending} modification(s) non enregistrée(s)`:state.dirty?'Enregistré · sorties à régénérer':'Modifications enregistrées'}Les sorties comprennent les images, PDF et le dossier A Rendre configurés.
{pending>0&&}
-
Identités et remarques générales {issues.length} nom(s) à vérifier

Les remarques sont composées en LaTeX. Leur ordre est celui de la liste.

{matches.map(c=>{const general=value('general',c.id,'',c.general) as string[];const changeGeneral=(next:string[])=>edit('general',c.id,'',next);return
Copie {c.id}{issues.includes(c)&&Nom à vérifier}Voir l’originale ↗
{general.map((text,i)=>