/* validation_builder -- one stylesheet, no framework, no build step.
   Follows the house conventions: custom properties at :root, dark by default like
   photo_cluster_lab, and nothing that needs compiling. */
:root {
  --bg: #12141a;
  --surface: #181b23;
  --surface-2: #1f2430;
  --border: #2b3140;
  --text: #dfe3ec;
  --muted: #8d95a8;
  --dim: #5d6477;
  --primary: #4f8ef7;
  --good: #3fb06a;
  --bad: #e2565c;
  --warn: #d9a441;
  --radius: 6px;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 14px/1.5 system-ui, -apple-system, "Segoe UI", sans-serif;
}

.hidden { display: none !important; }
.grow { flex: 1; }
.dim { color: var(--dim); }
.hint { color: var(--muted); font-size: 12px; margin: 4px 0 12px; max-width: 70ch; }
.sep { width: 1px; height: 20px; background: var(--border); margin: 0 6px; }

/* ---------------------------------------------------------------- topbar */
.topbar {
  display: flex; align-items: center; gap: 12px;
  padding: 10px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  position: sticky; top: 0; z-index: 20;
}
.topbar h1 { font-size: 15px; margin: 0; font-weight: 600; letter-spacing: .2px; }
.tabs { display: flex; gap: 4px; }
.tab {
  background: none; border: 1px solid transparent; color: var(--muted);
  padding: 5px 12px; border-radius: var(--radius); cursor: pointer; font-size: 13px;
}
.tab:hover { color: var(--text); }
.tab.active { background: var(--surface-2); border-color: var(--border); color: var(--text); }

.badge {
  font-size: 11px; padding: 2px 8px; border-radius: 10px;
  border: 1px solid var(--border); color: var(--muted); cursor: help;
}
.badge.readonly { border-color: #2f5d3f; color: var(--good); }

.progress { font-size: 12px; color: var(--muted); font-family: var(--mono); }

select, input, textarea {
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 5px 8px; font: inherit;
}
textarea { font-family: var(--mono); font-size: 12px; width: 100%; }

button {
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--radius);
  padding: 5px 11px; cursor: pointer; font: inherit;
}
button:hover { border-color: var(--primary); }
button.primary { background: var(--primary); border-color: var(--primary); color: #fff; }
button.primary:hover { filter: brightness(1.1); }
button.ghost { background: none; color: var(--muted); }
button.ghost:hover { color: var(--text); }
button:disabled { opacity: .45; cursor: not-allowed; }

/* ------------------------------------------------------------ job + error */
.job {
  display: flex; align-items: center; gap: 12px;
  padding: 8px 16px; background: var(--surface-2);
  border-bottom: 1px solid var(--border); font-size: 12px;
}
.job .bar { flex: 1; height: 4px; background: var(--border); border-radius: 2px; overflow: hidden; }
.job .bar > div { height: 100%; background: var(--primary); width: 0; transition: width .2s; }

.error {
  padding: 10px 16px; background: #3a1d20; color: #ffc9cc;
  border-bottom: 1px solid #5c2a2f; font-size: 13px; white-space: pre-wrap;
}

/* ------------------------------------------------------------------ panes */
.tabpane { display: flex; gap: 0; align-items: flex-start; }
.panel-wide { padding: 20px 24px; max-width: 1200px; }

.sidebar {
  width: 260px; flex: 0 0 260px; padding: 14px;
  border-right: 1px solid var(--border);
  height: calc(100vh - 53px); overflow-y: auto; position: sticky; top: 53px;
}
.sidebar h2 { font-size: 13px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--muted); margin: 0 0 6px; }

.work { flex: 1; padding: 16px 20px; min-width: 0; }
.empty { color: var(--muted); padding: 60px 20px; text-align: center; }

