1import{j as e}from"./motion-YM8fB_5Z.js";import{r as l}from"./sentry-otjh_W8X.js";import{b as Fa,u as Ba}from"./react-OFElpF2u.js";import{L as Da}from"./lenswork-layout-CPUXOGOK.js";import{M as C}from"./material-icon-4IKyhXPg.js";import{e1 as Wa,ej as Ua,aq as Ga,g as Va,cI as Ne,ek as Qt,a5 as Kt,a8 as Ha,ae as $e,el as Ja,ac as _a,em as Ya,ad as Qa,en as Ka,eo as Xa,ep as Xt,eq as Za,cV as ot,er as es}from"./index-BoOYcZhe.js";import{l as ts}from"./google-maps-loader-ALtPb3gC.js";import{M as as,T as ss,a as Zt,b as ea,u as ns,L as oa}from"./maps-B9f5yxAp.js";import{t as g}from"./ui-BM2pkkqU.js";import{g as os,C as is}from"./event-categories-BOed9pud.js";import{t as ta}from"./format-time-CDlzm80L.js";import"./pdf-BEE2WjVn.js";import"./supabase-BTsOnGLq.js";import"./charts-DnWBDTZK.js";import"./i18n-BRS0AnGA.js";const it={photographer:"#2563EB",parking:"#9333EA",bathroom:"#0891B2",water:"#0EA5E9",medical:"#DC2626",custom:"#6B7280"},rs={photographer:'<path d="M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z"/><circle cx="12" cy="13" r="3.5"/>',parking:'<rect width="18" height="18" x="3" y="3" rx="2" ry="2"/><path d="M9 17V7h4a3 3 0 0 1 0 6H9"/>',bathroom:'<circle cx="8" cy="4" r="2"/><path d="M6 9h4l1 6h-1.5v6h-3v-6H5z"/><circle cx="16" cy="4" r="2"/><path d="M14 9h4l-1 7h-1v5h-2v-5h-1z"/>',water:'<path d="M12 22a7 7 0 0 0 7-7c0-2-1-3.9-3-5.5s-3.5-4-4-6.5c-.5 2.5-2 4.9-4 6.5C6 11.1 5 13 5 15a7 7 0 0 0 7 7z"/>',medical:'<path d="M10 3h4v7h7v4h-7v7h-4v-7H3v-4h7z"/>',custom:'<path d="M20 10c0 7-8 12-8 12s-8-5-8-12a8 8 0 0 1 16 0z"/><circle cx="12" cy="10" r="3"/>'},aa=[{value:"photographer",label:"Photographer"},{value:"parking",label:"Parking"},{value:"bathroom",label:"Bathroom"},{value:"water",label:"Water"},{value:"medical",label:"Medical"},{value:"custom",label:"Custom"}];function ls(o){const p=it[o],u=rs[o],N=`<svg xmlns="http://www.w3.org/2000/svg" width="32" height="44" viewBox="0 0 32 44"> 2 <path d="M16 0C9.373 0 4 5.373 4 12c0 8.627 12 32 12 32S28 20.627 28 12C28 5.373 22.627 0 16 0z" fill="${p}" stroke="#fff" stroke-width="2"/> 3 <svg x="8" y="5" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round">${u}</svg> 4 </svg>`;return"data:image/svg+xml;charset=UTF-8,"+encodeURIComponent(N)}function ds({pins:o,onPinsChange:p,coordinates:u,address:N,heightClass:R="h-[400px]"}){const[x,v]=l.useState("loading"),[T,I]=l.useState("photographer"),A=l.useRef(null),S=l.useRef(null),K=l.useRef([]);l.useEffect(()=>{let f=!1;return(async()=>{try{const b=await Wa();if(!b){f||v("error");return}await ts(b),f||v("ready")}catch{f||v("error")}})(),()=>{f=!0}},[]),l.useEffect(()=>{if(x!=="ready"||!A.current||S.current)return;const f=window.google;let b,y;u?(b={lat:u[0],lng:u[1]},y=15):(b={lat:39.5,lng:-98.35},y=4);const P=new f.maps.Map(A.current,{center:b,zoom:y,mapTypeId:"roadmap",streetViewControl:!1,mapTypeControl:!1,fullscreenControl:!1,draggableCursor:"crosshair",draggingCursor:"crosshair"});S.current=P,!u&&N&&N.trim().length>=4&&new f.maps.Geocoder().geocode({address:N.trim()},(q,F)=>{if(F==="OK"&&(q!=null&&q[0])){const M=q[0].geometry.location,V=typeof M.lat=="function"?M.lat():M.lat,Y=typeof M.lng=="function"?M.lng():M.lng;P.setCenter({lat:V,lng:Y}),P.setZoom(15)}})},[x]),l.useEffect(()=>{if(!S.current||x!=="ready")return;const f=window.google;u?(S.current.setCenter({lat:u[0],lng:u[1]}),S.current.setZoom(15)):N&&N.trim().length>=4&&new f.maps.Geocoder().geocode({address:N.trim()},(y,P)=>{var $,q;if(P==="OK"&&(y!=null&&y[0])){const F=y[0].geometry.location,M=typeof F.lat=="function"?F.lat():F.lat,V=typeof F.lng=="function"?F.lng():F.lng;($=S.current)==null||$.setCenter({lat:M,lng:V}),(q=S.current)==null||q.setZoom(15)}})},[u,N,x]);const W=l.useRef(T);l.useEffect(()=>{W.current=T},[T]);const _=l.useRef(o),G=l.useRef(p);l.useEffect(()=>{_.current=o},[o]),l.useEffect(()=>{G.current=p},[p]),l.useEffect(()=>{if(!S.current||x!=="ready")return;const f=window.google,b=S.current.addListener("click",y=>{var Y;const P=typeof y.latLng.lat=="function"?y.latLng.lat():y.latLng.lat,$=typeof y.latLng.lng=="function"?y.latLng.lng():y.latLng.lng,q=W.current,F=((Y=aa.find(ae=>ae.value===q))==null?void 0:Y.label)??q,M=_.current.filter(ae=>ae.type===q).length+1,V={label:`${F} ${M}`,type:q,lat:P,lng:$};G.current([..._.current,V])});return()=>{f.maps.event.removeListener(b)}},[x]),l.useEffect(()=>
4{if(!S.current||x!=="ready")return;const f=window.google;K.current.forEach(b=>b.setMap(null)),K.current=[],o.forEach((b,y)=>{if(typeof b.lat!="number"||typeof b.lng!="number")return;const P=new f.maps.Marker({position:{lat:b.lat,lng:b.lng},map:S.current,title:b.label,draggable:!0,icon:{url:ls(b.type),scaledSize:new f.maps.Size(32,44),anchor:new f.maps.Point(16,44)}});P.addListener("dragend",$=>{const q=typeof $.latLng.lat=="function"?$.latLng.lat():$.latLng.lat,F=typeof $.latLng.lng=="function"?$.latLng.lng():$.latLng.lng;G.current(_.current.map((M,V)=>V===y?{...M,lat:q,lng:F}:M))}),K.current.push(P)})},[o,x]);const ke=l.useCallback(f=>{p(o.filter((b,y)=>y!==f))},[o,p]),Se=l.useCallback((f,b)=>{p(o.map((y,P)=>P===f?{...y,label:b}:y))},[o,p]);return e.jsxs("div",{className:"space-y-3",children:[e.jsxs("div",{className:"flex flex-wrap gap-2 rounded-lg border border-slate-200 bg-slate-50 p-2",children:[e.jsx("span",{className:"text-xs font-semibold text-slate-600 self-center mr-1",children:"Drop:"}),aa.map(({value:f,label:b})=>{const y=T===f;return e.jsxs("button",{type:"button",onClick:()=>I(f),className:`flex items-center gap-1.5 text-xs rounded-md px-2.5 py-1.5 font-medium transition-colors ${y?"bg-slate-900 text-white shadow-sm":"bg-white text-slate-700 border border-slate-200 hover:bg-slate-50"}`,title:`Drop ${b.toLowerCase()} pin`,children:[e.jsx("span",{className:"inline-block h-3 w-3 rounded-full ring-1 ring-white/40",style:{background:it[f]}}),b]},f)})]}),e.jsxs("div",{className:`relative ${R} w-full overflow-hidden rounded-xl border border-slate-200`,style:{cursor:x==="ready"?"crosshair":"default"},children:[e.jsx("div",{ref:A,className:"h-full w-full"}),x==="loading"&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-slate-100",children:e.jsx("span",{className:"text-sm text-slate-500",children:"Loading mapâ¦"})}),x==="error"&&e.jsx("div",{className:"absolute inset-0 flex items-center justify-center bg-slate-100 p-6",children:e.jsx("p",{className:"text-sm text-center text-slate-600 max-w-xs",children:"Google Map couldn't load â confirm the Maps JavaScript API is enabled on your key."})})]}),o.length>0&&e.jsxs("div",{className:"rounded-lg border border-slate-200 bg-white p-3",children:[e.jsxs("div",{className:"text-xs font-semibold text-slate-700 mb-2",children:["Pins on map (",o.length,")"]}),e.jsx("ul",{className:"space-y-1.5",children:o.map((f,b)=>e.jsxs("li",{className:"flex items-center gap-2 text-xs",children:[e.jsx("span",{className:"inline-block h-3 w-3 rounded-full shrink-0",style:{background:it[f.type]}}),e.jsx("input",{type:"text",value:f.label,onChange:y=>Se(b,y.target.value),className:"flex-1 rounded border border-slate-200 px-2 py-1 text-xs"}),typeof f.lat=="number"&&typeof f.lng=="number"&&e.jsxs("span",{className:"text-slate-400 text-[10px]",children:[f.lat.toFixed(4),", ",f.lng.toFixed(4)]}),e.jsx("button",{type:"button",onClick:()=>ke(b),className:"text-red-500 hover:text-red-700 text-[10px] font-medium",children:"â"})]},b))})]}),e.jsx("p",{className:"text-xs text-slate-500",children:"Click anywhere on the map to drop a pin of the selected type. Scroll to zoom. Drag to pan. Pin data saves with your logistics."})]})}const cs=[{id:"mercedes-benz-atlanta",name:"Mercedes-Benz Stadium",city:"Atlanta, GA",country:"USA",lat:33.7553,lng:-84.4006,spots:[{catalogId:"transit-drop-off",lat:33.7558,lng:-84.4112,nameOverride:"MARTA Vine City station exit"},{catalogId:"fan-fest-plaza",lat:33.7616,lng:-84.3934,nameOverride:"Centennial Olympic Park north entry"},{catalogId:"stadium-perimeter",lat:33.7544,lng:-84.406,nameOverride:"Northside Drive sidewalk (south of MLK Jr Dr)"},{catalogId:"main-gate-approach",lat:33.761,lng:-84.3955,nameOverride:"Andrew Young Intl Blvd @ Centennial Olympic Park Dr"},{catalogId:"stadium-perimeter",lat:33.7589,lng:-84.4012,nameOverride:"The Home Depot Backyard approach (Ivan Allen Blvd)"}]},{id:"gillette-foxborough",name:"Gillette Stadium",city:"Foxborough, MA (Boston)",country:"USA",lat:42.0909,lng:-71.2643,spots:[{catalogId:"fan-fest-plaza",lat:42.0938,lng:-71.2625,nameOverride:"Patriot Place south entrance (Route 1 sidewalk)"},{catalogId:"main-gate-approach",lat:42.0955,lng:-71.2627,nameOverride:"Washington Street @ Patriot Pl crosswalk"},{catalogId:"stadium-perimeter",lat:42.098,lng:-71.262,nameOverride:"Route 1 / Washington St sidewalk (north)"},{catalogId:"public-plaza",lat:42.093,lng:-71.2655,nameOverride:"Patriot Place plaza near CBS Scene"}]},{id:"att-arlington",name:"AT&T Stadium",city:"Arlington, TX (Dallas)",country:"USA",lat:32.7473,lng:-97.0945,spots:[{catalogId:"main-gate-approach",lat:32.7499,lng:-97.0936,nameOverride:"Randol Mill Rd @ AT&T Way crosswalk"},{catalogId:"fan-fest-plaza",lat:32.751,lng:-97.083,nameOverride:"Texas Live! plaza entry"},{catalogId:"stadium-perimeter",lat:32.745,lng:-97.0905,nameOverride:"E Division St sidewalk"},{catalogId:"stadium-perimeter",lat:32.7445,lng:-97.0945,nameOverride:"AT&T Way pedestrian approach (south)"}]},{id:"nrg-houston",name:"NRG Stadium",city:"Houston, TX",country:"USA",lat:29.6847,lng:-95.4107,spots:[{catalogId:"transit-drop-off",lat:29.681,lng:-95.408,nameOverride:"Stadium METRORail station drop-off"},{catalogId:"main-gate-approach",lat:29.685,lng:-95.4145,nameOverride:"Kirby Drive @ Murworth Dr crosswalk"},{catalogId:"stadium-perimeter",lat:29.6905,lng:-95.4108,nameOverride:"Fannin St sidewalk near NRG Park north gate"},{catalogId:"stadium-perimeter",lat:29.6814,lng:-95.412,nameOverride:"Holly Hall St public sidewalk"}]},{id:"arrowhead-kc",name:"Arrowhead Stadium",city:"Kansas City, MO",country:"USA",lat:39.0489,lng:-94.4839,spots:[{catalogId:"main-gate-approach",lat:39.0495,lng:-94.4795,nameOverride:"Blue Ridge Cutoff @ Stadium Dr pedestrian approach"},{catalogId:"stadium-perimeter",lat:39.053,lng:-94.4825,nameOverride:"Raytown Rd sidewalk (Royals lot edge)"},{catalogId:"stadium-perimeter",lat:39.0455,lng:-94.4835,nameOverride:"I-70 frontage (south of stadium)"},{catalogId:"main-gate-approach",lat:39.051,lng:-94.4865,nameOverride:"Sports Complex Dr public sidewalk"}]},{id:"sofi-inglewood",name:"SoFi Stadium",city:"Inglewood, CA (Los Angeles)",country:"USA",lat:33.9534,lng:-118.3387,spots:[{catalogId:"fan-fest-plaza",lat:33.9514,lng:-118.338,nameOverride:"Hollywood Park plaza / YouTube Theater approach"},{catalogId:"main-gate-approach",lat:33.946,lng:-118.339,nameOverride:"S Prairie Ave sidewalk @ W Century Blvd"},{catalogId:"stadium-perimeter",lat:33.9555,lng:-118.343,nameOverride:"Pincay Drive pedestrian approach"},{catalogId:"stadium-perimeter",lat:33.956,lng:-118.3355,nameOverride:"Kareem Court public-side walk"},{catalogId:"stadium-perimeter",lat:33.9445,lng:-118.3502,nameOverride:"S La Brea Ave @ W 102nd St"}]},{id:"hard-rock-miami",name:"Hard Rock Stadium",city:"Miami Gardens, FL",country:"USA",lat:25.958,lng:-80.2389,spots:[{catalogId:"main-gate-approach",lat:25.961,lng:-80.2385,nameOverride:"NW 199th St @ Don Shula Dr crosswalk"},{catalogId:"stadium-perimeter",lat:25.958,lng:-80.2435,nameOverride:"NW 27th Ave sidewalk (east of stadium)"},{catalogId:"stadium-perimeter",lat:25.956,lng:-80.24,nameOverride:"Dan Marino Blvd public-street crosswalk"},{catalogId:"main-gate-approach",lat:25.9645,lng:-80.241,nameOverride:"NW 203rd St / Honey Hill Dr approach"}]},{id:"metlife-east-rutherford",name:"MetLife Stadium",city:"East Rutherford, NJ (New York)",country:"USA",lat:40.8128,lng:-74.0742,spots:[{catalogId:"transit-drop-off",lat:40.8137,lng:-74.07,nameOverride:"Meadowlands Sports Complex NJ Transit station"},{catalogId:"main-gate-approach",lat:40.812,lng:-74.0712,nameOverride:"Sports Complex Dr pedestrian approach"},{catalogId:"stadium-perimeter",lat:40.8158,lng:-74.0735,nameOverride:"Route 120 sidewalk (north of stadium)"},{catalogId:"stadium-perimeter",lat:40.8118,lng:-74.0775,nameOverride:"American Dream / stadium-shared parking lot edge"}]},{id:"lincoln-financial-philly",name:"Lincoln Financial Field",city:"Philadelphia, PA",country:"USA",lat:39.9008,lng:-75.1675,spots:[{catalogId:"transit-drop-off",lat:39.907,lng:-75.166,nameOverride:"NRG Station (SEPTA Broad Street line)"},{catalogId:"main-gate-approach",lat:39.9035,lng:-75.168,nameOverride:"Pattison Ave sidewalk (north of stadium)"},{catalogId:"stadium-perimeter",lat:39.9038,lng:-75.1633,nameOverride:"S 11th St sidewalk @ Pattison"},{catalogId:"public-plaza",lat:39.9019,lng:-75.1719,nameOverride:"Wells Fargo Center plaza approach"}]},{id:"levis-santa-clara",name:"Levi's Stadium",city:"Santa Clara, CA (San Francisco)",country:"USA",lat:37.4032,lng:-121.9698,spots:[{catalogId:"transit-drop-off",lat:37.4068,lng:-121.9755,nameOverride:"Great America VTA light-rail station"},{catalogId:"main-gate-approach",lat:37.406,lng:-121.972,nameOverride:"Tasman Dr @ Centennial Blvd crosswalk"},{catalogId:"stadium-perimeter",lat:37.406,lng:-121.969,nameOverride:"Stars and Stripes Drive sidewalk"},{catalogId:"fan-fest-plaza",lat:37.4028,lng:-121.976,nameOverride:"Convention Center plaza approach"}]},{id:"lumen-seattle",name:"Lumen Field",city:"Seattle, WA",country:"USA",lat:47.5952,lng:-122.3316,spots:[{catalogId:"transit-drop-off",lat:47.5984,lng:-122.3281,nameOverride:"International District / Chinatown light-rail station"},{catalogId:"fan-fest-plaza",lat:47.6005,lng:-122.3327,nameOverride:"Occidental Park pedestrian plaza"},{catalogId:"stadium-perimeter",lat:47.5942,lng:-122.3315,nameOverride:"S Royal Brougham Way sidewalk"},{catalogId:"main-gate-approach",lat:47.599,lng:-122.3344,nameOverride:"1st Ave S @ S King St"}]},{id:"bmo-toronto",name:"BMO Field",city:"Toronto, ON",country:"Canada",lat:43.6332,lng:-79.4185,spots:[{catalogId:"transit-drop-off",lat:43.6358,lng:-79.4145,nameOverride:"Exhibition GO station drop-off"},{catalogId:"main-gate-approach",lat:43.6354,lng:-79.4123,nameOverride:"Princes' Gates @ Lake Shore Blvd"},{catalogId:"public-plaza",lat:43.6347,lng:-79.4197,nameOverride:"Bandshell Park public plaza"},{catalogId:"stadium-perimeter",lat:43.632,lng:-79.4145,nameOverride:"Lake Shore Blvd W sidew
4alk (east)"}]},{id:"bc-place-vancouver",name:"BC Place",city:"Vancouver, BC",country:"Canada",lat:49.2768,lng:-123.1119,spots:[{catalogId:"transit-drop-off",lat:49.279,lng:-123.1095,nameOverride:"Stadium-Chinatown SkyTrain station exit"},{catalogId:"public-plaza",lat:49.2755,lng:-123.111,nameOverride:"Terry Fox Plaza"},{catalogId:"main-gate-approach",lat:49.277,lng:-123.1075,nameOverride:"Pacific Blvd sidewalk @ Beatty St"},{catalogId:"fan-fest-plaza",lat:49.282,lng:-123.118,nameOverride:"Robson Square pedestrian approach"}]},{id:"azteca-mexico-city",name:"Estadio Azteca",city:"Mexico City",country:"Mexico",lat:19.3029,lng:-99.1505,spots:[{catalogId:"transit-drop-off",lat:19.3062,lng:-99.1488,nameOverride:"Estadio Azteca light-rail (Tren Ligero) station"},{catalogId:"main-gate-approach",lat:19.305,lng:-99.1525,nameOverride:"Calz de Tlalpan @ Calz del Hueso"},{catalogId:"main-gate-approach",lat:19.3018,lng:-99.149,nameOverride:"Av Estadio Azteca pedestrian approach"},{catalogId:"stadium-perimeter",lat:19.307,lng:-99.1532,nameOverride:"Periférico Sur frontage sidewalk"}]},{id:"akron-guadalajara",name:"Estadio Akron",city:"Guadalajara",country:"Mexico",lat:20.6815,lng:-103.4625,spots:[{catalogId:"main-gate-approach",lat:20.681,lng:-103.4592,nameOverride:"Av Vallarta @ Periférico Sur pedestrian crossing"},{catalogId:"fan-fest-plaza",lat:20.711,lng:-103.4145,nameOverride:"Centro Comercial Andares plaza approach"},{catalogId:"stadium-perimeter",lat:20.6845,lng:-103.4615,nameOverride:"Av Independencia pedestrian sidewalk"},{catalogId:"stadium-perimeter",lat:20.679,lng:-103.4645,nameOverride:"Periférico Manuel Gómez MorÃn frontage"}]},{id:"bbva-monterrey",name:"Estadio BBVA",city:"Monterrey",country:"Mexico",lat:25.6691,lng:-100.2444,spots:[{catalogId:"main-gate-approach",lat:25.6705,lng:-100.2432,nameOverride:"Av Pablo Livas pedestrian sidewalk"},{catalogId:"public-plaza",lat:25.672,lng:-100.2375,nameOverride:"Parque Fundidora pedestrian gateway (east of stadium)"},{catalogId:"stadium-perimeter",lat:25.6664,lng:-100.247,nameOverride:"Av Eugenio Garza Sada frontage"},{catalogId:"main-gate-approach",lat:25.672,lng:-100.2415,nameOverride:"Av Diego DÃaz de Berlanga sidewalk"}]}];function ms(o,p,u=1){if(typeof o!="number"||typeof p!="number")return null;let N=null,R=1/0;for(const x of cs){const v=us(o,p,x.lat,x.lng);v<R&&v<=u&&(N=x,R=v)}return N}function us(o,p,u,N){const x=A=>A*Math.PI/180,v=x(u-o),T=x(N-p),I=Math.sin(v/2)**2+Math.cos(x(o))*Math.cos(x(u))*Math.sin(T/2)**2;return 2*3958.8*Math.asin(Math.sqrt(I))}const ps=[{id:"finish-line",name:"Finish Line",role:"lead",description:"Position 8â15 ft past the finish tape on the photographer side of the chute. Low angle is best â kneel or shoot from a stool â so finishers are framed against the sky, not the crowd behind them. Capture every finisher individually if possible; for high-volume events focus on the moment a runner breaks the tape and the emotional reaction in the 3â5 seconds after.",expectedPhotoCount:"5,000â7,000",defaultTimeWindow:"Race start â 30 min through 1 hr after the last finisher",shotStyle:"emotional",shotList:["Tape break / clock-in-frame","Arms-up celebration","Medal hand-off","Family reunion in the corral","Group photo with finishers' bibs visible"],equipmentRequired:["70â200mm f/2.8","24â70mm f/2.8 as a second body","Knee pad or stool for sustained low-angle","Extra batteries (3+) + memory cards"],notes:"DO NOT block the runners' path. Coordinate with the race director on which side of the chute is the photographer side.",nameEs:"LÃnea de meta",descriptionEs:"Colócate de 2.5 a 4.5 m (8â15 pies) después de la cinta de meta, del lado del canal asignado a fotógrafos. Lo mejor es disparar desde un ángulo bajo â de rodillas o desde un banquito â para que quienes cruzan queden encuadrados contra el cielo y no contra el público. Captura a cada corredor en lo individual cuando se pueda; en eventos masivos enfócate en el momento exacto en que rompen la cinta y en la reacción emotiva de los 3â5 segundos siguientes.",shotStyleEs:"emotivo",shotListEs:["Cruce de la cinta / reloj de meta en el cuadro","Celebración con los brazos arriba","Entrega de medalla","Reencuentro con la fam
4ilia en el corral","Foto grupal con dorsales visibles"],equipmentRequiredEs:["70â200mm f/2.8","24â70mm f/2.8 en un segundo cuerpo","Rodillera o banquito para sostener el ángulo bajo","BaterÃas de repuesto (3+) y tarjetas de memoria"],notesEs:"NO obstruyas la trayectoria de los corredores. Coordina con el director de carrera para confirmar de qué lado del canal de meta deben colocarse los fotógrafos."},{id:"start-line",name:"Start Line",role:"second",description:"Wide-angle, energy-and-anticipation coverage. Shoot from inside the corral 10 minutes before gun time (anthem, stretching, nervous smiles), then move to the side as the gun fires for the wave-release shot. Stay safely off the running line.",expectedPhotoCount:"1,500â3,000",defaultTimeWindow:"Race start â 45 min through wave 3 release",shotStyle:"wide",shotList:["Wide crowd-density shot showing wave size","National anthem moment","Runners at the start line awaiting the gun","Wave release with the front pack visible","Spectators cheering as the wave passes"],equipmentRequired:["16â35mm wide-angle","24â70mm f/2.8","Extra batteries"],nameEs:"LÃnea de salida",descriptionEs:"Cobertura amplia y de anticipación. Dispara desde dentro del corral 10 minutos antes del banderazo (himno, calentamientos, sonrisas nerviosas), y muévete a un costado al sonar la pistola para tomar la salida de la oleada. Mantente fuera de la lÃnea de carrera por seguridad.",shotStyleEs:"amplio",shotListEs:["Toma amplia que muestre la densidad de la oleada","Momento del himno nacional","Corredores en la lÃnea de salida esperando el banderazo","Salida de la oleada con el pelotón de cabeza visible","Espectadores echándole porras al pasar la oleada"],equipmentRequiredEs:["Gran angular 16â35mm","24â70mm f/2.8","BaterÃas de repuesto"]},{id:"mile-marker",name:"Mile Marker",role:"course",description:"On-course coverage at a single mile marker. Pre-walk the spot the day before â pick a sight-line that captures runners against a clean background (not parked cars). Telephoto compression makes the field look denser; mix in side-on shots for bib visibility.",expectedPhotoCount:"3,000â5,000",defaultTimeWindow:"Front pack ETA â 15 min through final cutoff at this mile",shotStyle:"action",shotList:["Front-pack lead runners with bib + clock visible","Mid-pack action with race-day faces","Walkers / back-of-pack finishers (most under-photographed)","Course details (mile sign, aid station, marshals)"],equipmentRequired:["70â200mm f/2.8","100â400mm telephoto","Lens cleaning kit"],notes:"Rename to the actual mile (e.g. 'Mile 4 turnaround') once you've picked a spot.",nameEs:"Marca de milla / kilómetro",descriptionEs:"Cobertura en ruta sobre una sola marca de milla o kilómetro. Recorre el lugar el dÃa anterior â elige una lÃnea de tiro que encuadre a los corredores contra un fondo limpio (no autos estacionados). La compresión del teleobjetivo hace que el pelotón se vea más denso; combina con tomas de costado para que se vean los dorsales.",shotStyleEs:"acción",shotListEs:["LÃderes del pelotón con dorsal y reloj visibles","Acción del pelotón medio con expresiones de carrera","Caminantes / cierre del pelotón (los menos fotografiados)","Detalles del recorrido (señal de la milla, avituallamiento, banderilleros)"],equipmentRequiredEs:["70â200mm f/2.8","Teleobjetivo 100â400mm","Kit de limpieza de lentes"],notesEs:"Renómbralo a la milla o kilómetro real (p. ej. 'Vuelta en milla 4') una vez que hayas elegido el punto."},{id:"water-station",name:"Water Station",role:"course",description:"Storytelling shots at a hydration / aid station. Volunteers handing cups, runners chugging, the chaos of the cup pile underfoot. Stay on the side of the road photographers are allowed on â never enter the runner line.",expectedPhotoCount:"1,500â2,500",defaultTimeWindow:"Front pack ETA â 10 min through back-of-pack passing",shotStyle:"candid",shotList:["Volunteer handing a cup to a runner","Runner drinking on the move","Runner dumping water over their head","Wide of the table + volunteers + cup pile"],equipmentRequired:["24â70mm f/2.8","70â200mm f/2.8"],nameEs:"Estación de hidratación",descriptionEs:"Tomas narrativas en una estación de hidratación o avituallamiento. Voluntarios entregando vasos, corredores bebiendo al paso, el caos de los vasos amontonados en el piso. Mantente del lado de la calle donde se permiten fotógrafos â nunca cruces la lÃnea de los corredores.",shotStyleEs:"espontáneo",shotListEs:["Voluntario entregando un vaso a un corredor","Corredor bebiendo en movimiento","Corredor echándose agua en la cabeza","Toma amplia de la mesa, los voluntarios y los vasos en el piso"],equipmentRequiredEs:["24â70mm f/2.8","70â200mm f/2.8"]},{id:"awards-tent",name:"Awards / Ceremony",role:"course",description:"Podium coverage post-race. Mix tight shots of individual awardees holding their medal/trophy with wider three-up podium shots. Shoot from a low angle so the awardees look up to the camera â flatters everyone.",expectedPhotoCount:"300â600",defaultTimeWindow:"Ceremony start through 15 min after the final age group",shotStyle:"portrait",shotList:["Individual winner with medal / trophy raised","Three-up podium with all three places","Age-group group photos (kids, masters, etc.)","Race director handshake / hand-off"],equipmentRequired:["24â70mm f/2.8","70â200mm f/2.8","Speedlight (covered venues)"],nameEs:"Premiación / Ceremonia",descriptionEs:"Cobertura del podio al terminar la carrera. Combina tomas cerradas de cada premiado sosteniendo su medalla o trofeo con tomas más abiertas de los tres lugares juntos. Dispara desde ángulo bajo para que los premiados queden de frente a la cámara â favorece a todos.",shotStyleEs:"retrato",shotListEs:["Ganador individual levantando medalla o trofeo","Podio completo con los tres lugares","Fotos grupales por categorÃa de edad (infantil, máster, etc.)","Apretón de manos / entrega del director de carrera"],equipmentRequiredEs:["24â70mm f/2.8","70â200mm f/2.8","Flash de zapata (Speedlight) en venues techados"]},{id:"course-roamer",name:"Course Roamer",role:"roamer",description:"Fill gaps on the course not covered by fixed mile-marker positions. Move every 20â30 min â don't anchor. Carry minimal gear so you can walk/bike between spots. Listen to the lead photographer on coverage gaps via radio or group chat.",expectedPhotoCount:"2,000â3,500",defaultTimeWindow:"Race start through back-of-pack passing the half-mark",shotStyle:"candid",shotList:["Unscripted moments between mile markers","Spectator cheering sections","Pace-group interactions","Race signs / homemade posters"],equipmentRequired:["24â70mm f/2.8","70â200mm f/2.8","Comfortable shoes"],nameEs:"Fotógrafo móvil del recorrido",descriptionEs:"Cubre los huecos del recorrido que las posiciones fijas no alcanzan. Cámbiate de punto cada 20â30 minutos â no te ancles. Carga lo mÃnimo para poder caminar o ir en bicicleta entre puntos. Escucha al fotógrafo lÃder por radio o chat grupal para saber dónde falta cobertura.",shotStyleEs:"espontáneo",shotListEs:["Momentos no planeados entre mar
4cas de milla","Tribunas de espectadores echando porras","Interacciones dentro de los grupos de paso","Letreros y carteles hechos a mano"],equipmentRequiredEs:["24â70mm f/2.8","70â200mm f/2.8","Calzado cómodo"]},{id:"main-court",name:"Main Court / Field",role:"lead",description:"Court-side or field-side at the championship / main bracket game. Find the photographer well â never enter the playing surface. Anticipate plays one beat ahead of where the ball is.",expectedPhotoCount:"2,500â4,000",defaultTimeWindow:"Warm-ups through final whistle + trophy presentation",shotStyle:"action",shotList:["Game-winning moment / final whistle","Goal / score celebration","Tight player action (hands on ball, mid-air, etc.)","Coach / bench reaction","Trophy presentation"],equipmentRequired:["300mm or 400mm f/2.8 for field sports","70â200mm f/2.8 for court sports","Monopod"],notes:"STAY OUT of players' sight-lines and the playing area at all times.",nameEs:"Cancha / Campo principal",descriptionEs:"Al borde de la cancha o del campo en el partido del cuadro principal o la final. Busca el pozo o área asignada a fotógrafos â nunca pises la superficie de juego. Anticipa la jugada un tiempo antes de donde está la pelota.",shotStyleEs:"acción",shotListEs:["Jugada decisiva / silbatazo final","Celebración del gol o anotación","Acción cerrada del jugador (manos en el balón, en el aire, etc.)","Reacción del entrenador o del banquillo","Entrega del trofeo"],equipmentRequiredEs:["300mm o 400mm f/2.8 para deportes de campo","70â200mm f/2.8 para deportes de cancha","Monopié"],notesEs:"MANTENTE FUERA de la lÃnea de visión de los jugadores y del área de juego en todo momento."},{id:"team-bench",name:"Team Bench / Sideline",role:"second",description:"Emotional / human side of the game. Coach calling plays, bench reactions, huddles, substitutions. Tight portrait coverage that contextualizes the action shots from the main-court photographer.",expectedPhotoCount:"1,000â2,000",defaultTimeWindow:"First whistle through final whistle",shotStyle:"portrait",shotList:["Coach in the moment of a critical call","Bench eruption after a big play","Player walking off after a sub","Team huddle at a timeout"],equipmentRequired:["70â200mm f/2.8","24â70mm f/2.8"],nameEs:"Banquillo / Banda",descriptionEs:"El lado emotivo y humano del partido. El entrenador marcando jugadas, reacciones del banquillo, cÃrculos de equipo, cambios. Cobertura tipo retrato cercana que da contexto a las tomas de acción del fotógrafo principal de cancha.",shotStyleEs:"retrato",shotListEs:["Entrenador en el instante de una decisión clave","Banquillo estallando tras una jugada grande","Jugador saliendo tras un cambio","CÃrculo del equipo en el tiempo fuera"],equipmentRequiredEs:["70â200mm f/2.8","24â70mm f/2.8"]},{id:"warm-ups",name:"Warm-Ups",role:"course",description:"Pre-game coverage. Teams stretching, drills, jersey close-ups, the national anthem. Often the best portrait opportunities of the day â calm, controlled lighting, players relaxed.",expectedPhotoCount:"500â1,200",defaultTimeWindow:"Doors open through opening whistle",shotStyle:"portrait",shotList:["Player portraits during stretching","Tight jersey / number shots","National anthem moment","Team intros / starting lineup walk-out"],equipmentRequired:["70â200mm f/2.8","24â70mm f/2.8"],nameEs:"Calentamiento",descriptionEs:"Cobertura previa al partido. Equipos estirando, ejercicios, planos cerrados de las playeras, el himno nacional. Suelen ser los mejores momentos del dÃa para hacer retratos â luz tranquila y controlada, jugadores relajados.",shotStyleEs:"retrato",shotListEs:["Retratos de jugadores durante el estiramiento","Planos cerrados de playera y número","Momento del himno nacional","Presentación / salida de la alineación titular"],equipmentRequiredEs:["70â200mm f/2.8","24â70mm f/2.8"]},{id:"trophy-ceremony",name:"Trophy Ceremony",role:"course",description:"Post-game ceremony. Position so the winning team's reactions face the camera â coordinate with the lead photographer on which side that is. Mix tight individual hold-the-trophy shots with the wide team-photo-with-trophy.",expectedPhotoCount:"300â600",defaultTimeWindow:"Final whistle + 5 min through the team locker-room walk",shotStyle:"emotional",shotList:["Tro
4phy lift moment","Captain / MVP individual portrait with trophy","Team gathered around the trophy","Coach + team-owner handshake"],equipmentRequired:["24â70mm f/2.8","70â200mm f/2.8"],nameEs:"Ceremonia del trofeo",descriptionEs:"Ceremonia posterior al partido. Colócate del lado en el que las reacciones del equipo ganador queden hacia la cámara â coordÃnalo con el fotógrafo lÃder. Combina tomas cerradas del trofeo levantado con la toma amplia del equipo completo junto al trofeo.",shotStyleEs:"emotivo",shotListEs:["Momento del levantamiento del trofeo","Retrato individual del capitán o MVP con el trofeo","Equipo reunido alrededor del trofeo","Apretón de manos entre entrenador y directivo"],equipmentRequiredEs:["24â70mm f/2.8","70â200mm f/2.8"]},{id:"floor-coverage",name:"Floor / Apparatus",role:"lead",description:"Position floor-side but out of athletes' sight-lines. Each athlete gets one performance â no re-shoots â so anticipate the routine's peak moments. Silent shutter recommended for indoor venues.",expectedPhotoCount:"1,500â3,500",defaultTimeWindow:"First routine through final routine",shotStyle:"action",shotList:["Peak skill (flip, leap, tumble)","Stick-the-landing moment","Routine ending salute","Coach reaction at the side"],equipmentRequired:["70â200mm f/2.8 (or faster) â indoor venues are dim","Silent shutter mode"],nameEs:"Tapete / Aparato",descriptionEs:"Colócate a un costado del tapete pero fuera de la lÃnea de visión de las atletas. Cada quien tiene una sola presentación â no hay repetición â asà que anticipa los momentos cumbre de la rutina. Se recomienda obturador silencioso en venues techados.",shotStyleEs:"acción",shotListEs:["Habilidad cumbre (giro, salto, voltereta)","Aterrizaje firme","Saludo de cierre de la rutina","Reacción del entrenador a un costado"],equipmentRequiredEs:["70â200mm f/2.8 (o más luminoso) â los venues techados son oscuros","Modo de obturador silencioso"]},{id:"podium",name:"Podium",role:"second",description:"Awards ceremony coverage. Low angle so the medalists look proud â sky / ceiling backdrop is better than the crowd. Mix tight individual shots with three-up podium-with-medals.",expectedPhotoCount:"400â800",defaultTimeWindow:"Final routine + 30 min through end of all age groups",shotStyle:"portrait",shotList:["Individual medalist with medal","Three-up podium","Medal hand-off moment","Family reaction in the audience"],equipmentRequired:["24â70mm f/2.8","70â200mm f/2.8"],nameEs:"Podio",descriptionEs:"Cobertura de la ceremonia de premiación. Ãngulo bajo para que las medallistas se vean orgullosas â un fondo de cielo o techo lee mejor que el público. Combina tomas cerradas individuales con la toma del podio completo con sus medallas.",shotStyleEs:"retrato",shotListEs:["Medallista individual con su medalla","Podio completo de los tres lugares","Momento de la entrega de medalla","Reacción de la familia entre el público"],equipmentRequiredEs:["24â70mm f/2.8","70â200mm f/2.8"]},{id:"warm-up-area",name:"Warm-Up Area",role:"course",description:"Backstage / behind-the-scenes coverage. Athletes stretching, coaches giving last-minute notes, the focused calm before the routine. Get permission first â some venues restrict warm-up access.",expectedPhotoCount:"500â1,000",defaultTimeWindow:"Doors open through final athlete called to floor",shotStyle:"candid",shotList:["Athlete stretching / focused face","Coach giving final notes","Athlete walking out of the warm-up area"],equipmentRequired:["24â70mm f/2.8","Discreet body / silent shutter"],notes:"Confirm warm-up area access with the host before the event.",nameEs:"Ãrea de calentamiento",descriptionEs:"Cobertura tras bambalinas. Atletas estirando, entrenadores dando indicaciones de último momento, la calma concentrada antes de la rutina. Pide permiso primero â algunos venues restringen el acceso al área de calentamiento.",shotStyleEs:"espontáneo",shotListEs:["Atleta estirando / rostro concentrado","Entrenador dando las últimas indicaciones","Atleta saliendo del área de calentamiento"],equipmentRequiredEs:["24â70mm f/2.8","Cuerpo discreto / obturador silencioso"],notesEs:"Confirma con el organizador el acceso al área de calentamiento antes del evento."},{id:"transit-drop-off",name:"Transit Drop-Off",role:"lead",description:"Position at the public transit station (subway / metro / light-rail / commuter rail) where the most fans funnel toward the stadium. Stand on PUBLIC ground â never inside the station's fare-paid area or on stadium property. Shoot couples and families as they emerge from the station and walk toward the venue.",expectedPhotoCount:"1,500â3,000",defaultTimeWindow:"3 hr before kickoff through kickoff",shotStyle:"portrait",shotList:["Couple horizontal 3/4-length, low angle, stadium in soft background","Family full-length, stadium silhouette behind","Small group vertical 3/4-length, sky background","Fan with jersey + scarf visible"],equipmentRequired:["Fast 24â70mm f/2.8 (ideal for posed full / 3-4 length)","Extra batteries (3+) â constant shooting on your feet","QR cards to hand to every customer (print 1,000+)"],notes:"Hand EVERY customer a QR card so they can find their photos. Low camera angle keeps background peo
4ple out of frame. Avoid huge group shots â couples and direct families photograph better and move faster.",nameEs:"Salida del transporte público",descriptionEs:"Colócate en la estación de transporte público (metro, tren ligero, tren suburbano) por donde llega el mayor flujo de aficionados rumbo al estadio. Mantente en SUELO PÃBLICO â nunca dentro del área de pago de la estación ni en propiedad del estadio. FotografÃa parejas y familias mientras salen de la estación y caminan hacia el venue.",shotStyleEs:"retrato",shotListEs:["Pareja en plano 3/4 horizontal, ángulo bajo, estadio difuso al fondo","Familia en plano entero, silueta del estadio detrás","Grupo pequeño en plano 3/4 vertical, fondo de cielo","Aficionado con playera y bufanda visibles"],equipmentRequiredEs:["24â70mm f/2.8 luminoso (ideal para plano entero / 3-4 posado)","BaterÃas de repuesto (3+) â vas a disparar todo el tiempo de pie","Tarjetas QR para entregar a cada cliente (imprime 1,000+)"],notesEs:"Entrega una tarjeta QR a CADA cliente para que pueda encontrar sus fotos. El ángulo bajo deja a los curiosos del fondo fuera del cuadro. Evita los grupos enormes â las parejas y familias directas fotografÃan mejor y avanzan más rápido."},{id:"fan-fest-plaza",name:"Fan-Fest Plaza",role:"second",description:"Public plaza or fan-fest zone serving as a pre-game gathering point. High foot traffic, festive atmosphere, props (face paint, flags, jerseys) for great photos. Stay on PUBLIC ground â never cross into stadium / venue property.",expectedPhotoCount:"1,500â2,500",defaultTimeWindow:"3 hr before kickoff through kickoff",shotStyle:"portrait",shotList:["Family with flag / scarf, low angle, venue silhouette","Couple horizontal 3/4-length against fan-fest signage","Small group vertical 3/4-length, plaza in soft background"],equipmentRequired:["24â70mm f/2.8","Extra batteries","QR cards"],notes:"Same QR-card hand-off + low-angle + small-groups rules as Transit Drop-Off.",nameEs:"Plaza del Fan-Fest",descriptionEs:"Plaza pública o zona de fan-fest que sirve como punto de reunión previo al partido. Mucho flujo de gente, ambiente festivo, props (pintura facial, banderas, playeras) para grandes fotos. Mantente en SUELO PÃBLICO â nunca cruces a la propiedad del estadio o venue.",shotStyleEs:"retrato",shotListEs:["Familia con bandera o bufanda, ángulo bajo, silueta del venue","Pareja en plano 3/4 horizontal frente a la señalética del fan-fest","Grupo pequeño en plano 3/4 vertical, plaza difusa al fondo"],equipmentRequiredEs:["24â70mm f/2.8","BaterÃas de repuesto","Tarjetas QR"],notesEs:"Aplican las mismas reglas que en Salida del transporte público: entrega de tarjeta QR, ángulo bajo y grupos pequeños."},{id:"main-gate-approach",name:"Main Gate Approach",role:"course",description:"Public-street pedestrian approach to the stadium's main entrance gate. Stand on the public sidewalk â NEVER cross the property line into stadium-owned space. Fans funneling to the gate are festive but moving â be quick.",expectedPhotoCount:"1,500â2,500",defaultTimeWindow:"2 hr before kickoff through kickoff",shotStyle:"portrait",shotList:["Couple horizontal 3/4-length, gate / signage softly behind","Family full-length, stadium silhouette behind","Fan with jersey + ticket visible"],equipmentRequired:["24â70mm f/2.8","Extra batteries","QR cards"],nameEs:"Acceso a la puerta principal",descriptionEs:"Acceso peatonal por vÃa pública hacia la puerta principal del estadio. Mantente en la banqueta pública â NUNCA cruces el lindero hacia el terreno del estadio. Los aficionados que se dirigen a la puerta vienen festivos pero en movimiento â sé rápido.",shotStyleEs:"retrato",shotListEs:["Pareja en plano 3/4 horizontal, puerta o señalética difusa atrás","Familia en plano entero, silueta del estadio detrás","Aficionado con playera y boleto visibles"],equipmentRequiredEs:["24â70mm f/2.8","BaterÃas de repuesto","Tarjetas QR"]},{id:"stadium-perimeter",name:"Stadium-Perimeter Sidewalk",role:"course",description:"Public sidewalk along the stadium perimeter where fans walk between parking / transit and their gate. Stand clearly on the public side of any property line. The stadium itself makes a great backdrop from this angle.",expectedPhotoCount:"1,200â2,000",defaultTimeWindow:"2.5 hr before kickoff through kickoff",shotStyle:"portrait",shotList:["Couple horizontal 3/4-length, stadium visible behind","Family vertical 3/4-length, low angle, sky background"],equipmentRequired:["24â70mm f/2.8","Extra batteries","QR cards"],nameEs:"Banqueta del perÃmetro del estadio",descriptionEs:"Banqueta pública alrededor del perÃmetro del estadio, por donde los aficionados caminan entre estacionamiento o transporte y su puerta de acceso. Colócate claramente del lado público de cualquier lindero. Desde este ángulo, el propio estadio queda como un gran fondo.",shotStyleEs:"retrato",shotListEs:["Pareja en plano 3/4 horizontal, estadio visible detrás","Familia en plano 3/4 vertical, ángulo bajo, fondo de cielo"],equipmentRequiredEs:["24â70mm f/2.8","BaterÃas de repuesto","Tarjetas QR"]},{id:"public-plaza",name:"Public Plaza / Park",role:"course",description:"Public park or city plaza near the stadium where fans gather before walking to the gate. Look for benches, fountains, statues â they make for cleaner compositions than the stadium-adjacent sidewalks.",expectedPhotoCount:"1,000â2,000",defaultTimeWindow:"3 hr before kickoff through kickoff",shotStyle:"portrait",shotList:["Couple seated on a public bench, environmental","Family in front of a fountain / statue","Vertical 3/4-length with public-park greenery behind"],equipmentRequired:["24â70mm f/2.8","Extra batteries","QR cards"],nameEs:"Plaza / Parque público",descriptionEs:"Parque público o plaza de la ciudad cerca del estadio donde los aficionados se reúnen antes de caminar a la puerta. Busca bancas, fuentes, estatuas â dan composiciones más limpias que las banquetas pegadas al estadio.",shotStyleEs:"retrato",shotListEs:["Pareja sentada en una banca pública, plano ambiental","Familia frente a una fuente o estatua","Plano 3/4 vertical con vegetación del parque público de fondo"],equipmentRequiredEs:["24â70mm f/2.8","BaterÃas de repuesto","Tarjetas QR"]},{id:"stadium-roamer",name:"Stadium-Area Roamer",role:"roamer",description:"Fill coverage gaps between fixed positions. Move every 20â30 min along public approaches around the stadium. Listen to the lead photographer on where the foot traffic is shifting.",expectedPhotoCount:"1,000â2,000",defaultTimeWindow:"3 hr before kickoff through kickoff",shotStyle:"candid",shotList:["Spontaneous fan reactions on the approach","Stadium-adjacent street photography","Pre-game atmospheric wide shots"],equipmentRequired:["24â70mm f/2.8","Comfortable shoes","QR cards"],nameEs:"Fotógrafo móvil de la zona del estadio",descriptionEs:"Cubre los huecos de cobertura entre las posiciones fijas. Cámbiate de punto cada 20â30 minutos a lo largo de los accesos públicos alrededor del estadio. Escucha al fotógrafo lÃder sobre hacia dónde se está moviendo el flujo de gente.",shotStyleEs:"espontáneo",shotListEs:["Reacciones espontáneas de aficionados en el acceso","FotografÃa callejera junto al estadio","Tomas amplias del ambiente previo al partido"],equipmentRequiredEs:["24â70mm f/2.8","Calzado cómodo","Tarjetas QR"]},{id:"vip-arrivals",name:"VIP Arrivals",role:"lead",description:"Position at the venue entrance for arriving VIPs, sponsors, speakers. Get a list of names from the client in advance â knowing who to recognize is half the job.",expectedPhotoCount:"300â800",defaultTimeWindow:"Doors open â 15 min through 30 min after start",shotStyle:"portrait",shotList:["Individual VIP entrance / handshake","VIP with event signage","V
4IP small-group conversation"],equipmentRequired:["24â70mm f/2.8","Speedlight + diffuser"],nameEs:"Llegada de VIPs",descriptionEs:"Colócate en la entrada del venue para recibir a los VIPs, patrocinadores y ponentes. Pide al cliente la lista de invitados con anticipación â saber a quién reconocer ya es la mitad del trabajo.",shotStyleEs:"retrato",shotListEs:["Llegada / apretón de manos del VIP individual","VIP junto a la señalética del evento","VIP en plática de grupo pequeño"],equipmentRequiredEs:["24â70mm f/2.8","Flash de zapata con difusor"]},{id:"keynote-stage",name:"Keynote / Main Stage",role:"second",description:"Stage-side coverage during the keynote, panel, or main programming. Mix wide audience-with-speaker shots with tight speaker portraits. Stay out of the audience's sight-line.",expectedPhotoCount:"500â1,500",defaultTimeWindow:"Keynote start through final speaker",shotStyle:"portrait",shotList:["Tight speaker portrait, hands-in-frame gesture","Wide stage with audience and screens visible","Q&A audience hands raised","Speaker + screen with key slide content"],equipmentRequired:["70â200mm f/2.8","24â70mm f/2.8"],nameEs:"Conferencia magistral / Escenario principal",descriptionEs:"Cobertura a un costado del escenario durante la conferencia, el panel o el programa principal. Combina tomas amplias del público con el ponente y retratos cerrados del ponente. Mantente fuera de la lÃnea de visión del público.",shotStyleEs:"retrato",shotListEs:["Retrato cerrado del ponente con gesto de manos en cuadro","Toma amplia del escenario con público y pantallas visibles","Manos levantadas del público en la sesión de preguntas","Ponente más pantalla con la diapositiva clave"],equipmentRequiredEs:["70â200mm f/2.8","24â70mm f/2.8"]},{id:"audience-reaction",name:"Audience Reaction",role:"course",description:"Documenting the audience's experience. Laughing, taking notes, networking during breaks. Helps the client's marketing team show 'engagement' rather than just 'we had a speaker'.",expectedPhotoCount:"500â1,000",defaultTimeWindow:"First session through final session",shotStyle:"candid",shotList:["Audience member laughing at a joke","Two attendees in a focused side conversation","Person taking notes / using their phone","Wide audience showing density"],equipmentRequired:["70â200mm f/2.8","24â70mm f/2.8"],nameEs:"Reacción del público",descriptionEs:"Documenta la experiencia del público. Risas, toma de apuntes, networking en los recesos. Ayuda al equipo de marketing del cliente a mostrar 'participación', no nada más 'tuvimos un ponente'.",shotStyleEs:"espontáneo",shotListEs:["Asistente riéndose de un chiste","Dos asistentes en una conversación lateral concentrada","Persona tomando apuntes o usando el celular","Toma amplia del público mostrando la densidad"],equipmentRequiredEs:["70â200mm f/2.8","24â70mm f/2.8"]},{id:"networking-breaks",name:"Networking / Breaks",role:"course",description:"Coverage of breaks, mixers, receptions. Less posed, more candid. Watch for handshakes, business-card exchanges, and the 'a-ha' moments at sponsor tables.",expectedPhotoCount:"500â1,000",defaultTimeWindow:"Each break window â usually 3â4 windows per event-day",shotStyle:"candid",shotList:["Two attendees mid-conversation, drink in hand","Handshake / business-card exchange","Group laughing at a high-top table","Sponsor booth interaction"],equipmentRequired:["24â70mm f/2.8","35mm f/1.4 (low-light bonus)"],nameEs:"Networking / Receso",descriptionEs:"Cobertura de recesos, cocteles y recepciones. Menos pose, más espontáneo. Pon atención a apretones de manos, intercambios de tarjetas y los momentos 'aha' en los stands de patrocinadores.",shotStyleEs:"espontáneo",shotListEs:["Dos asistentes a media conversación, con bebida en mano","Apretón de manos / intercambio de tarjeta de presentación","Grupo riéndose en una mesa alta","Interacción en el stand de patrocinador"],equipmentRequiredEs:["24â70mm f/2.8","35mm f/1.4 (extra para poca luz)"]},{id:"general-roamer",name:"Event Roamer",role:"roamer",description:"Fill coverage gaps. Move every 30 min between programming areas. The lead photographer will direct you to under-covered moments.",expectedPhotoCount:"500â1,000",defaultTimeWindow:"Event start through event end",shotStyle:"candid",shotList:["Unscripted moments outside formal programming","Event signage / branding","Atmosphere shots"],equipmentRequired:["24â70mm f/2.8"],nameEs:"Fotógrafo móvil del evento",descriptionEs:"Cubre los huecos de cobertura. Muévete cada 30 minutos entre las áreas del programa. El fotógrafo lÃder te va a dirigir a los momentos con menos cobertura.",shotStyleEs:"espontáneo",shotListEs:["Momentos no planeados fuera del programa formal","Señalética y branding del evento","Tomas de ambiente"],equipmentRequiredEs:["24â70mm f/2.8"]}],hs=Object.fromEntries(ps.map(o=>[o.id,o]));function gs(o){return hs[o]??null}function fs(o){const p=o.length,u=o.map(x=>{const T=`${x.name??""} ${x.location??""}`.toLowerCase().match(/\b(?:mile|km)\s*(\d+(?:\.\d+)?)/);return T?parseFloat(T[1]):null}),N=u.filter(x=>x!==null),R=N.length?Math.max(1,...N):1;return o.map((x,v)=>{const T=`${x.name??""} ${x.location??""}`.toLowerCase(),I=u[v];let A,S;return/\bfinish\b/.test(T)?A=92:/\bstart\b|\bgun\b/.test(T)?A=8:/\bturn[\s-]?around\b/.test(T)?A=50:I!==null?A=10+I/R*80:A=p>1?25+v/(p-1)*50:50,/\bwater\b|\bhydration\b|\baid\b|\bmedical\b/.test(T)?S=72:/\bspectator\b|\bcrowd\b|\baward\b|\bmedal\b|\bfinisher\b|\bcorral\b|\bpodium\b/.test(T)?S=28:/\broamer\b/.test(T)?S=45+v%3*8:I!==null?S=50+(v%3-1)*5:S=50,{x:Math.max(5,Math.min(95,A)),y:Math.max(5,Math.min(95,S))}})}function sa(o){const p=Math.max(1,Math.round(o*.35)),u=Math.max(1,Math.round(o*.45)),N=Math.max(1,o-p-u);return{finish:p,course:u,medals:N}}function Oe(o){switch((o||"").toLowerCase().trim()){case"soccer":case"lacrosse"
4:case"rugby":case"football":case"baseball":case"softball":return{singular:"field",plural:"fields"};case"hockey":return{singular:"rink",plural:"rinks"};case"basketball":case"tennis":case"pickleball":case"volleyball":return{singular:"court",plural:"courts"};case"wrestling":case"martial-arts":return{singular:"mat",plural:"mats"};case"swimming":case"diving":return{singular:"pool",plural:"pools"};case"gymnastics":case"cheer":case"cheerleading":case"dance":case"figure-skating":return{singular:"floor",plural:"floors"};case"weightlifting":case"crossfit":case"bodybuilding":return{singular:"stage",plural:"stages"};default:return{singular:"venue",plural:"venues"}}}function xs(o,p){switch(o){case"tournament":{const u=Oe(p);return{finish:`at the main ${u.singular}`,course:`at side ${u.plural}`,medals:"at the awards / ceremony"}}case"competition":return{finish:`on the ${Oe(p).singular}`,course:"at warm-up / staging",medals:"at the awards"};case"general":return{finish:"lead",course:"secondary",medals:"awards"};default:return{finish:"at the finish line",course:"along the course",medals:"in the finisher / awards area"}}}function bs(o,p){switch(o){case"tournament":return`Positions on the ${Oe(p).singular}`;case"competition":return`Positions on the ${Oe(p).singular}`;case"general":return"Positions at the venue";default:return"Positions on the course"}}const na=["Event Basics","Recommended Crew","Plan & Staffing"];function pe(o){if(typeof o!="string"||!o)return"";const p=o.match(/\b([01]?\d|2[0-3]):([0-5]\d)(?::[0-5]\d(?:\.\d{1,3})?)?\b/);return p?`${p[1].padStart(2,"0")}:${p[2]}`:""}const vs=oa.divIcon({className:"logistics-pin-accepted",html:'<span style="display:block;width:14px;height:14px;border-radius:50%;background:#2563EB;border:2px solid #fff;box-shadow:0 1px 3px rgba(0,0,0,.3);"></span>',iconSize:[14,14],iconAnchor:[7,7]}),ys=oa.divIcon({className:"logistics-pin-ai",html:'<span style="display:block;width:14px;height:14px;border-radius:50%;background:#fff;border:2px dashed #64748B;box-shadow:0 1px 3px rgba(0,0,0,.3);"></span>',iconSize:[14,14],iconAnchor:[7,7]});function js({bounds:o}){const p=ns(),u=l.useRef(!1);return l.useEffect(()=>{u.current||!o||(p.fitBounds(o,{padding:[40,40],maxZoom:18}),u.current=!0)},[o,p]),null}function zs(){const{eventId:o}=Fa(),p=Ba(),[u,N]=l.useState(0),[R,x]=l.useState(""),[v,T]=l.useState(""),[I,A]=l.useState(""),[S,K]=l.useState(""),[W,_]=l.useState(""),[G,ke]=l.useState(0),[Se,f]=l.useState("1"),[b,y]=l.useState("5000-7000"),[P,$]=l.useState("direct"),[q,F]=l.useState("24"),[M,V]=l.useState(null),[Y,ae]=l.useState("upload"),[he,ze]=l.useState([]),[Ee,rt]=l.useState([]),[se,lt]=l.useState([]),[ne,ia]=l.useState([]),[oe,dt]=l.useState({}),[Fe,Be]=l.useState(!1),[ct,De]=l.useState(""),[mt,We]=l.useState(1),[E,ge]=l.useState(null),[k,O]=l.useState([]),[Q,fe]=l.useState([]),[L,X]=l.useState([]),[ut,pt]=l.useState(null),[ht,gt]=l.useState([]),[ra,ft]=l.useState(!1),[la,Ce]=l.useState(!1),[Pe,Ue]=l.useState(""),[ie,xt]=l.useState(!1),[bt,vt]=l.useState(null),[Te,Ge]=l.useState(!1),[xe,yt]=l.useState(!1),[da,jt]=l.useState(0),[wt,Nt]=l.useState(null),[Z,kt]=l.useState(!1),[ca,Re]=l.useState(!1),[be,ma]=l.useState("hourly"),[Ve,ua]=l.useState(""),[He,St]=l.useState(""),[re,Et]=l.useState(""),[le,pa]=l.useState(!1),[Ct,ha]=l.useState("5"),[Pt,ga]=l.useState("20"),[z,Tt]=l.useState(!1),[H,Je]=l.useState(null),[h,_e]=l.useState(null),[Ye,fa]=l.useState(null),[qe,xa]=l.useState([]),[de,Rt]=l.useState(!1),[Qe,qt]=l.useState(!1),[ve,Le]=l.useState("upload"),ee=l.useRef(!1),Lt=l.useRef(null);l.useEffect(()=>{H?Le("upload"):h&&Le("live")},[H,h]),l.useEffect(()=>{if(H||h)return;const t=W.trim();if(!t){_e(null);return}let a=!1;const s=setTimeout(()=>{fetch(`https://nominatim.openstreetmap.org/search?format=json&limit=1&q=${encodeURIComponent(t)}`,{headers:{"Accept-Language":"en"}}).then(r=>r.ok?r.json():null).then(r=>{if(!a&&Array.isArray(r)&&r.length>0){const n=parseFloat(r[0].lat),i=parseFloat(r[0].lon);Number.isFinite(n)&&Number.isFinite(i)&&_e({lat:n,lng:i})}}).catch(()=>{})},700);return()=>{a=!0,clearTimeout(s)}},[W,H,h]);const Mt=k.some(t=>t.staffingTab==="marketplace");l.useEffect(()=>{Mt&&(de||Qe||(Rt(!0),Ua({lat:h==null?void 0:h.lat,lng:h==null?void 0:h.lng,radiusMiles:h?100:void 0,eventType:v||void 0,limit:12}).then(t=>{xa(t),qt(!0)}).finally(()=>Rt(!1))))},[Mt,h,v,de,Qe]),l.useEffect(()=>{qt(!1)},[h,v]);const It=l.useRef(null),Ke=l.useRef(!1),te=os(v),ba=is[te],At=Ye==="stadium-souvenir-photos"?"souvenir":te;l.useEffect(()=>{let t=!1;return Ga(At).then(a=>{t||ia(a)}),()=>{t=!0}},[At]);const Me=l.useMemo(()=>Object.values(oe).reduce((t,a)=>t+(a>0?a:0),0),[oe]),B=l.useMemo(()=>
4{if(!h)return null;const t=.003,a=.012,s=[...k.filter(m=>typeof m.lat=="number"&&typeof m.lng=="number"),...Q.filter(m=>typeof m.lat=="number"&&typeof m.lng=="number")],r=[h.lat,...s.map(m=>m.lat)],n=[h.lng,...s.map(m=>m.lng)];let i=Math.min(...r)-t,d=Math.max(...r)+t,c=Math.min(...n)-t,w=Math.max(...n)+t;if(d-i<a){const m=h.lat;i=m-a/2,d=m+a/2}if(w-c<a){const m=h.lng;c=m-a/2,w=m+a/2}return{south:i,north:d,west:c,east:w}},[h,k,Q]),$t=l.useCallback((t,a)=>{if(a==="live"&&B&&typeof t.lat=="number"&&typeof t.lng=="number"){const s=(t.lng-B.west)/(B.east-B.west)*100,r=(B.north-t.lat)/(B.north-B.south)*100;return{x:Math.max(2,Math.min(98,s)),y:Math.max(2,Math.min(98,r))}}return{x:t.pinX,y:t.pinY}},[B]);l.useEffect(()=>{!o||Ke.current||(Ke.current=!0,Va(o).then(t=>{t&&(x(a=>a||t.eventName||""),A(a=>{var s;return a||((s=t.eventDate)==null?void 0:s.slice(0,10))||""}),_(a=>a||t.eventLocation||""),K(a=>a||pe(t.startTime)),T(a=>a||t.eventType||""),ke(a=>a||t.totalParticipants||0),t.lat!=null&&t.lng!=null&&Number.isFinite(t.lat)&&Number.isFinite(t.lng)&&_e({lat:t.lat,lng:t.lng}),fa(t.landingGroupSlug??null),t.hasMarketplaceJobs&&Ge(!0))}),Ne(o).then(t=>{X(t)}),ft(!0),Qt().then(t=>{gt(t),ft(!1)}),Kt(o).then(t=>{if(!t)return;t.mapImageUrl&&Je(t.mapImageUrl),t.callTime&&K(r=>r||pe(t.callTime)),t.callLocation&&_(r=>r||t.callLocation||"");const a=(t.mapPins||[]).filter(r=>r.type==="photographer"),s=(t.mapPins||[]).filter(r=>r.type!=="photographer");if(s.length>0&&rt(s),(t.mapPins||[]).length>0&&ze(t.mapPins||[]),a.length>0){O(a.map(n=>({name:n.label||"Position",role:n.role,location:void 0,description:n.notes||"",timeWindow:n.timeWindow,shotStyle:n.shotStyle,equipmentRequired:n.equipmentRequired,shotList:n.shotList,notes:void 0,pinX:typeof n.x=="number"?n.x:50,pinY:typeof n.y=="number"?n.y:50,lat:typeof n.lat=="number"?n.lat:void 0,lng:typeof n.lng=="number"?n.lng:void 0,inviteEmail:"",inviteName:"",staffingTab:"byo",assignmentStatus:"unassigned"}))),ee.current=!0;const r=t.eventNotes||"";if(r||t.callTime){const n=U=>{const j=new RegExp("^"+U+":\\s*([\\s\\S]*?)(?=\\n\\n[A-Z][A-Z ]*:|$)","m"),J=r.match(j);return J?J[1].trim():void 0},i=n("GENERAL INSTRUCTIONS"),d=n("WEATHER BACKUP"),c=n("STYLE NOTES"),w=n("EQUIPMENT NEEDED"),m=w?w.split(/\n/).map(U=>U.replace(/^[\u2022\-]\s*/,"").trim()).filter(Boolean):void 0;ge({meetingTime:t.callTime,generalInstructions:i,weatherBackupPlan:d,styleNotes:c,equipmentNeeded:m,positions:a})}}}))},[o]),l.useEffect(()=>{if(!o||!Ke.current)return;const t=setTimeout(()=>{Ha(o,{eventName:R||void 0,eventLocation:W||void 0,eventType:v||void 0,totalParticipants:G||void 0,startTime:S||void 0,eventDate:I||void 0})},1500);return()=>clearTimeout(t)},[o,R,W,v,G,S,I]);const Ot=async t=>{if(V(t),o){const a=await Qa(o,t);Je(typeof a=="string"&&a?a:URL.createObjectURL(t))}},Ie=(()=>{const t=G,a=parseInt(Se)||1,s=v;if(t<100)return{total:3,finish:1,course:1,medals:1};const r=Math.ceil(Math.max(t,1e3)/1e3);let n=0;["5k","1-mile","5k-10k"].includes(s)?n=a>4?1:0:["10k","15k","half-marathon"].includes(s)?n=a>=6?2:a>=4?1:0:["marathon","mud-run","obstacle","trail","ultra"].includes(s)&&(n=a>=6?2:a>=5?1:0);let i=0;["half-marathon","15k"].includes(s)?i=1:["marathon","mud-run","obstacle","trail","ultra","triathlon"].includes(s)&&(i=2);const d=Math.max(3,r+n+i);return{total:d,...sa(d)}})().total,Xe=sa(Ie),va=se.reduce((t,a)=>t+a.count,0),zt=(Me>0?Me:Ie)+va,Ft=k.filter(t=>t.staffingTab==="marketplace"&&t.assignmentStatus!=="invited").length,Bt=()=>{const t=ct.trim();if(!t){g.error("Give the role a name.");return}const a=Math.max(1,Math.min(20,mt));lt(s=>[...s,{id:`role-${Date.now()}`,name:t,count:a}]),De(""),We(1),Be(!1)},ya=t=>{lt(a=>a.filter(s=>s.id!==t))},Ze=l.useMemo(()=>Ye!=="stadium-souvenir-photos"?null:ms(h==null?void 0:h.lat,h==null?void 0:h.lng),[Ye,h]),ja=t=>{const r=[...t.spots.map(n=>({spot:n,def:gs(n.catalogId)})).filter(n=>n.def!==null)].sort((n,i)=>{const d={lead:0,second:1,course:2,roamer:3};return d[n.def.role]-d[i.def.role]}).slice(0,Math.max(1,zt));O(r.map(({spot:n,def:i})=>({name:n.nameOverride||i.name,role:i.role,location:n.nameOverride||i.name,description:n.descriptionOverride||i.description,timeWindow:i.defaultTimeWindow,shotStyle:i.shotStyle,equipmentRequired:i.equipmentRequired,shotList:i.shotList,notes:i.notes,nameEs:i.nameEs,descriptionEs:i.descriptionEs,shotStyleEs:i.shotStyleEs,shotListEs:i.shotListEs,equipmentRequiredEs:i.equipmentRequiredEs,notesEs:i.notesEs,pinX:50,pinY:50,lat:n.lat,lng:n.lng,inviteEmail:"",inviteName:"",staffingTab:"byo",assignmentStatus:"unassigned"}
4))),ge({meetingLocation:t.name,generalInstructions:`Curated positions for ${t.name}, ${t.city}. Photographers stand on PUBLIC ground around the venue (never on stadium property). Subjects: couples and direct families â keep groups small. Low camera angle to keep background people out. Drag any pin to fine-tune the spot on the map.`})},wa=()=>{const t=Object.fromEntries(ne.map(n=>[n.id,n])),a={lead:0,second:1,course:2,roamer:3},s=Object.keys(oe).filter(n=>(oe[n]||0)>0&&t[n]).sort((n,i)=>(a[t[n].role]??9)-(a[t[i].role]??9)),r=[];for(const n of s){const i=t[n],d=oe[n]||0;for(let c=0;c<d;c++)r.push({name:i.name,role:i.role,location:i.name,description:i.description,timeWindow:i.defaultTimeWindow||void 0,shotStyle:i.shotStyle||void 0,equipmentRequired:i.equipmentRequired,shotList:i.shotList,notes:i.notes||void 0,nameEs:i.nameEs,descriptionEs:i.descriptionEs,shotStyleEs:i.shotStyleEs,shotListEs:i.shotListEs,equipmentRequiredEs:i.equipmentRequiredEs,notesEs:i.notesEs,pinX:50,pinY:50,inviteEmail:"",inviteName:"",staffingTab:"byo",assignmentStatus:"unassigned"})}O(r),ge({generalInstructions:"Positions selected from the catalog. Edit any position's details below, drag pins to place them on the map, then assign or invite photographers."})},et=async()=>{var d;if(!o||xe)return;yt(!0),Nt(null),jt(0);const t=setInterval(()=>jt(c=>c+1),1e3),a={expectedPhotosPerPhotographer:b,uploadDeadlineHours:q,uploadMethod:P},s=xs(te,v),r=`Crew breakdown: ${Xe.finish} ${s.finish}, ${Xe.course} ${s.course}, ${Xe.medals} ${s.medals}`+(se.length>0?`, plus ${se.map(c=>`${c.count} à ${c.name}`).join(", ")}`:""),i=`${P==="direct"?"Upload method: each photographer uploads their own images directly to the portal.":"Upload method: photographers hand memory cards to the team lead who ingests + uploads."} ${r}.`;try{const c=await Ja(o,zt,i,a);if(!c)throw new Error("No result");ge(c);const w=c.positions||[],m=fs(w);fe(w.map((j,J)=>{const{x:ce,y:me}=m[J]||{x:50,y:50},at=typeof j.lat=="number"&&Number.isFinite(j.lat)?j.lat:void 0,st=typeof j.lng=="number"&&Number.isFinite(j.lng)?j.lng:void 0;return{name:j.name||"Position",role:j.role,location:j.location,description:j.description||"",timeWindow:j.timeWindow,shotStyle:j.shotStyle,equipmentRequired:j.equipmentRequired,shotList:j.shotList,notes:j.notes,pinX:ce,pinY:me,lat:at,lng:st,inviteEmail:"",inviteName:"",staffingTab:"byo",assignmentStatus:"unassigned"}}));const U=[c.generalInstructions?`GENERAL INSTRUCTIONS: 5${c.generalInstructions}`:"",(d=c.equipmentNeeded)!=null&&d.length?`EQUIPMENT NEEDED: 6${c.equipmentNeeded.map(j=>`⢠${j}`).join(` 7`)}`:"",c.weatherBackupPlan?`WEATHER BACKUP: 8${c.weatherBackupPlan}`:"",c.styleNotes?`STYLE NOTES: 9${c.styleNotes}`:""].filter(Boolean).join(` 10 11`);await $e(o,{callTime:pe(c.meetingTime)||pe(S)||void 0,eventNotes:U||void 0}),await _a(o,{allowPhotographerUpload:!0,photographerUploadDeadlineHours:Number(q)||0,photographerUploadMethod:P})}catch(c){console.error("AI generation failed:",c),Nt("Couldn't generate the plan. Try again.")}finally{clearInterval(t),yt(!1)}};l.useEffect(()=>{if(u===2&&!ee.current&&o){if(Ze){ee.current=!0,ja(Ze);return}if(Me>0){ee.current=!0,wa();return}ee.current=!0,et()}},[u,o,Ze]);const Na=async t=>{if(!o)return;const a=k[t];if(!a)return;const s=a.inviteEmail.trim(),r=a.inviteName.trim()||s.split("@")[0]||"Photographer";if(!s||!s.includes("@")){g.error("Enter a valid email.");return}const n=r.split(/\s+/),i=n[0]||"Photographer",d=n.slice(1).join(" ")||"";O(w=>{const m=[...w];return m[t]={...m[t],assignmentStatus:"inviting"},m});const c=await Xa(o,{firstName:i,lastName:d,email:s,role:a.role||void 0,customRole:a.name});c.ok?(g.success(`Invited ${i} ${d}`.trim()),O(w=>{const m=[...w];return m[t]={...m[t],assignmentStatus:"invited"},m})):(g.error(c.detail||"Couldn't send invite."),O(w=>{const m=[...w];return m[t]={...m[t],assignmentStatus:"unassigned"},m}))},Dt=async()=>{if(o){if(L.length===0){g.error("Add team members to your positions before publishing â invite via 'Bring my own' on each position card, or hire via 'Book from marketplace'.");return}kt(!0);try{const t=await Xt(o);if(!t){g.error("Couldn't publish â try again.");return}const a=t.notifiedConfirmed??0;if(t.invited+a===0){g.error(t.skipped>0?`Skipped ${t.skipped} team member${t.skipped===1?"":"s"} â missing or invalid email addresses.`:"No notifications went out â check your team list.");const d=await Ne(o);X(d);return}const r=[];t.invited>0&&r.push(`${t.invited} invite${t.invited===1?"":"s"}`),a>0&&r.push(`${a} briefing${a===1?"":"s"}`),g.success(`Sent ${r.join(" + ")}.`),Ge(!0);const n=await Ne(o);X(n);const i=t.unfilledPositions??0;t.marketplaceJobStatus==="updated"&&i>0?g.success(`Marketplace listing updated â ${i} position${i===1?"":"s"} still open to applicants.`):t.marketplaceJobStatus==="needs_create"&&i>0&&g.custom(d=>e.jsxs("div",{className:"flex flex-col gap-2",children:[e.jsxs("span",{className:"text-sm text-slate-900",children:[i," position",i===1?"":"s"," still unfilled â post a hire job so new photographers can a
11pply?"]}),e.jsxs("div",{className:"flex gap-2",children:[e.jsx("button",{onClick:()=>{g.dismiss(d),p(`/post-job?eventId=${o}`)},className:"rounded-lg bg-[var(--m3-primary)] px-3 py-1.5 text-xs font-semibold text-white hover:opacity-90",children:"Post hire job"}),e.jsx("button",{onClick:()=>g.dismiss(d),className:"rounded-lg border border-slate-300 px-3 py-1.5 text-xs font-medium text-slate-600 hover:bg-slate-50",children:"Not now"})]})]}),{duration:12e3})}finally{kt(!1)}}},ka=async()=>{if(!o||Te||z)return;if(be==="flat-plus-commission"){const s=parseFloat(He);if(!Number.isFinite(s)||s<0||s>100){g.error("Commission must be between 0 and 100%.");return}}Tt(!0);let t=!0,a=!1;try{const s=await Xt(o);if(!s){g.error("Couldn't publish â try again."),t=!1;return}const r=s.notifiedConfirmed??0;if(s.invited+r>0){const m=[];s.invited>0&&m.push(`${s.invited} invite${s.invited===1?"":"s"}`),r>0&&m.push(`${r} briefing${r===1?"":"s"}`),g.success(`Sent ${m.join(" + ")}.`);const U=await Ne(o);X(U)}const i=Math.max(1,parseInt(re,10)||1),d=parseFloat(Ve),c=be==="flat-plus-commission"?parseFloat(He)||0:void 0,w={eventId:o,eventName:R||"",eventType:v||"",eventDateIso:I?`${I}T00:00:00`:new Date(Date.now()+30*864e5).toISOString(),applicationDeadlineIso:I?new Date(new Date(`${I}T00:00:00`).getTime()-864e5).toISOString():new Date(Date.now()+14*864e5).toISOString(),payStructure:be,minGuaranteeAmount:isNaN(d)?0:d,photographerRate:isNaN(d)?0:d,commissionPct:c,locationAddress:W||void 0,referralEnabled:le,referralBonusCents:le?Math.max(500,Math.round((parseFloat(Ct)||5)*100)):void 0,referralCapCents:le?Math.max(500,Math.round((parseFloat(Pt)||20)*100)):void 0};if(P==="lead"){const m=Math.max(0,i-1),U=[ot({...w,role:"lead",positionsAvailable:1,description:"Lead / upload coordinator â collects the team's cards and uploads."})];m>0&&U.push(ot({...w,role:"photographer",positionsAvailable:m,description:`${m} photographer slot${m===1?"":"s"} for ${R||"this event"}.`})),(await Promise.all(U)).every(J=>J.ok)?(g.success(m>0?`Posted Lead listing + ${m} photographer slot${m===1?"":"s"}.`:"Lead listing posted."),a=!0):g.error("Couldn't post all listings â check the marketplace and try again.")}else{const m=await ot({...w,role:"photographer",positionsAvailable:i,description:`${i} photographer slot${i===1?"":"s"} for ${R||"this event"}.`});m.ok?(g.success("Job posted to the marketplace."),a=!0):g.error(`Couldn't post job: ${m.detail}`)}}finally{Tt(!1),t&&Re(!1),a&&(Ge(!0),le&&o&&es(o).then(s=>{s&&s.sent>0&&g.success(`Referral request sent to ${s.sent} team member${s.sent===1?"":"s"} (${s.bonusLabel} each).`)}))}},tt=t=>{fe(a=>{const s=a[t];return s?(O(r=>[...r,s]),a.filter((r,n)=>n!==t)):a})},Sa=()=>{fe(t=>t.length===0?t:(O(a=>[...a,...t]),[]))},Ea=t=>{fe(a=>a.filter((s,r)=>r!==t))},Ca=()=>{fe([])},ye=(t,a,s)=>{O(r=>{const n=[...r];return n[t]={...n[t],[a]:s},n})},Pa=(t,a)=>{var i;const s=(((i=k[t])==null?void 0:i.name)||"").trim(),r=a;O(d=>{const c=[...d],w=c[t];return w?(c[t]={...w,name:r},c):d});const n=r.trim();s&&n&&s!==n&&X(d=>d.map(c=>(c.assignedPosition||"").trim()===s?{...c,assignedPosition:n}:c))},Ta=async(t,a)=>{if(o){pt(t);try{const s=await Ka(o,t,a.trim()||null);if(!s){g.error("Couldn't update assignment â try again");return}X(n=>n.map(i=>i.id===t?{...i,assignedPosition:s.assignedPosition}:i)),g.success(a?`Assigned ${s.firstName||"photographer"} to ${a}`:`Unassigned ${s.firstName||"photographer"}`);const r=await Ne(o);X(r)}finally{pt(null)}}},Wt=async()=>{const t=Pe.trim();if(!t){g.error("Give the template a name");return}if(k.length===0){g.error("Add at least one position before saving as template");return}xt(!0);try{const s={mapPins:k.map(i=>({type:"photographer",label:i.name,role:i.role,notes:i.description,timeWindow:i.timeWindow,shotStyle:i.shotStyle,equipmentRequired:i.equipmentRequired,shotList:i.shotList,labelEs:i.nameEs,notesEs:i.descriptionEs,shotStyleEs:i.shotStyleEs,equipmentRequiredEs:i.equipmentRequiredEs,shotListEs:i.shotListEs,x:i.pinX,y:i.pinY})),eventNotes:E!=null&&E.generalInstructions?String(E.generalInstructions):void 0,specialInstructions:E!=null&&E.weatherBackupPlan?String(E.weatherBackupPlan):void 0};if(!await Za(t,s)){g.error("Couldn't save template â try again");return}g.success(`Template "${t}" saved`),Ce(!1),Ue("");
11const n=await Qt();gt(n)}finally{xt(!1)}},Ra=async t=>{if(!(!o||!t)){vt(t);try{const a=await Ya(o,t);if(!(a!=null&&a.ok)){g.error("Couldn't apply template â try again");return}const s=await Kt(o);if(!s){g.error("Template applied but couldn't reload â refresh the page");return}const r=(s.mapPins||[]).filter(n=>n.type==="photographer");if(r.length===0){g.error("Template had no photographer positions");return}O(r.map(n=>({name:n.label||"Position",role:n.role,location:void 0,description:n.notes||"",timeWindow:n.timeWindow,shotStyle:n.shotStyle,equipmentRequired:n.equipmentRequired,shotList:n.shotList,notes:void 0,pinX:typeof n.x=="number"?n.x:50,pinY:typeof n.y=="number"?n.y:50,inviteEmail:"",inviteName:"",staffingTab:"marketplace",assignmentStatus:"unassigned"}))),g.success(`Applied "${a.templateName||"template"}" â ${r.length} position${r.length===1?"":"s"} loaded`),N(2)}finally{vt(null)}}},qa=async()=>{if(o)try{await $e(o,{callTime:pe(S)||void 0,callLocation:W||void 0}),g.success("Draft saved")}catch{g.error("Couldn't save draft")}},La=(t,a)=>{t.preventDefault(),t.stopPropagation();const s=Lt.current;if(!s)return;const r=k[a];if(!r)return;const n=s.getBoundingClientRect(),i=t.clientX,d=t.clientY,c=r.pinX,w=r.pinY,m=t.currentTarget;try{m.setPointerCapture(t.pointerId)}catch{}const U=!(H&&(ve==="upload"||!h)),j=B,J=me=>{const at=(me.clientX-i)/n.width*100,st=(me.clientY-d)/n.height*100,Vt=Math.max(0,Math.min(100,c+at)),Ht=Math.max(0,Math.min(100,w+st));O(Jt=>{const nt=[...Jt],ue=nt[a];if(!ue)return Jt;let _t=ue.lat,Yt=ue.lng;return U&&j&&typeof ue.lat=="number"&&typeof ue.lng=="number"&&(Yt=j.west+Vt/100*(j.east-j.west),_t=j.north-Ht/100*(j.north-j.south)),nt[a]={...ue,pinX:Vt,pinY:Ht,lat:_t,lng:Yt},nt})},ce=me=>{window.removeEventListener("pointermove",J),window.removeEventListener("pointerup",ce),window.removeEventListener("pointercancel",ce);try{m.releasePointerCapture(me.pointerId)}catch{}};window.addEventListener("pointermove",J),window.addEventListener("pointerup",ce),window.addEventListener("pointercancel",ce)},Ma=t=>t.filter(a=>a.type==="photographer").map(a=>({name:a.label||"Position",role:a.role,location:a.label,description:a.notes||"",timeWindow:a.timeWindow,shotStyle:a.shotStyle,equipmentRequired:a.equipmentRequired,shotList:a.shotList,notes:void 0,pinX:typeof a.x=="number"?a.x:50,pinY:typeof a.y=="number"?a.y:50,lat:typeof a.lat=="number"?a.lat:void 0,lng:typeof a.lng=="number"?a.lng:void 0,inviteEmail:"",inviteName:"",staffingTab:"byo",assignmentStatus:"unassigned"})),Ia=t=>({label:t.name,type:"photographer",x:t.pinX,y:t.pinY,lat:t.lat,lng:t.lng,notes:t.description,role:t.role,timeWindow:t.timeWindow,shotStyle:t.shotStyle,equipmentRequired:t.equipmentRequired,shotList:t.shotList,labelEs:t.nameEs,notesEs:t.descriptionEs,shotStyleEs:t.shotStyleEs,equipmentRequiredEs:t.equipmentRequiredEs,shotListEs:t.shotListEs}),Ae=l.useCallback(()=>[...k.map(Ia),...Ee],[k,Ee]);l.useEffect(()=>{if(!o||k.length===0&&Ee.length===0)return;const t=setTimeout(()=>{$e(o,{mapPins:Ae()})},800);return()=>clearTimeout(t)},[o,k,Ee,Ae]);const[je,we]=l.useState(!1),Ut=async()=>o?(await $e(o,{mapPins:Ae(),callTime:pe(S)||void 0,callLocation:W||void 0}),!0):!1,Aa=async()=>{if(!je){we(!0);try{await Ut(),g.success("Changes saved")}catch{g.error("Couldn't save changes â try again")}finally{we(!1)}}},$a=async()=>{if(!(je||Z)){we(!0);try{await Ut()}catch{g.error("Couldn't save changes â try again"),we(!1);return}we(!1),await Dt()}},Oa=!!R.trim()&&!!v&&G>0&&!!W.trim(),Gt=u===0?Oa:!0,za=()=>{if(!Gt){g.error("Fill in name, type, address, and participants to continue.");return}if(u===0&&he.some(t=>t.type==="photographer")){O(Ma(he)),rt(he.filter(t=>t.type!=="photographer")),ge({generalInstructions:"Positions you placed on the map. Edit any position's details below, drag pins to fine-tune, then assign or invite photographers."}),ee.current=!0,N(2);return}N(t=>Math.min(t+1,2))},D="w-full text-base bg-white px-4 py-3 rounded-lg border border-slate-300 focus:border-[var(--m3-primary)] focus:ring-2 focus:ring-[var(--m3-primary)]/20 focus:outline-none placeholder:text-slate-400";return e.jsxs(Da,{children:[e.jsxs("div",{className:"max-w-3xl mx-auto px-4 py-6 pb-28 md:pb-8",children:[e.jsxs("div",{className:"mb-6",children:[e.jsxs("button",{type:"button",onClick:()=>p(o?`/events/${o}
11/dashboard`:"/client-dashboard"),className:"text-sm text-slate-500 hover:text-slate-700 inline-flex items-center gap-1",children:[e.jsx(C,{name:"arrow_back",size:16})," Back to event"]}),e.jsx("h1",{className:"mt-2 text-2xl md:text-3xl font-bold text-slate-900",children:R||"Plan your event logistics"}),e.jsx("p",{className:"text-sm text-slate-500 mt-1",children:"A few concrete details and we'll suggest crew size + draft a plan."})]}),e.jsx("ol",{className:"flex items-center justify-between mb-8","aria-label":"Steps",children:na.map((t,a)=>{const s=a===u,r=a<u,n=a>u;return e.jsxs("li",{className:"flex-1 flex items-center min-w-0",children:[e.jsxs("button",{type:"button",disabled:n,onClick:()=>a<=u&&N(a),className:`flex items-center gap-2 min-w-0 ${n?"opacity-40":""}`,children:[e.jsx("span",{className:`w-7 h-7 shrink-0 rounded-full flex items-center justify-center text-sm font-semibold ${r?"bg-[var(--m3-primary)] text-white":s?"bg-[var(--m3-primary)] text-white ring-4 ring-[var(--m3-primary)]/15":"bg-slate-200 text-slate-600"}`,children:r?e.jsx(C,{name:"check",size:16}):a+1}),e.jsx("span",{className:`hidden sm:inline text-sm font-medium truncate ${s?"text-slate-900":"text-slate-500"}`,children:t})]}),a<na.length-1&&e.jsx("div",{className:`flex-1 h-px mx-2 ${r?"bg-[var(--m3-primary)]":"bg-slate-200"}`})]},t)})}),u===0&&e.jsxs("div",{className:"space-y-5",children:[!ra&&ht.length>0&&e.jsx("section",{className:"rounded-2xl border border-blue-200 bg-blue-50 p-4 md:p-5 shadow-sm",children:e.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsxs("div",{children:[e.jsx("h2",{className:"text-sm font-bold text-blue-900",children:"Start from a saved template"}),e.jsx("p",{className:"mt-0.5 text-xs text-blue-700",children:"Pre-fills photographer positions + notes from a past event. Event-specific fields stay as you set them."})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("select",{className:"rounded-lg border border-blue-300 bg-white px-3 py-2 text-sm font-medium text-slate-900 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 disabled:opacity-50",disabled:bt!==null,defaultValue:"",onChange:t=>{const a=t.target.value;t.target.value="",a&&Ra(a)},children:[e.jsx("option",{value:"",disabled:!0,children:"Pick a templateâ¦"}),ht.map(t=>e.jsx("option",{value:t.id,children:t.name},t.id))]}),bt&&e.jsx("span",{className:"text-[11px] text-blue-700",children:"applyingâ¦"})]})]})}),e.jsxs("section",{className:"bg-white rounded-2xl border border-slate-200 p-5 md:p-6 shadow-sm",children:[e.jsx("h2",{className:"text-lg font-bold text-slate-900 mb-4",children:"Event basics"}),e.jsxs("div",{className:"space-y-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:"Event name"}),e.jsx("input",{type:"text",className:D,placeholder:"e.g. Boston Marathon 2026",value:R,onChange:t=>x(t.target.value)})]}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:"Event type"}),e.jsxs("select",{className:D,value:v,onChange:t=>T(t.target.value),children:[e.jsx("option",{value:"",children:"Select typeâ¦"}),e.jsxs("optgroup",{label:"Endurance / road race",children:[e.jsx("option",{value:"1-mile",children:"1 mile"}),e.jsx("option",{value:"5k",children:"5K"}),e.jsx("option",{value:"5k-10k",children:"5K / 10K"}),e.jsx("option",{value:"10k",children:"10K"}),e.jsx("option",{value:"15k",children:"15K"}),e.jsx("option",{value:"half-marathon",children:"Half marathon"}),e.jsx("option",{value:"marathon",children:"Marathon"}),e.jsx("option",{value:"ultra",children:"Ultra marathon"}),e.jsx("option",{value:"trail",children:"Trail race"}),e.jsx("option",{value:"triathlon",children:"Triathlon"}),e.jsx("option",{value:"cycling",children:"Cycling"}),e.jsx("option",{value:"obstacle",children:"Obstacle course"}),e.jsx("option",{value:"mud-run",children:"Mud run"})]}),e.jsxs("optgroup",{label:"Tournament / team sport",children:[e.jsx("option",{value:"soccer",children:"Soccer"}),e.jsx("option",{value:"basketball",children:"Basketball"}),e.jsx("option",{value:"hockey",children:"Hockey"}),e.jsx("option",{value:"baseball",children:"Baseball"}),e.jsx("option",{value:"softball",children:"Softball"}),e.jsx("option",{value:"volleyball",children:"Volleyball"}),e.jsx("option",{value:"football",children:"Football"}),e.jsx("option",{value:"lacrosse",children:"Lacrosse"}),e.jsx("option",{value:"rugby",children:"Rugby"}),e.jsx("option",{value:"tennis",children:"Tennis"}),e.jsx("option",{value:"pickleball",children:"Pickleball"}),e.jsx("option",{value:"wrestling",children:"Wrestling"}),e.jsx("option",{value:"team-sports",children:"Other team sport"})]}),e.jsxs("optgroup",{label:"Competition (judged / performance)",children:[e.jsx("option",{value:"cheer",children:"Cheer"}),e.jsx("option",{value:"dance",children:"Dance"}),e.jsx("option",{value:"gymnastics",children:"Gymnastics"}),e.jsx("option",{value:"martial-arts",children:"Martial arts"}),e.jsx("option",{value:"figure-skating",children:"Figure skating"}),e.jsx("option",{value:"diving",children:"Diving"}),e.jsx("option",{value:"swimming",children:"Swim meet"}),e.jsx("option",{value:"weightlifting",children:"Weightlifting"}),e.jsx("option",{value:"bodybuilding",children:"Bodybuilding"}),e.jsx("option",{value:"crossfit",children:"CrossFit competition"})]})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:"Participants"}),e.jsx("input",{type:"number",className:D,placeholder:"e.g. 2500",value:G||"",onChange:t=>ke(parseInt(t.target.value)||0)})]})]}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:"Date"}),e.jsx("input",{type:"date",className:D,value:I,onChange:t=>A(t.target.value)})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:"Start time"}),e.jsx("input",{type:"time",className:D,value:S,onChange:t=>K(t.target.value)})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:"Address"}),e.jsx("input",{type:"text",className:D,placeholder:"Full event address",value:W,onChange:t=>_(t.target.value)})]}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-4",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:ba.scheduleLabel||"Waves / heats"}),e.jsx("select",{className:D,value:Se,onChange:t=>f(t.target.value),children:[1,2,3,4,5,6,7,8,10,12,16,20,24].map(t=>{const a=te==="tournament"?t===1?"game":"games":te==="competition"?t===1?"round":"rounds":t===1?"wave (single start)":"waves";return e.jsxs("option",{value:String(t),children:[t," ",a]},t)})})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:"Photos per photographer"}),e.jsxs("select",{className:D,value:b,onChange:t=>y(t.target.value),children:[e.jsx("option",{value:"3000",children:"~3,000 (light coverage)"}),e.jsx("option",{value:"5000-7000",children:"~5,000â7,000 (standard)"}),e.jsx("option",{value:"10000+",children:"10,000+ (heavy coverage)"})]})]})]})]})]}),e.jsxs("section",{className:"bg-white rounded-2xl border border-slate-200 p-5 md:p-6 shadow-sm",children:[e.jsx("h3",{className:"text-base font-bold text-slate-900",children:"How will photos get uploaded?"}),e.jsx("p",{className:"text-xs text-slate-500 mt-1 mb-4",children:"Choose how photographers hand off images after the event."}),e.jsxs("div",{className:"grid sm:grid-cols-2 gap-3",children:[e.jsxs("button",{type:"button",onClick:()=>$("direct"),className:`text-left p-4 rounded-xl border-2 transition-colors ${P==="direct"?"border-[var(--m3-primary)] bg-[var(--m3-primary)]/5":"border-slate-200 hover:border-slate-300"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(C,{name:"cloud_upload",size:20,className:"text-[var(--m3-primary)]"}),e.jsx("span",{className:"font-semibold text-slate-900",children:"Each photographer uploads their own"})]}),e.jsx("p",{className:"text-xs text-slate-600",children:"Photographers sign into the portal and upload directly. Fastest delivery."})]}),e.jsxs("button",{type:"button",onClick:()=>{$("lead"),O(t=>t.some(a=>a.role==="lead")?t:[...t,{name:"Lead / Upload Coordinator",role:"lead",pinX:50,pinY:50,inviteEmail:"",inviteName:"",staffingTab:"marketplace",assignmentStatus:"unassigned"}])},className:`text-left p-4 rounded-xl border-2 transition-colors ${P==="lead"?"border-[var(--m3-primary)] bg-[var(--m3-primary)]/5":"border-slate-200 hover:border-slate-300"}`,children:[e.jsxs("div",{className:"flex items-center gap-2 mb-1",children:[e.jsx(C,{name:"sd_card",size:20,className:"text-[var(--m3-primary)]"}),e.jsx("span",{className:"font-semibold text-slate-900",children:"Memory cards to team lead"})]}),e.jsx("p",{className:"text-xs text-slate-600",children:"Photographers hand cards to the lead, who ingests and uploads. Simpler for new teams."})]})]}),e.jsxs("div",{className:"mt-4",children:[e.jsx("label",{className:"block text-sm font-medium text-slate-700 mb-1.5",children:"Upload deadline (hours after event ends)"}),e.jsx("input",{type:"number",min:"1",max:"168",className:D+" max-w-[140px]",value:q,onChange:t=>F(t.target.value)})]})]}),e.jsxs("section",{className:"bg-white rounded-2xl border border-slate-200 p-5 md:p-6 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-1",children:[e.jsx("h3",{className:"text-base font-bold text-slate-900",children:"Course map"}),e.jsx("span",{className:"text-xs font-medium text-slate-500",children:"Optional"})]}),e.jsx("p",{className:"text-xs text-slate-500 mb-3",children:"Upload a course map OR drop pins on a real map to mark photographer positions and key locations."}),e.jsxs("div",{className:"inline-flex rounded-lg border border-slate-200 bg-slate-50 p-1 mb-4",children:[e.jsx("button",{type:"button",onClick:()=>ae("upload"),className:`text-xs font-semibold px-3 py-1.5 rounded-md transition-colors ${Y==="upload"?"bg-white text-slate-900 shadow-sm":"text-slate-600 hover:text-slate-900"}`,children:"ð Upload Map"}),e.jsx("button",{type:"button",onClick:()=>ae("map"),className:`text-xs font-semibold px-3 py-1.5 rounded-md transition-colors ${Y==="map"?"bg-white text-slate-900 shadow-sm":"text-slate-600 hover:text-slate-900"}`,children:"ðº Use Live Map"})]}),Y==="upload"?e.jsxs(e.Fragment,{children:[e.jsx("input",{ref:It,type:"file",className:"hidden",accept:".pdf,.jpg,.jpeg,.png,.gpx",onChange:t=>{var s;const a=(s=t.target.files)==null?void 0:s[0];a&&Ot(a)}}),e.jsx("button",{type:"button",onClick:()=>{var t;return(t=It.current)==null?void 0:t.click()},onDragOver:t=>{t.preventDefault(),t.stopPropagation()},onDrop:t=>{var s;t.preventDefault(),t.stopPropagation();const a=(s=t.dataTransfer.files)==null?void 0:s[0];a&&Ot(a)},className:"w-full border-2 border-dashed border-slate-300 rounded-xl p-6 hover:border-[var(--m3-primary)]/50 transition-colors text-center",children:M?e.jsxs("div",{children:[e.jsx(C,{name:"check_circle",size:28,className:"text-green-600 mx-auto mb-1"}),e.jsx("p",{className:"text-sm font-medium text-slate-900",children:M.name}),e.jsxs("p",{className:"text-xs text-slate-500",children:[(M.size/1024/1024).toFixed(1)," MB · Tap to replace"]})]}):e.jsxs("div",{children:[e.jsx(C,{name:"file_upload",size:28,className:"text-slate-400 mx-auto mb-1"}),e.jsx("p",{className:"text-sm font-medium text-slate-900",children:"Drop a course map or tap to browse"}),e.jsx("p",{className:"text-xs text-slate-500 mt-0.5",children:"PDF, JPG, or GPX up to 25 MB"})]})})]}):e.jsx(ds,{pins:he,onPinsChange:ze,address:W,coordinates:h?[h.lat,h.lng]:null})]})]}),u===1&&e.jsxs("div",{className:"space-y-5",children:[e.jsxs("section",{className:"bg-white rounded-2xl border border-slate-200 p-5 md:p-6 shadow-sm",children:[e.jsxs("div",{className:"flex items-end justify-between gap-3 mb-1",children:[e.jsx("h3",{className:"text-base font-bold text-slate-900",children:"Choose your photographer positions"}),e.jsxs("div",{className:"text-right",children:[e.jsx("span",{className:"text-3xl font-bold text-slate-900 leading-none",children:Me}),e.jsx("span",{className:"ml-1 text-sm text-slate-500",children:"picked"})]})]}),e.jsxs("p",{className:"text-xs text-slate-500 mb-4",children:["Suggested for ",G.toLocaleStr
11ing()," ",te==="competition"?"competitors":"participants",":"," ",e.jsxs("button",{type:"button",className:"font-medium text-[var(--m3-primary)] hover:underline",onClick:()=>{if(ne.length===0)return;const t=ne.find(n=>n.role==="lead"),a=ne.filter(n=>n.id!==(t==null?void 0:t.id)),s={};t&&(s[t.id]=1);let r=Math.max(0,Ie-(t?1:0));a.forEach((n,i)=>{const d=Math.ceil(r/Math.max(1,a.length-i));d>0&&(s[n.id]=d,r-=d)}),dt(s)},children:["~",Ie," photographers â auto-fill"]})]}),ne.length===0?e.jsx("p",{className:"text-sm text-slate-400 italic",children:"Loading positionsâ¦"}):e.jsx("ul",{className:"divide-y divide-slate-100",children:ne.map(t=>{const a=oe[t.id]||0,s=r=>dt(n=>({...n,[t.id]:Math.max(0,Math.min(40,r))}));return e.jsxs("li",{className:"flex items-center gap-3 py-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("span",{className:"text-sm font-semibold text-slate-900 truncate",children:t.name}),e.jsx("span",{className:"text-[10px] uppercase tracking-wider text-slate-400",children:t.role})]}),t.description&&e.jsx("p",{className:"text-xs text-slate-500 line-clamp-1",children:t.description})]}),e.jsxs("div",{className:"flex items-center gap-2 shrink-0",children:[e.jsx("button",{type:"button",onClick:()=>s(a-1),disabled:a<=0,className:"w-9 h-9 rounded-lg bg-slate-100 hover:bg-slate-200 disabled:opacity-40 text-slate-700 flex items-center justify-center","aria-label":`Fewer ${t.name}`,children:e.jsx(C,{name:"remove",size:18})}),e.jsx("input",{type:"number",min:0,max:40,inputMode:"numeric",value:a,onChange:r=>{const n=parseInt(r.target.value,10);s(Number.isFinite(n)?n:0)},"aria-label":`${t.name} quantity`,className:"w-12 text-center text-lg font-bold text-slate-900 bg-transparent focus:outline-none focus:bg-slate-50 rounded"}),e.jsx("button",{type:"button",onClick:()=>s(a+1),disabled:a>=40,className:"w-9 h-9 rounded-lg bg-slate-100 hover:bg-slate-200 disabled:opacity-40 text-slate-700 flex items-center justify-center","aria-label":`More ${t.name}`,children:e.jsx(C,{name:"add",size:18})})]})]},t.id)})})]}),e.jsxs("section",{className:"bg-white rounded-2xl border border-slate-200 p-5 md:p-6 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"text-base font-bold text-slate-900",children:"Custom roles"}),e.jsx("p",{className:"text-xs text-slate-500 mt-0.5",children:"Optional. Add positions outside the standard split (sponsor booth, drone pilot, etc.)."})]}),!Fe&&e.jsx("button",{type:"button",onClick:()=>Be(!0),className:"text-xs font-semibold text-[var(--m3-primary)] hover:underline whitespace-nowrap",children:"+ Add role"})]}),se.length>0&&e.jsx("ul",{className:"space-y-2 mb-3",children:se.map(t=>e.jsxs("li",{className:"flex items-center justify-between gap-3 bg-slate-50 rounded-lg px-3 py-2",children:[e.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[e.jsx(C,{name:"person",size:18,className:"text-slate-500 shrink-0"}),e.jsx("span",{className:"text-sm font-medium text-slate-800 truncate",children:t.name}),e.jsxs("span",{className:"text-xs text-slate-500 shrink-0",children:["Ã",t.count]})]}),e.jsx("button",{type:"button",onClick:()=>ya(t.id),className:"text-xs text-red-600 hover:underline shrink-0",children:"Remove"})]},t.id))}),Fe&&e.jsxs("div",{className:"bg-slate-50 rounded-lg p-3 space-y-3",children:[e.jsxs("div",{className:"grid grid-cols-[1fr_auto] gap-2",children:[e.jsx("input",{type:"text",autoFocus:!0,placeholder:"e.g. Sponsor booth, Drone pilot, VIP tent",value:ct,onChange:t=>De(t.target.value),onKeyDown:t=>{t.key==="Enter"&&Bt()},className:D}),e.jsx("input",{type:"number",min:"1",max:"20",value:mt,onChange:t=>We(parseInt(t.target.value)||1),className:D+" w-20 text-center"})]}),e.jsxs("div",{className:"flex items-center justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>{Be(!1),De(""),We(1)},className:"text-sm font-medium text-slate-600 px-3 py-1.5 rounded-lg hover:bg-slate-200",children:"Cancel"}),e.jsx("button",{type:"button",onClick:Bt,className:"text-sm font-semibold text-white bg-[var(--m3-primary)] px-4 py-1.5 rounded-lg hover:opacity-90",children:"Add"})]})]}),se.length===0&&!Fe&&e.jsx("p",{className:"text-xs text-slate-400 italic",children:"No custom roles yet."})]})]}),u===2&&e.jsxs("div",{className:"space-y-5",children:[xe&&e.jsxs("section",{className:"bg-white rounded-2xl border border-slate-200 p-6 text-center shadow-sm",children:[e.jsxs("div",{className:"inline-flex items-center gap-3 text-slate-700",children:[e.jsx(C,{name:"autorenew",size:22,className:"animate-spin text-[var(--m3-primary)]"}),e.jsxs("p",{className:"text-sm font-medium",children:["Drafting your plan⦠",da,"s"]})]}),e.jsx("p",{className:"text-xs text-slate-500 mt-2",children:"Typically takes 30-90s. You can leave this page; we'll save the result."})]}),wt&&!xe&&e.jsxs("section",{className:"bg-red-50 border border-red-200 rounded-2xl p-4 flex items-start gap-3",children:[e.jsx(C,{name:"error_outline",size:20,className:"text-red-600 shrink-0 mt-0.5"}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsx("p",{className:"text-sm font-semibold text-red-800",children:wt}),e.jsx("button",{type:"button",onClick:()=>void et(),className:"mt-1 text-xs font-semibold text-red-700 hover:underline",children:"Try again"})]})]}
11),E&&!xe&&e.jsxs(e.Fragment,{children:[(E.generalInstructions||E.weatherBackupPlan||E.meetingTime)&&e.jsxs("section",{className:"bg-white rounded-2xl border border-slate-200 p-5 md:p-6 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between mb-3",children:[e.jsx("h2",{className:"text-lg font-bold text-slate-900",children:"Day-of plan"}),e.jsx("button",{type:"button",onClick:()=>{ee.current=!1,et()},disabled:xe,className:"text-xs font-medium text-[var(--m3-primary)] hover:underline disabled:opacity-40",children:"Regenerate"})]}),e.jsxs("div",{className:"space-y-3 text-sm text-slate-700",children:[E.meetingTime&&e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(C,{name:"schedule",size:18,className:"text-slate-500 mt-0.5 shrink-0"}),e.jsxs("p",{children:[e.jsxs("span",{className:"font-semibold",children:["Meet at ",ta(String(E.meetingTime))]}),E.meetingLocation?` â ${String(E.meetingLocation)}`:""]})]}),E.parkingInstructions&&e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(C,{name:"local_parking",size:18,className:"text-slate-500 mt-0.5 shrink-0"}),e.jsx("p",{children:String(E.parkingInstructions)})]}),E.generalInstructions&&e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(C,{name:"info",size:18,className:"text-slate-500 mt-0.5 shrink-0"}),e.jsx("p",{className:"whitespace-pre-line",children:String(E.generalInstructions)})]}),E.weatherBackupPlan&&e.jsxs("div",{className:"flex items-start gap-2",children:[e.jsx(C,{name:"thunderstorm",size:18,className:"text-slate-500 mt-0.5 shrink-0"}),e.jsxs("p",{children:[e.jsx("span",{className:"font-semibold",children:"Weather backup: "}),String(E.weatherBackupPlan)]})]})]})]}),e.jsxs("section",{className:"bg-white rounded-2xl border border-slate-200 p-5 md:p-6 shadow-sm",children:[e.jsxs("div",{className:"flex items-center justify-between gap-3 mb-3",children:[e.jsx("h2",{className:"text-lg font-bold text-slate-900",children:bs(te,v)}),e.jsxs("span",{className:"text-xs text-slate-500 whitespace-nowrap",children:[k.length," pin",k.length===1?"":"s"]})]}),H&&h&&e.jsxs("div",{className:"inline-flex gap-1 mb-3 bg-slate-100 rounded-lg p-1 text-xs font-semibold",children:[e.jsx("button",{type:"button",onClick:()=>Le("upload"),className:`px-3 py-1.5 rounded-md transition-colors ${ve==="upload"?"bg-white text-slate-900 shadow-sm":"text-slate-500 hover:text-slate-700"}`,children:"Uploaded map"}),e.jsx("button",{type:"button",onClick:()=>Le("live"),className:`px-3 py-1.5 rounded-md transition-colors ${ve==="live"?"bg-white text-slate-900 shadow-sm":"text-slate-500 hover:text-slate-700"}`,children:"Live map"})]}),e.jsx("div",{ref:Lt,className:"relative w-full aspect-[16/9] rounded-xl overflow-hidden bg-gradient-to-br from-slate-100 via-blue-50 to-emerald-50 border border-slate-200 select-none",children:H&&(ve==="upload"||!h)?e.jsxs(e.Fragment,{children:[e.jsx("img",{src:H,alt:"Course map",draggable:!1,className:"absolute inset-0 w-full h-full object-contain pointer-events-none"}),k.map((t,a)=>{const{x:s,y:r}=$t(t,"upload");return e.jsxs("div",{onPointerDown:n=>La(n,a),title:"Drag to reposition",className:"absolute -translate-x-1/2 -translate-y-full flex flex-col items-center cursor-grab active:cursor-grabbing",style:{left:`${s}%`,top:`${r}%`,touchAction:"none"},children:[e.jsx("span",{className:"px-2 py-0.5 text-[10px] font-semibold bg-slate-900 text-white rounded shadow whitespace-nowrap max-w-[120px] truncate pointer-events-none",children:t.name}),e.jsx("span",{className:"w-3 h-3 -mt-0.5 rounded-full bg-[var(--m3-primary)] ring-2 ring-white shadow pointer-events-none"})]},a)}),Q.map((t,a)=>{const{x:s,y:r}=$t(t,"upload");return e.jsxs("button",{type:"button",onClick:()=>tt(a),title:`AI recommended: ${t.name} â click to add to your plan`,className:"absolute -translate-x-1/2 -translate-y-full flex flex-col items-center cursor-pointer opacity-80 hover:opacity-100",style:{left:`${s}%`,top:`${r}%`},children:[e.jsxs("span",{className:"px-2 py-0.5 text-[10px] font-semibold bg-white text-slate-700 rounded shadow whitespace-nowrap max-w-[140px] truncate pointer-events-none border border-dashed border-slate-400",children:["AI: ",t.name]}),e.jsx("span",{className:"w-3 h-3 -mt-0.5 rounded-full bg-white ring-2 ring-d
11ashed border-2 border-dashed border-slate-500 pointer-events-none"})]},`ai-${a}`)})]}):h&&(ve==="live"||!H)?e.jsxs(as,{center:[h.lat,h.lng],zoom:17,scrollWheelZoom:!0,className:"absolute inset-0 w-full h-full",children:[e.jsx(ss,{attribution:'© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"}),e.jsx(js,{bounds:B?[[B.south,B.west],[B.north,B.east]]:null}),k.map((t,a)=>typeof t.lat!="number"||typeof t.lng!="number"?null:e.jsx(Zt,{position:[t.lat,t.lng],draggable:!0,icon:vs,eventHandlers:{dragend:s=>{const r=s.target.getLatLng();O(n=>{const i=[...n],d=i[a];return d&&(i[a]={...d,lat:r.lat,lng:r.lng}),i})}},children:e.jsx(ea,{permanent:!0,direction:"top",offset:[0,-10],className:"logistics-pin-label",children:t.name})},`pos-${a}-${t.lat}-${t.lng}`)),Q.map((t,a)=>typeof t.lat!="number"||typeof t.lng!="number"?null:e.jsx(Zt,{position:[t.lat,t.lng],icon:ys,eventHandlers:{click:()=>tt(a)},children:e.jsxs(ea,{permanent:!0,direction:"top",offset:[0,-10],className:"logistics-pin-label",children:["AI: ",t.name]})},`ai-${a}-${t.lat}-${t.lng}`))]}):null}),e.jsx("p",{className:"text-xs text-slate-500 mt-2",children:"Scroll or pinch to zoom · drag the map to pan · drag a pin to reposition it. Backdrop is your uploaded course map if available, otherwise a live street map centered on the event address. Initial pin placement is by label heuristic (start â left, finish â right, mile-N interpolated) â fine-tune by dragging."})]}),Q.length>0&&e.jsxs("section",{className:"rounded-2xl border-2 border-dashed border-slate-300 bg-slate-50 p-5",children:[e.jsxs("div",{className:"mb-3 flex flex-wrap items-start justify-between gap-3",children:[e.jsxs("div",{children:[e.jsxs("h2",{className:"text-base font-bold text-slate-900",children:["AI recommended ",Q.length," spot",Q.length===1?"":"s"]}),e.jsxs("p",{className:"mt-0.5 text-xs text-slate-600",children:["Review the suggestions below and click ",e.jsx("span",{className:"font-semibold",children:"Add to plan"})," to keep one, or ",e.jsx("span",{className:"font-semibold",children:"Add all"})," to keep them all. Nothing is saved until you accept."]})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-2",children:[e.jsx("button",{type:"button",onClick:()=>Sa(),className:"rounded-lg bg-[var(--m3-primary)] px-3 py-1.5 text-xs font-semibold text-white shadow-sm hover:opacity-90",children:"Add all"}),e.jsx("button",{type:"button",onClick:()=>Ca(),className:"rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-xs font-semibold text-slate-600 hover:bg-slate-50",children:"Dismiss all"})]})]}),e.jsx("ul",{className:"space-y-2",children:Q.map((t,a)=>e.jsxs("li",{className:"flex flex-wrap items-start gap-3 rounded-xl border border-slate-200 bg-white px-3 py-2",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex flex-wrap items-baseline gap-2",children:[e.jsx("span",{className:"text-sm font-semibold text-slate-900 truncate",children:t.name}),t.role&&e.jsx("span",{className:"text-[10px] uppercase tracking-wider text-slate-500",children:t.role}),t.timeWindow&&e.jsx("span",{className:"text-[11px] text-slate-500",children:ta(t.timeWindow)})]}),t.location&&e.jsx("div",{className:"mt-0.5 text-xs text-slate-600 truncate",children:t.location}),t.description&&e.jsx("div",{className:"mt-0.5 text-xs text-slate-500 line-clamp-2",children:t.description})]}),e.jsxs("div",{className:"flex shrink-0 items-center gap-1.5",children:[e.jsx("button",{type:"button",onClick:()=>tt(a),className:"rounded-md bg-[var(--m3-primary)] px-2.5 py-1 text-xs font-semibold text-white hover:opacity-90",children:"Add to plan"}),e.jsx("button",{type:"button",onClick:()=>Ea(a),className:"rounded-md border border-slate-300 px-2.5 py-1 text-xs font-medium text-slate-600 hover:bg-slate-50",children:"Dismiss"})]})]},a))})]}),L.filter(t=>!t.assignedPosition).length>0&&e.jsxs("section",{className:"rounded-2xl border border-orange-200 bg-orange-50 p-5",children:[e.jsx("div",{className:"mb-3 flex items-start justify-between gap-3",children:e.jsxs("div",{children:[e.jsxs("h2",{className:"text-base font-bold text-orange-900",children:[L.filter(t=>!t.assignedPosition).length," hire",L.filter(t=>!t.assignedPosition).length===1?"":"s"," need",L.filter(t=>!t.assignedPosition).length===1?"s":""," placement"]}),e.jsx("p",{className:"mt-0.5 text-xs text-orange-700",children:"Assign each photographer to a position below so they show up on the map."})]})}),e.jsx("ul",{className:"space-y-2",children:L.filter(t=>!t.assignedPosition).map(t=>{const a=`${t.firstName||""} ${t.lastName||""}`.trim()||"Photographer";return e.jsxs("li",{className:"flex flex-wrap items-center justify-between gap-3 rounded-xl bg-white p-3 shadow-sm ring-1 ring-orange-100",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsx("p",{className:"truncate text-sm font-semibold text-slate-900",children:a}),t.email&&e.jsx("p",{className:"truncate text-[11px] text-slate-500",children:e.jsx("a",{href:`mailto:${t.email}`,className:"hover:text-slate-700 hover:underline",children:t.email})}),t.phone&&e.jsx("p",{className:"truncate text-[11px] text-slate-500",children:e.jsx("a",{href:`tel:${t.phone}`,className:"hover:text-slate-700 hover:underline",children:t.phone})})]}),e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsxs("select",{className:"rounded-lg border border-slate-300 bg-white px-3 py-1.5 text-xs font-medium text-slate-900 shadow-sm focus:border-orange-400 focus:outline-none focus:ring-2 focus:ring-orange-200 disabled:opacity-50",disabled:ut===t.id||k.length===0,defaultValue:"",onChange:s=>{const r=s.target.value;r&&Ta(t.id,r),s.target.value=""},children:[e.jsx("option",{value:"",disabled:!0,children:k.length===0?"N
11o positions yet":"Assign toâ¦"}),k.map((s,r)=>e.jsx("option",{value:s.name,children:s.name},`${s.name}-${r}`))]}),ut===t.id&&e.jsx("span",{className:"text-[10px] text-orange-700",children:"savingâ¦"})]})]},t.id)})}),k.length===0&&e.jsx("p",{className:"mt-3 text-[11px] italic text-orange-700",children:"Generate or add positions below first, then come back to assign."})]}),Te&&L.length>0&&e.jsxs("section",{className:"rounded-2xl border border-emerald-200 bg-white p-5 shadow-sm",children:[e.jsx("div",{className:"mb-3 flex items-start justify-between gap-3",children:e.jsxs("div",{children:[e.jsx("h2",{className:"text-base font-bold text-slate-900",children:"Photo Team â contacts"}),e.jsxs("p",{className:"mt-0.5 text-xs text-slate-500",children:[L.length," member",L.length===1?"":"s",". Tap email or phone to contact."]})]})}),e.jsx("div",{className:"overflow-x-auto",children:e.jsxs("table",{className:"min-w-full text-sm",children:[e.jsx("thead",{className:"border-b border-slate-200 text-left text-[11px] font-semibold uppercase tracking-wide text-slate-500",children:e.jsxs("tr",{children:[e.jsx("th",{className:"px-2 py-2",children:"Name"}),e.jsx("th",{className:"px-2 py-2",children:"Role / Position"}),e.jsx("th",{className:"px-2 py-2",children:"Status"}),e.jsx("th",{className:"px-2 py-2",children:"Email"}),e.jsx("th",{className:"px-2 py-2",children:"Phone"})]})}),e.jsx("tbody",{className:"divide-y divide-slate-100",children:[...L].sort((t,a)=>{const s={confirmed:0,pending:1,"not-invited":2,declined:3};return(s[t.status]??9)-(s[a.status]??9)}).map(t=>{const a=`${t.firstName||""} ${t.lastName||""}`.trim()||"Photographer",s=t.assignedPosition||t.customRole||t.role||"â",n={confirmed:"bg-emerald-100 text-emerald-800",pending:"bg-amber-100 text-amber-800",declined:"bg-red-100 text-red-800","not-invited":"bg-slate-100 text-slate-600"}[t.status]??"bg-slate-100 text-slate-600";return e.jsxs("tr",{className:"hover:bg-slate-50",children:[e.jsx("td",{className:"px-2 py-2 font-medium text-slate-900",children:a}),e.jsx("td",{className:"px-2 py-2 text-slate-700",children:s}),e.jsx("td",{className:"px-2 py-2",children:e.jsx("span",{className:`inline-block rounded-full px-2 py-0.5 text-[10px] font-semibold ${n}`,children:t.status})}),e.jsx("td",{className:"px-2 py-2 text-slate-700",children:t.email?e.jsx("a",{href:`mailto:${t.email}`,className:"text-blue-600 hover:underline",children:t.email}):e.jsx("span",{className:"text-slate-300",children:"â"})}),e.jsx("td",{className:"px-2 py-2 text-slate-700",children:t.phone?e.jsx("a",{href:`tel:${t.phone}`,className:"text-blue-600 hover:underline",children:t.phone}):e.jsx("span",{className:"text-slate-300",children:"â"})})]},t.id)})})]})})]}),e.jsxs("section",{className:"space-y-3",children:[e.jsx("h2",{className:"text-lg font-bold text-slate-900",children:"Photographer positions"}),k.map((t,a)=>{var s,r,n,i;return e.jsxs("div",{className:"bg-white rounded-2xl border border-slate-200 p-5 shadow-sm",children:[e.jsxs("div",{className:"flex items-start justify-between gap-3 mb-3",children:[e.jsxs("div",{className:"min-w-0 flex-1",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsx("input",{type:"text",value:t.name,onChange:d=>Pa(a,d.target.value),"aria-label":"Position name",placeholder:"Position name",className:"text-base font-bold text-slate-900 bg-transparent border-0 border-b border-dashed border-slate-200 hover:border-slate-400 focus:border-[var(--m3-primary)] focus:outline-none focus:ring-0 px-0 py-0.5 min-w-0 flex-1"}),t.role&&e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider px-2 py-0.5 rounded bg-slate-100 text-slate-600 shrink-0",children:t.role})]}),t.location&&e.jsx("p",{className:"text-xs text-slate-500 mt-0.5",children:t.location})]}),e.jsx("span",{className:`text-[10px] font-semibold uppercase tracking-wider px-2 py-1 rounded shrink-0 ${t.assignmentStatus==="invited"?"bg-emerald-100 text-emerald-700":t.assignmentStatus==="inviting"?"bg-amber-100 text-amber-700":"bg-slate-100 text-slate-500"}`,children:t.assignmentStatus==="invited"?"Invited":t.assignmentStatus==="inviting"?"Sendingâ¦":"Unassigned"})]}),(()=>{const d=L.filter(c=>(c.assignedPosition||"").trim()===t.name.trim());return d.length>0?e.jsxs("div",{className:"mb-3 flex flex-wrap items-center gap-1.5",children:[e.jsx("span",{className:"text-[10px] font-semibold uppercase tracking-wider text-slate-400",children:"Assigned"}),d.map(c=>e.jsxs("span",{className:"inline-flex items-center gap-1 text-xs font-medium px-2 py-0.5 rounded-full bg-[var(--m3-primary)]/10 text-[var(--m3-primary)]",children:[e.jsx(C,{name:"person",size:12}),`${c.firstName||""} ${c.lastName||""}`.trim()||c.email||"Photographer"]},c.id))]}):null})(),e.jsx("textarea",{rows:3,value:t.description||"",onChange:d=>ye(a,"description",d.target.value),className:D+" text-sm leading-relaxed",placeholder:"Assignment notes"}),(((s=t.equipmentRequired)==null?void 0:s.length)||((r=t.shotList)==null?void 0:r.length))&&e.jsxs("div",{className:"grid sm:grid-cols-2 gap-3 mt-3",children:[(n=t.equipmentRequired)!=null&&n.length?e.jsxs("div",{className:"bg-slate-50 rounded-lg p-3",children:[e.jsx("p",{className:"text-[11px] font-bold uppercase tracking-wider text-slate-500 mb-1",children:"What to bring"}),e.jsx("ul",{className:"text-xs text-slate-700 space-y-0.5",children:t.equipmentRequired.map((d,c
11)=>e.jsxs("li",{className:"flex items-start gap-1.5",children:[e.jsx("span",{className:"text-slate-400 mt-0.5",children:"â¢"}),e.jsx("span",{children:d})]},c))})]}):null,(i=t.shotList)!=null&&i.length?e.jsxs("div",{className:"bg-slate-50 rounded-lg p-3",children:[e.jsx("p",{className:"text-[11px] font-bold uppercase tracking-wider text-slate-500 mb-1",children:"Shot list"}),e.jsx("ul",{className:"text-xs text-slate-700 space-y-0.5",children:t.shotList.map((d,c)=>e.jsxs("li",{className:"flex items-start gap-1.5",children:[e.jsx("span",{className:"text-slate-400 mt-0.5",children:"â¢"}),e.jsx("span",{children:d})]},c))})]}):null]}),e.jsxs("div",{className:"mt-4 pt-4 border-t border-slate-100",children:[e.jsxs("div",{className:"flex gap-1 mb-3 bg-slate-100 rounded-lg p-1",children:[e.jsx("button",{type:"button",onClick:()=>ye(a,"staffingTab","byo"),className:`flex-1 text-xs font-semibold py-1.5 rounded-md transition-colors ${t.staffingTab==="byo"?"bg-white text-slate-900 shadow-sm":"text-slate-500 hover:text-slate-700"}`,children:"Bring my own"}),e.jsx("button",{type:"button",onClick:()=>ye(a,"staffingTab","marketplace"),className:`flex-1 text-xs font-semibold py-1.5 rounded-md transition-colors ${t.staffingTab==="marketplace"?"bg-white text-slate-900 shadow-sm":"text-slate-500 hover:text-slate-700"}`,children:"Book from marketplace"})]}),t.staffingTab==="byo"?e.jsxs("div",{className:"grid sm:grid-cols-[1fr_1fr_auto] gap-2",children:[e.jsx("input",{type:"text",placeholder:"Name",value:t.inviteName,onChange:d=>ye(a,"inviteName",d.target.value),disabled:t.assignmentStatus!=="unassigned",className:D+" text-sm"}),e.jsx("input",{type:"email",placeholder:"[email protected]",value:t.inviteEmail,onChange:d=>ye(a,"inviteEmail",d.target.value),disabled:t.assignmentStatus!=="unassigned",className:D+" text-sm"}),e.jsx("button",{type:"button",onClick:()=>void Na(a),disabled:t.assignmentStatus!=="unassigned"||!t.inviteEmail.trim(),className:"text-sm font-semibold text-white bg-[var(--m3-primary)] px-4 py-2.5 rounded-lg hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed whitespace-nowrap",children:t.assignmentStatus==="invited"?"Sent":t.assignmentStatus==="inviting"?"Sendingâ¦":"Invite"})]}):e.jsxs("div",{className:"bg-slate-50 rounded-lg p-3 space-y-2",children:[de&&e.jsxs("div",{className:"text-center py-3 text-xs text-slate-500 inline-flex items-center justify-center gap-2 w-full",children:[e.jsx(C,{name:"autorenew",size:16,className:"animate-spin"}),"Searching photographersâ¦"]}),!de&&qe.length===0&&Qe&&e.jsxs("div",{className:"text-center py-3",children:[e.jsx(C,{name:"search_off",size:20,className:"text-slate-400 mx-auto mb-1"}),e.jsxs("p",{className:"text-xs text-slate-500",children:["No photographers found",h?" within 100 miles":"",v?` for ${v}`:"","."]}),e.jsx("button",{type:"button",onClick:()=>p(`/post-job?eventId=${o||""}`),className:"mt-2 text-xs font-semibold text-[var(--m3-primary)] hover:underline",children:"Post a job â"})]}),!de&&qe.slice(0,5).map(d=>{var c,w;return e.jsxs("div",{className:"flex items-center gap-3 bg-white rounded-lg p-2 ring-1 ring-slate-200",children:[d.profilePhotoUrl?e.jsx("img",{src:d.profilePhotoUrl,alt:"",className:"w-10 h-10 rounded-full object-cover shrink-0"}):e.jsx("div",{className:"w-10 h-10 rounded-full bg-slate-200 flex items-center justify-center text-xs font-semibold text-slate-500 shrink-0",children:(((c=d.firstName)==null?void 0:c[0])||"?")+(((w=d.lastName)==null?void 0:w[0])||"")}),e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("p",{className:"text-sm font-semibold text-slate-900 truncate",children:[d.firstName," ",d.lastName]}),e.jsxs("p",{className:"text-[11px] text-slate-500 truncate",children:[d.hourlyRate?`$${d.hourlyRate}/hr · `:"",d.city||"",d.state?`, ${d.state}`:"",typeof d.distanceMiles=="number"?` · ${d.distanceMiles.toFixed(1)} mi`:""]})]}),e.jsx("button",{type:"button",onClick:()=>p(`/post-job?eventId=${o||""}&photographerId=${d.id}&role=${t.role||""}`),className:"text-xs font-semibold text-white bg-[var(--m3-primary)] px-3 py-1.5 rounded-md hover:opacity-90 shrink-0",children:"Hire"})]},d.id)}),!de&&qe.length>5&&e.jsxs("button",{type:"button",onClick:()=>p(`/post-job?eventId=${o||""}`),className:"w-full text-xs font-semibold text-[var(--m3-primary)] hover:underline pt-1",children:["Browse all ",qe.length," matches â"]})]})]})]},a)})]}),e.jsxs("p",{className:"text-xs text-slate-500 text-center pt-2",children:["Need pixel-level pin control?"," ",e.jsx("button",{type:"button",onClick:()=>p(`/events/${o}/logistics/editor`),className:"font-semibold text-[var(--m3-primary)] hover:underline",children:"Open in Editor"})]})]})]})]}),e.jsx("div",{className:"fixed bottom-20 lg:bottom-0 inset-x-0 z-30 bg-white/95 backdrop-blur border-t border-slate-200 md:static md:bottom-auto md:bg-transparent md:border-0",children:e.jsxs("div",{className:"max-w-3xl mx-auto px-4 py-3 md:py-4 flex items-center justify-between gap-3",style:{paddingBottom:"max(0.75rem, env(safe-area-inset-bottom))"},children:[e.jsx("button",{type:"button",onClick:()=>
11{if(u===2&&he.some(t=>t.type==="photographer")){ze(Ae()),N(0);return}u>0?N(t=>t-1):p(o?`/events/${o}/dashboard`:"/client-dashboard")},className:"text-sm font-medium text-slate-600 px-4 py-2.5 rounded-xl hover:bg-slate-100",children:u>0?"Back":"Cancel"}),u===2?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("button",{type:"button",onClick:()=>{Ue(R?`${R} template`:""),Ce(!0)},disabled:k.length===0,title:k.length===0?"Add positions before saving":"Save this plan as a template",className:"text-sm font-medium text-slate-700 px-4 py-2.5 rounded-xl border border-slate-300 hover:bg-slate-50 disabled:opacity-40 disabled:cursor-not-allowed",children:"Save as template"}),!Te&&e.jsx("button",{type:"button",onClick:()=>void qa(),className:"text-sm font-medium text-slate-700 px-4 py-2.5 rounded-xl border border-slate-300 hover:bg-slate-50",children:"Save draft"}),e.jsx("div",{className:"text-xs text-slate-500 mr-1 whitespace-nowrap",children:L.length===0?`0 of ${k.length} position${k.length===1?"":"s"} staffed`:`${L.length} on team`}),Te?e.jsxs(e.Fragment,{children:[e.jsxs("button",{type:"button",onClick:()=>void Aa(),disabled:je||Z,title:"Save your edits to this logistics plan",className:"inline-flex items-center gap-2 text-sm font-semibold px-5 py-2.5 rounded-xl bg-[var(--m3-primary)] text-white hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed",children:[je?"Savingâ¦":"Save Changes",e.jsx(C,{name:"save",size:16})]}),e.jsxs("button",{type:"button",onClick:()=>void $a(),disabled:je||Z||L.length===0,title:L.length===0?"No hired photographers to update yet":"Save edits and re-send the updated brief to your hired photographers",className:"inline-flex items-center gap-2 text-sm font-semibold px-5 py-2.5 rounded-xl bg-emerald-600 text-white hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed",children:[Z?"Updatingâ¦":"Save & Update Hired Photographers",e.jsx(C,{name:"send",size:16})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("button",{type:"button",onClick:()=>void Dt(),disabled:Z||z||!E||L.length===0,title:L.length===0?"Add at least one photographer (Bring my own or Book from marketplace) on a position card first":"Send invite emails to each team member",className:"inline-flex items-center gap-2 text-sm font-semibold px-5 py-2.5 rounded-xl bg-[var(--m3-primary)] text-white hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed",children:[Z?"Publishingâ¦":L.length===0?"Add team to publish":"Publish",e.jsx(C,{name:"send",size:16})]}),e.jsxs("button",{type:"button",onClick:()=>{!re.trim()&&Ft>0&&Et(String(Ft)),Re(!0)},disabled:Z||z||!E,title:"Publish logistics and post photographer listing(s) to the marketplace",className:"inline-flex items-center gap-2 text-sm font-semibold px-5 py-2.5 rounded-xl bg-orange-500 text-white hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed",children:[z?"Postingâ¦":"Publish + Post Jobs",e.jsx(C,{name:"work",size:16})]})]})]}):e.jsxs("button",{type:"button",onClick:za,disabled:!Gt,className:"inline-flex items-center gap-2 text-sm font-semibold text-white bg-[var(--m3-primary)] px-5 py-2.5 rounded-xl hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed",children:["Continue",e.jsx(C,{name:"arrow_forward",size:16})]})]})}),la&&e.jsx("div",{className:"fixed inset-0 z-[80] flex items-center justify-center overflow-y-auto bg-black/60 p-4",onClick:t=>{t.target===t.currentTarget&&!ie&&Ce(!1)},children:e.jsxs("div",{className:"my-auto w-full max-w-md rounded-2xl bg-white p-6 shadow-xl",children:[e.jsx("h3",{className:"text-lg font-bold text-slate-900",children:"Save logistics as template"}),e.jsx("p",{className:"mt-1 text-sm text-slate-600",children:"Reuse this plan's photographer positions and notes on future events. Event-specific fields (name, date, address, team) won't be saved."}),e.jsx("label",{className:"mt-4 block text-sm font-medium text-slate-700",children:"Template name"}),e.jsx("input",{type:"text",autoFocus:!0,className:"mt-1 w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200",placeholder:"e.g. 10K Race â 3 photographers",value:Pe,onChange:t=>Ue(t.target.value),onKeyDown:t=>{t.key==="Enter"&&Pe.trim()&&!ie&&Wt()},disabled:ie}),e.jsxs("div",{className:"mt-5 flex items-center justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>Ce(!1),disabled:ie,className:"rounded-xl px-4 py-2 text-sm font-medium text-slate-600 hover:bg-slate-100 disabled:opacity-40",children:"Cancel"}),e.jsx("button",{type:"button",onClick:()=>void Wt(),disabled:ie||!Pe.trim(),className:"rounded-xl bg-[var(--m3-primary)] px-5 py-2 text-sm font-semibold text-white hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed",children:ie?"Savingâ¦":"Save template"})]})]})}),ca&&e.jsx("div",{className:"fixed inset-0 z-[80] flex items-center justify-center overflow-y-auto bg-black/60 p-4",onClick:t=>{t.target===t.currentTarget&&!z&&Re(!1)},children:e.jsxs("div",{className:"my-auto w-full max-w-md rounded-2xl bg-white p-6 shadow-xl",children:[e.jsx("h3",{className:"text-lg font-bold text-slate-900",children:"Post to the job board"}),e.jsx("p",{className:"mt-1 text-sm text-slate-600",children:"Post to the photographer marketplace. Photographers apply; you hire, and the role is assigned automatically â no per-position setup."}),e.jsxs("label",{className:"mt-4 block text-sm font-medium text-slate-700",children:["Photographers needed (total",P==="lead"?", including the lead":"",")"]}),e.jsx("input",{type:"number",min:"1",step:"1",className:"mt-1 w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200",placeholder:"e.g. 20",value:re,onChange:t=>Et(t.target.value),disabled:z}),e.jsx("p",{className:"mt-1 text-xs text-slate-500",children:(()=>{const t=Math.max(1,parseInt(re,10)||0);if(!re.trim())return P==="lead"?"Posts a Lead listing + a Photographer listing for the rest.":"Posts one Photographer listing.";if(P==="lead"){const a=Math.max(0,t-1);return a>0?`Posts 1 Lead (1 slot) + 1 Photographer listing (${a} slot${a===1?"":"s"}).`:"Posts 1 Lead listing (1 slot)."}return`Posts 1 Photographer listing (${t} slot${t===1?"":"s"}).`})()}),e.jsx("label",{className:"mt-4 block text-sm font-medium text-slate-700",children:"Pay structure"}),e.jsxs("select",{className:"mt-1 w-full rounded-lg border border-slate-300 px-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200",value:be,onChange:t=>ma(t.target.value),disabled:z,children:[e.jsx("option",{value:"hourly",children:"Hourly"}),e.jsx("option",{value:"half-day",children:"Half-day"}),e.jsx("option",{value:"full-day",children:"Full-day"}),e.jsx("option",{value:"flat-plus-commission",children:"Flat + commission"})]}),e.jsx("label",{className:"mt-3 block text-sm font-medium text-slate-700",children:"Amount ($ per photographer)"}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx("span",{className:"pointer-events-none absolute inset-y-0 left-3 flex items-center text-slate-500 text-sm",children:"$"}),e.jsx("input",{type:"number",min:"0",step:"1",className:"w-full rounded-lg border border-slate-300 pl-7 pr-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200",placeholder:"e.g. 250",value:Ve,onChange:t=>ua(t.target.value),disabled:z})]}),be==="flat-plus-commission"&&e.jsxs(e.Fragment,{children:[e.jsx("label",{className:"mt-3 block text-sm font-medium text-slate-700",children:"Commission %"}),e.jsxs("div",{className:"relative mt-1",children:[e.jsx("input",{type:"number",min:"0",max:"100",step:"1",className:"w-full rounded-lg border border-slate-300 px-3 py-2 pr-7 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200",placeholder:"e.g. 15",value:He,onCh
11ange:t=>{const a=t.target.value;if(a===""){St("");return}const s=Number(a);Number.isNaN(s)||St(String(Math.max(0,Math.min(100,s))))},disabled:z}),e.jsx("span",{className:"pointer-events-none absolute inset-y-0 right-3 flex items-center text-slate-500 text-sm",children:"%"})]})]}),e.jsxs("div",{className:"mt-4 rounded-lg border border-slate-200 bg-slate-50 p-3",children:[e.jsxs("label",{className:"flex items-start gap-2 cursor-pointer",children:[e.jsx("input",{type:"checkbox",className:"mt-0.5",checked:le,onChange:t=>pa(t.target.checked),disabled:z}),e.jsxs("span",{children:[e.jsx("span",{className:"block text-sm font-medium text-slate-800",children:"Offer a referral bonus"}),e.jsx("span",{className:"block text-xs text-slate-500",children:"Pay your hired photographers a bonus when they refer a friend who gets hired and completes this event. You fund it; it's charged when you hire the friend and released after they finish."})]})]}),le&&e.jsxs("div",{className:"mt-3 grid grid-cols-2 gap-3",children:[e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-slate-600 mb-1",children:"Bonus per referral"}),e.jsxs("div",{className:"relative",children:[e.jsx("span",{className:"pointer-events-none absolute inset-y-0 left-3 flex items-center text-slate-500 text-sm",children:"$"}),e.jsx("input",{type:"number",min:"5",step:"5",className:"w-full rounded-lg border border-slate-300 pl-7 pr-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200",value:Ct,onChange:t=>ha(t.target.value),disabled:z})]})]}),e.jsxs("div",{children:[e.jsx("label",{className:"block text-xs font-medium text-slate-600 mb-1",children:"Max per event"}),e.jsxs("div",{className:"relative",children:[e.jsx("span",{className:"pointer-events-none absolute inset-y-0 left-3 flex items-center text-slate-500 text-sm",children:"$"}),e.jsx("input",{type:"number",min:"5",step:"5",className:"w-full rounded-lg border border-slate-300 pl-7 pr-3 py-2 text-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200",value:Pt,onCh
11ange:t=>ga(t.target.value),disabled:z})]})]})]})]}),e.jsxs("div",{className:"mt-5 flex items-center justify-end gap-2",children:[e.jsx("button",{type:"button",onClick:()=>Re(!1),disabled:z,className:"rounded-xl px-4 py-2 text-sm font-medium text-slate-600 hover:bg-slate-100 disabled:opacity-40",children:"Cancel"}),e.jsx("button",{type:"button",onClick:()=>void ka(),disabled:z||!Ve.trim()||!re.trim(),className:"rounded-xl bg-orange-500 px-5 py-2 text-sm font-semibold text-white hover:opacity-90 disabled:opacity-40 disabled:cursor-not-allowed",children:z?"Publishingâ¦":"Publish & post job"})]})]})})]})}export{zs as LogisticsAiBuilder};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.