.photolist { list-style: none; margin: 0; padding: 0; }
.photolist li {
  padding: 7px 8px; border-radius: var(--radius); cursor: pointer;
  font-family: var(--mono); font-size: 11px; color: var(--muted);
}
.photolist li:hover { background: var(--surface-2); color: var(--text); }
.photolist li.active { background: var(--surface-2); color: var(--text); }
.photolist li.done { color: var(--good); }
.photolist li.skipped { color: var(--dim); font-style: italic; cursor: not-allowed; }
.photolist .mini { display: block; height: 3px; background: var(--border);
  border-radius: 2px; margin-top: 4px; }
.photolist .mini > i { display: block; height: 100%; background: var(--good); border-radius: 2px; }

/* ---------------------------------------------------------------- overlay */
.overlay-wrap { margin-bottom: 14px; }
.overlay { position: relative; display: inline-block; max-width: 100%; line-height: 0; }
.overlay img { max-width: 100%; height: auto; display: block; border-radius: var(--radius); }
.overlay svg { position: absolute; inset: 0; width: 100%; height: 100%; }
/* SCOPED AWAY FROM THE RESULTS OVERLAY. A CSS rule beats a presentation attribute, so an
   unscoped `fill: transparent` here would silently win over the `fill="..."` the results
   overlay sets per rect and paint every facing empty -- with nothing in the console to say so. */
.overlay:not(.shaded) rect { fill: transparent; stroke-width: 3; cursor: pointer; }
.overlay:not(.shaded) rect.sel { fill: rgba(79,142,247,.28); stroke-width: 4; }
.overlay:not(.shaded) rect.hot { fill: rgba(255,255,255,.18); }
.overlay.shaded rect { cursor: default; }

/* THE MARQUEE, and what it is about to take. `banding` is shown while the drag is live so the
   band's effect is visible before the mouse comes up -- the alternative is selecting, looking,
   and undoing. `unbanding` is the alt-drag that takes facings back OUT of the selection, drawn
   in the warn colour so add and remove are never read as the same gesture. */
.overlay:not(.shaded) rect.marquee {
  fill: rgba(79,142,247,.12); stroke: var(--primary); stroke-width: 2;
  stroke-dasharray: 6 4; pointer-events: none;
}
.overlay:not(.shaded) rect.marquee.sub { fill: rgba(217,164,65,.12); stroke: var(--warn); }
.overlay:not(.shaded) rect.banding { fill: rgba(79,142,247,.34); stroke-width: 4; }
.overlay:not(.shaded) rect.unbanding { fill: rgba(217,164,65,.30); stroke-width: 4; }
/* A drag over the photo must not leave the browser selecting the page text underneath it. */
.overlay { user-select: none; -webkit-user-select: none; }

/* ---------------------------------------------------------------- toolbar */
.toolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; }
.selcount { font-size: 12px; color: var(--muted); min-width: 150px; font-family: var(--mono); }

.assign {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 10px 12px; margin-bottom: 14px;
}
.assign-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.assign-row + .assign-row { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border); }
.assign-row label { font-size: 12px; color: var(--muted); }
.assign-row input { min-width: 220px; }
/* The assign row is dead weight with nothing selected and the thing you are aiming at the
   moment something is, so it says which of the two it currently is. */
.assign.active { border-color: var(--primary); box-shadow: inset 3px 0 0 var(--primary); }

/* ------------------------------------------------- the results threshold */
.threshold {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 8px 12px; margin-bottom: 8px;
}
.threshold label { font-size: 12px; color: var(--muted); }
.threshold input[type=range] { flex: 1 1 260px; min-width: 200px; accent-color: var(--primary); }
.threshold output { font-size: 13px; min-width: 46px; text-align: right; }
.mono { font-family: var(--mono); }
/* AN EXCLUDED PHOTO IS STRUCK THROUGH, NOT HIDDEN -- it is still clickable, because a photo
   dropped for scoring badly is usually the one worth looking at. */
.ptable tr.excluded td { opacity: .42; text-decoration: line-through; }
.ptable tr.excluded td:first-child { text-decoration: none; }
.assign:not(.active) .assign-row:first-child { opacity: .6; }

/* ---------------------------------------------------------------- facings */
.facings { display: grid; grid-template-columns: repeat(auto-fill, minmax(124px, 1fr)); gap: 10px; }
.card {
  background: var(--surface); border: 2px solid var(--border);
  border-radius: var(--radius); padding: 6px; cursor: pointer; position: relative;
}
.card:hover { border-color: var(--muted); }
.card.sel { border-color: var(--primary); background: var(--surface-2); }
.card img { width: 100%; height: 108px; object-fit: contain; background: #0c0e13;
  border-radius: 3px; display: block; }
.card .lab { font-size: 11px; margin-top: 5px; line-height: 1.35; word-break: break-word; }
.card .kind { font-family: var(--mono); font-size: 10px; text-transform: uppercase;
  letter-spacing: .4px; }
.card .kind.brand { color: var(--good); }
.card .kind.unknown { color: var(--warn); }
.card .kind.product_unidentifiable { color: var(--primary); }
.card .kind.not_a_product, .card .kind.exclude { color: var(--dim); }
.card .kind.none { color: var(--dim); }
.card .second { color: var(--muted); font-size: 10px; }
.card .prod { color: var(--dim); font-size: 10px; margin-top: 3px; }
.card .prod button { padding: 1px 5px; font-size: 10px; margin-left: 2px; }
.card .idx { position: absolute; top: 4px; left: 6px; font-size: 9px; color: var(--dim);
  font-family: var(--mono); background: rgba(0,0,0,.55); padding: 0 3px; border-radius: 2px; }

/* ----------------------------------------------------------------- tables */
.table { width: 100%; border-collapse: collapse; font-size: 13px; margin-bottom: 24px; }
.table th, .table td { text-align: left; padding: 7px 10px; border-bottom: 1px solid var(--border); }
.table th { color: var(--muted); font-weight: 500; font-size: 11px;
  text-transform: uppercase; letter-spacing: .5px; }
.table td.num, .table th.num { text-align: right; font-family: var(--mono); }
.table tr.active td { background: var(--surface-2); }
.table .stale { color: var(--warn); font-size: 11px; }

.form { display: flex; gap: 12px; align-items: flex-end; flex-wrap: wrap; margin-bottom: 20px; }
.form label { display: flex; flex-direction: column; gap: 4px; font-size: 12px;
  color: var(--muted); }
.form label.wide { flex: 1 1 420px; }

/* ---------------------------------------------------------------- compare */
.stat { display: inline-block; margin-right: 22px; }
.stat b { display: block; font-size: 20px; font-family: var(--mono); }
.stat span { font-size: 11px; color: var(--muted); text-transform: uppercase;
  letter-spacing: .5px; }
.gained { color: var(--good); }
.lost { color: var(--bad); }
.flips { display: grid; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 8px; }
.flip { display: flex; gap: 8px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); padding: 6px; align-items: center; }
.flip img { width: 52px; height: 52px; object-fit: contain; background: #0c0e13;
  border-radius: 3px; flex: 0 0 52px; }
.flip .t { font-size: 11px; line-height: 1.4; min-width: 0; }
.flip .t div { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* ------------------------------------------------------------------ modal */
.modal { position: fixed; inset: 0; background: rgba(0,0,0,.6);
  display: flex; align-items: flex-start; justify-content: center; padding-top: 70px; z-index: 50; }
.modal-box { background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; width: min(520px, 92vw); padding: 14px; }
.modal-head { display: flex; align-items: center; margin-bottom: 10px; }
.modal-head b { flex: 1; }
#brandsearch { width: 100%; margin-bottom: 8px; }
.brandlist { list-style: none; margin: 0; padding: 0; max-height: 50vh; overflow-y: auto; }
.brandlist li { padding: 7px 9px; border-radius: var(--radius); cursor: pointer;
  display: flex; gap: 8px; align-items: center; }
.brandlist li:hover, .brandlist li.hot { background: var(--surface-2); }
.brandlist .slug { color: var(--dim); font-family: var(--mono); font-size: 11px; }

/* ------------------------------------------------------------------ zones */
.viewbar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 10px; }
.viewbar label { font-size: 12px; color: var(--muted); display: flex; align-items: center; gap: 5px; }
.viewbar select { max-width: 280px; }
.hint.inline { margin: 0; font-size: 11px; }
.check { cursor: pointer; user-select: none; }
button.sm { padding: 3px 8px; font-size: 12px; }

/* Brand names written on the photo. Heavy outline because a shelf photo is busy and a thin
   label over packaging is unreadable at any colour. */
.overlay text.zone-label {
  font: 600 15px system-ui, sans-serif;
  paint-order: stroke; stroke: rgba(0, 0, 0, .85); stroke-width: 4px; stroke-linejoin: round;
}

.zonebusy { padding: 8px 12px; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: var(--radius); font-size: 12px; color: var(--muted); margin-bottom: 10px; }

.zones { display: flex; flex-direction: column; gap: 8px; }
.zonecard {
  background: var(--surface); border: 1px solid var(--border);
  border-left: 4px solid var(--zone, var(--border));
  border-radius: var(--radius); padding: 8px 10px; cursor: pointer;
}
.zonecard:hover { border-color: var(--muted); border-left-color: var(--zone, var(--muted)); }
.zonecard.sel { background: var(--surface-2); border-color: var(--primary);
  border-left-color: var(--zone, var(--primary)); }
.zonehead { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; flex-wrap: wrap; }
.zonehead b { font-size: 12px; color: var(--muted); font-weight: 500; min-width: 74px; }
.zonehead .arrow { color: var(--dim); }

.chip { font-size: 12px; padding: 2px 8px; border-radius: 10px; border: 1px solid var(--border);
  white-space: nowrap; }
.chip.good { border-color: #2f5d3f; color: var(--good); }
.chip.dim { color: var(--dim); }
.chip.warn { border-color: #6b5320; color: var(--warn); }
.chip.brand { border-color: #2f5d3f; color: var(--good); }
.chip.unknown { border-color: #6b5320; color: var(--warn); }
.chip.product_unidentifiable { border-color: #2c4a7a; color: var(--primary); }
.chip.not_a_product, .chip.exclude { color: var(--dim); }

.thumbs { display: flex; gap: 5px; flex-wrap: wrap; align-items: center; }
.thumbs img { width: 56px; height: 62px; object-fit: contain; background: #0c0e13;
  border: 2px solid transparent; border-radius: 3px; cursor: pointer; }
.thumbs img:hover { border-color: var(--muted); }
.thumbs img.sel { border-color: var(--primary); }
/* THE THUMBNAILS ARE THE SELECTION SURFACE, so they have to look clickable and the picked ones
   have to be obvious at a glance across a card of forty. */
.thumbs img { cursor: pointer; }
.thumbs img:hover { border-color: var(--muted); }
.thumbs img.sel { box-shadow: 0 0 0 2px var(--primary); }
.zonepick { display: inline-flex; align-items: center; cursor: pointer; margin-right: 2px; }
.zonepick input { cursor: pointer; }
.zonecard.partial { border-color: var(--muted); box-shadow: inset 2px 0 0 var(--primary); }
.pickcount.hidden { display: none; }
button.more {
  font-size: 11px; padding: 2px 8px; align-self: center;
  background: var(--surface-2); border: 1px solid var(--border); color: var(--muted);
  border-radius: 10px; cursor: pointer;
}
button.more:hover { color: var(--text); border-color: var(--muted); }

/* The modifier table under the cards -- a paragraph of "shift-click does X" is read once and
   never again; four rows are scannable when you need one. */
table.keys { border-collapse: collapse; margin: 4px 0 10px; }
table.keys th {
  text-align: left; font-weight: 600; color: var(--text); white-space: nowrap;
  padding: 3px 12px 3px 0; vertical-align: top; font-size: 12px;
}
table.keys td { padding: 3px 0; vertical-align: top; }

.form .check { display: flex; align-items: center; gap: 6px; font-size: 13px; }
.form input.pct { width: 62px; }
.table td.scope { white-space: nowrap; font-size: 12px; }

/* `other brand` is a brand expectation the database cannot satisfy, so it is neither the green
   of a recorded brand nor the grey of a placeholder. */
.chip.other_brand, .card .kind.other_brand { border-color: #5c3a70; color: #b06ad6; }
.ratebar .ceiling b { color: var(--warn); }
.thumbs img.hot { border-color: #fff; }
.thumbs .more { font-size: 11px; color: var(--dim); font-family: var(--mono); }

/* ----------------------------------------------------------- facing menu */
/* Anchored at the click. Fixed rather than absolute so it is positioned against the viewport
   and cannot be clipped by the scrolling zone list it was opened from. */
.facingmenu {
  position: fixed; z-index: 60; min-width: 300px; max-width: 430px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; padding: 8px; box-shadow: 0 10px 34px rgba(0, 0, 0, .55);
}
.facingmenu .mhead { display: flex; gap: 9px; align-items: flex-start;
  padding-bottom: 8px; margin-bottom: 6px; border-bottom: 1px solid var(--border); }
.facingmenu .mhead img { width: 54px; height: 62px; object-fit: contain;
  background: #0c0e13; border-radius: 3px; flex: 0 0 54px; }
.facingmenu .mhead > div { flex: 1; min-width: 0; font-size: 12px; line-height: 1.6; }
.facingmenu .mhead > button { flex: 0 0 auto; }
.facingmenu .msug { font-size: 13px; }
.facingmenu .sml { font-size: 11px; }

/* Three scopes fit on a row at this width; when they do not, the row wraps rather than
   pushing `selected N` off the edge of the menu. */
.facingmenu .mrow { display: flex; align-items: center; gap: 6px; padding: 3px 0;
  flex-wrap: wrap; }
.facingmenu .mrow.subtle { opacity: .72; }
.facingmenu .mlabel { flex: 1 1 130px; min-width: 120px; font-size: 12px; color: var(--text); }
.facingmenu .mrow button { padding: 3px 9px; font-size: 12px; white-space: nowrap; }

/* ---------------------------------------------------------------- results */
/* The five buckets, and the two families they belong to. Colour carries the good/bad split so
   a run reads at a glance; the individual hues separate the three failures, which are different
   problems with different fixes. */
:root {
  /* OKABE-ITO, which is a palette chosen to stay separable under the common colour vision
     deficiencies. The obvious green/red pair is exactly the one to avoid here: the two hues
     doing the most work are "correct brand" and "wrong brand", and under deuteranopia or
     protanopia those are the two that collapse into each other.

     COLOUR IS NOT THE ONLY CUE. On the results overlay the three BAD verdicts are also hatched,
     so good and bad are told apart by texture with no colour perception at all -- see
     `#hatch-bad`. Hue then only has to separate the three failures from one another. */
  --tp: #009E73;   /* bluish green   — true positive, correct brand        */
  --tn: #56B4E9;   /* sky blue       — true negative, correctly no brand   */
  --fn: #E69F00;   /* orange         — false negative, missed a brand      */
  --fpb: #D55E00;  /* vermillion     — false positive brand, wrong brand   */
  --fpp: #CC79A7;  /* reddish purple — false positive, invented a brand    */
  --unscored: #6a7080;
}

.buckets { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 16px; }
.bucket {
  flex: 1 1 170px; background: var(--surface); border: 1px solid var(--border);
  border-top: 3px solid var(--k, var(--border));
  border-radius: var(--radius); padding: 10px 12px;
}
.bucket b { display: block; font-size: 24px; font-family: var(--mono); line-height: 1.2;
  color: var(--k, var(--text)); }
.bucket span { display: block; font-size: 11px; color: var(--muted); margin-top: 2px; }
.bucket em { font-style: normal; font-size: 10px; color: var(--dim); text-transform: uppercase;
  letter-spacing: .5px; }
.bucket.good em { color: var(--good); }
.bucket.bad em { color: var(--bad); }

.ratebar { display: flex; gap: 22px; flex-wrap: wrap; margin-bottom: 16px; font-size: 12px;
  color: var(--muted); }
.ratebar b { font-family: var(--mono); color: var(--text); font-size: 15px; display: block; }

.results-body { display: flex; gap: 16px; align-items: flex-start; }
.results-photos { flex: 0 0 300px; max-height: 70vh; overflow-y: auto; }
.results-photo { flex: 1; min-width: 0; }

.ptable { width: 100%; border-collapse: collapse; font-size: 12px; }
.ptable th, .ptable td { padding: 5px 6px; border-bottom: 1px solid var(--border);
  text-align: right; }
.ptable th:first-child, .ptable td:first-child { text-align: left; font-family: var(--mono); }
.ptable th { color: var(--muted); font-weight: 500; font-size: 10px; text-transform: uppercase; }
.ptable tbody tr { cursor: pointer; }
.ptable tbody tr:hover { background: var(--surface-2); }
.ptable tbody tr.active { background: var(--surface-2); outline: 1px solid var(--primary); }
.ptable .bad { color: var(--bad); }

.legend { display: flex; gap: 12px; flex-wrap: wrap; font-size: 11px; color: var(--muted);
  margin: 8px 0; }
.legend i { display: inline-block; width: 10px; height: 10px; border-radius: 2px;
  margin-right: 4px; vertical-align: -1px; }

.rfacings { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px; margin-top: 12px; }
.rcard { background: var(--surface); border: 1px solid var(--border);
  border-left: 4px solid var(--k, var(--border)); border-radius: var(--radius); padding: 6px; }
.rcard img { width: 100%; height: 92px; object-fit: contain; background: #0c0e13;
  border-radius: 3px; display: block; }
.rcard .rl { font-size: 11px; line-height: 1.45; margin-top: 4px; }
.rcard .rl .t { color: var(--muted); }

/* The count carries its denominator, and the group share sits beside it -- a bucket read
   against its own group is a rate that stands alone. */
.bucket b small { font-size: 13px; color: var(--dim); font-family: var(--mono); }
.bucket u { float: right; text-decoration: none; font-family: var(--mono); font-size: 15px;
  color: var(--k, var(--text)); margin-top: 4px; }
.bucket em { display: block; margin-top: 3px; }

.grouprow { display: flex; gap: 22px; flex-wrap: wrap; margin: -6px 0 14px; font-size: 12px;
  color: var(--muted); }
.grouprow b { font-family: var(--mono); color: var(--text); font-size: 15px; display: block; }

.legend small { color: var(--dim); font-family: var(--mono); }

/* Legend swatches match the overlay: a 30% shade of the verdict's colour, hatched for the three
   bad ones so the key is readable the same way the picture is -- by texture first, hue second. */
.legend i {
  width: 16px; height: 12px; border-radius: 2px; border: 1px solid var(--k);
  background: color-mix(in srgb, var(--k) 30%, transparent);
}
.legend i.hatched {
  background-image: repeating-linear-gradient(45deg,
    rgba(0, 0, 0, .55) 0 2px, transparent 2px 5px);
  background-color: color-mix(in srgb, var(--k) 30%, transparent);
}
.legend i.faint { border-style: dashed; opacity: .7; }

/* The photo under the results overlay, desaturated and darkened so the verdict shades read.
   Only the shaded overlay -- the labelling view wants the packaging in full colour, because
   there you are identifying products rather than judging outcomes. */
.overlay.shaded.muted img { filter: saturate(0.18) brightness(0.62); }
.overlay.shaded img { transition: filter .15s; }

/* A brand the PIPELINE detected on a facing you have not labelled yet. Italic and dimmed so a
   suggestion can never be mistaken for a decision you made -- without it the overlay would look
   as though the whole photo were already done. */
.overlay text.zone-label.suggested {
  font-style: italic; font-weight: 500; fill-opacity: .82;
  stroke-opacity: .7;
}
