© Copyright 2018 – 2024 FIRECRACKER SPORTS. All Rights Reserved.​ TERMS OF USE  |  PRIVACY POLICY

Brigade Baseball Club – Team Scout Day

06/14/2025
Leominster , Massachusetts

INFORMATION

  • Age groups:
    3 Divisions Positional Player Only Pitcher/Positional Player Combined Pitcher Only
  • Date :
    Saturday, June 14th
  • Price:
    Positional Player Only - $200Pitcher/Positional Player Combined - $225Pitcher Only - $175

The Brigade Baseball Club will be hosting a Team Scout Day on June 14, 2025 from 1:00pm - 4:00pm at McLaughlin Park (Upper Field) located in Leominster, MA. This special event will be powered by Firecracker Sports and its organizers in conjunction with the many college coaches in the area who will be in attendance.

This showcase gives exclusive access to players within the Brigade Baseball Club, and players invited by them the opportunity to showcase for college scouts who will be in attendance. Younger players will be able to gain valuable experience in showcasing for scouts while gathering a player evaluation from them and full metrics from the day. Each player must be at least the age of 13 and have the ability and experience of playing on the big diamond (60-90) by the time and date of this event to participate.

All players receive:

  • Performance T-Shirt, picture and recognition on our online scouting database with full event metrics and college coach evaluations to be distributed to our college coaching database across the country.
  • Dynamic workout, throwing session, Individual Skills and Drills, POP times for catchers, throwing velocities, advanced metrics through Trackman, 60 yd dash times, on field batting practice and bullpens for pitchers and catchers.
  • Players and parents also take part in a small group recruiting seminar during the event.
  • This event and its players will be promoted on Firecracker Sports social media platforms and to our 35K+ followers (this includes hundreds of college and pro scouts) during the event. The statistical data received from players at this event will be further promoted on our website and through our player profile platform https://firecrackersports.com/players-database and again through our social media.
  • To find out more about this event, you can contact operations@firecrackersports.com
  • To find out more about the Brigade Baseball Club or to request an invite to this event you can contact Alex Winkelmann at Alex.Winkelmann@edwardjones.com

Registration

  • DIVISION:
    • Positional Player Only
    • Pitcher/Positional Player Combined
    • Pitcher Only
    • 1:00 PM Session
    • 1:00 PM Session
    • 1:00 PM Session
    0 Players Registered
    COST: $175 - $225

College Coaches Attending

University of Pittsburgh

Stetson University
Assumption University
Rhode Island College
Compton College

Teams

Locations

McLaughlin Field - Upper Field

992 Lancaster street

Leominster massachusetts ,USA

Get Directions
Fields
  • Upper Field
    • Lights
    • Grass
    • Portable Bathrooms

schedule

HOTELS

SCHEDULES & STANDINGS

Brackets

TOP PERFORMERS

RULES

There is no rules.

WEATHER

`);printWindow.document.close(); }); function gpe_get_schedules_list() { const event_id = '39836';let division_filter_drop = $("#division_filter_drop").val(); let date_filter_drop = $("#date_filter_drop").val();// Show processing indicator (manually trigger it) table.destroy(); // Destroy old DataTable before making new AJAX call $("#schedules_table tbody").html('Loading...'); // Temporary loader row$.ajax({ url: gpe.ajax_url, type: 'post', data: { action: 'gpe_ajax', type: 'gpe_get_schedules_list', event_id: event_id, division_filter_drop: division_filter_drop, date_filter_drop: date_filter_drop }, success: function (response) { // Clear the table body and add new content $("#schedules_table tbody").empty().html(response.data.html);// Reinitialize DataTable with processing enabled table = $("#schedules_table").DataTable({ processing: true, serverSide: false, // Keep it false unless loading data dynamically searching: true, paging: true, autoWidth: false }); } }); } function gpe_get_standing_list() { const event_id = '39836'; let division_filter_drop = $("#division_filter_drop_for_standing").val(); // Show processing indicator (manually trigger it) standings_table.destroy(); // Destroy old DataTable before making new AJAX call $("#standings_table tbody").html('Loading...'); // Temporary loader row $.ajax({ url: gpe.ajax_url, type: 'post', data: { action: 'gpe_ajax', type: 'gpe_get_standing_list', event_id: event_id, division_filter_drop: division_filter_drop }, success: function (response) { // Clear the table body and add new content $("#standings_table tbody").empty().html(response.data.html); // Reinitialize DataTable with processing enabled standings_table = $("#standings_table").DataTable({ processing: true, serverSide: false, // Keep it false unless loading data dynamically searching: true, paging: true }); } }); } $('#shareDropdown').change(function(){ var selectedOption = $(this).val(); if (selectedOption === "copy") { var pageLink = window.location.href; var tempInput = $(""); $("body").append(tempInput); tempInput.val(pageLink).select(); document.execCommand("copy"); tempInput.remove(); Swal.fire({ title:"Success", text:"Copied to clipboard!", icon:'success' }); // Reset dropdown selection $(this).prop('selectedIndex', 0); } }); }); function gpeCustomeTabs(evt, cityName) { var i, tabcontent, tablinks; tabcontent = document.getElementsByClassName("gpe_tabcontent"); for (i = 0; i < tabcontent.length; i++) { tabcontent[i].style.display = "none"; } tablinks = document.getElementsByClassName("gpe_tablinks"); for (i = 0; i < tablinks.length; i++) { tablinks[i].className = tablinks[i].className.replace(" gpe_active", ""); } document.getElementById(cityName).style.display = "block"; evt.currentTarget.className += " gpe_active"; // Redraw connectors when Bracket tab is activated if (cityName === "brackets" && window.globalSerialMap) { // Wait until the browser has painted the visible DOM //requestAnimationFrame(() => { //setTimeout(() => { waitForLayoutAndDraw(window.globalSerialMap, 20); //}, 100); //}); } }// Get the element with id="defaultOpen" and click on it document.getElementById("defaultOpen").click(); var acc = document.getElementsByClassName("gpe_accordion"); var i; for (i = 0; i < acc.length; i++) { acc[i].addEventListener("click", function() { this.classList.toggle("active"); var panel = this.nextElementSibling; if (panel.style.maxHeight) { panel.style.maxHeight = null; } else { panel.style.maxHeight = panel.scrollHeight + "px"; } }); }var latitude = document.getElementById("latitude").value; var longitude = document.getElementById("longitude").value;var iframe = document.createElement("iframe"); iframe.src = "https://www.google.com/maps/embed?pb=!1m28!1m12!1m3!1d19797.686238814687!2d-71.3765509!3d41.8633795!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!4m13!3e6!4m5!1s0x89e45a80fc2b13ab%3A0x8f62f2e279889968!2sCurrent%20Location!3m2!1d" + latitude + "!2d" + longitude + "!4m5!1s0x89e45a7a2b41f7f3%3A0x6cb46461e8d0c1b4!2s" + latitude + "%2C" + longitude + "!3m2!1d" + latitude + "!2d" + longitude + "!5e0!3m2!1sen!2sus!4v1644233201036!5m2!1sen!2sus"; iframe.width = "528"; iframe.height = "295"; iframe.style.border = "0"; iframe.allowfullscreen = true;var mapContainer = document.getElementById("mapContainer"); mapContainer.innerHTML = ""; mapContainer.appendChild(iframe); function getPoolsByDivision(divisionId) { return $.ajax({ url: gpe.ajax_url, method: "POST", dataType: "json", data: { action: "gpe_ajax", type: "get_pools_save", division_id: divisionId } }); }function loadSavedBracket() { // Get the division ID from the division select dropdown const divisionId = $("#division_select").val(); // Get the current event ID dynamically from PHP const eventId = '39836';// If division ID is not selected, exit early if (!divisionId) return;// Perform both AJAX requests in parallel $.when( $.ajax({ url: gpe.ajax_url, // URL for the AJAX request type: "POST", // HTTP method dataType: "json", // Expected response type data: { action: "gpe_ajax", // WordPress action hook for AJAX type: "get_saved_bracket", // Custom action to get saved bracket data event_id: eventId, // The current event ID division_id: divisionId // The selected division ID } }), getPoolsByDivision(divisionId) // Function to get pools for the selected division ).done(function (bracketRes, poolsRes) { // Extract bracket data from the first response (bracketRes) const bracketData = bracketRes[0]?.data?.bracket_data || []; // Prepare a map of pool ID to pool title const poolMap = {}; poolsRes[0]?.data?.forEach(pool => { poolMap[pool.id] = pool.title; });// Call renderSavedBracket function to render the bracket renderSavedBracket(bracketData, poolMap); }).fail(function () { // In case of failure, show an error message in the bracket container $("#bracket").html("
Error loading bracket.
"); }); } function renderSavedBracket(bracketData, poolMap) { let bracketWrapper = $(".bracket_wrapper"); if (bracketWrapper.length === 0) { bracketWrapper = $("
").addClass("bracket_wrapper"); // Append it to the main container if it's missing $("#bracket").replaceWith(bracketWrapper); } else { bracketWrapper.empty(); // Clear existing content if already present } let bracketDiv = $("
").attr("id", "bracket"); bracketWrapper.append(bracketDiv); if (!bracketData || bracketData.length === 0) { bracketDiv.append(`

No bracket data found.

`); return; } let groups = {}; let serialMap = {}; let matchCounter = 1; bracketData.forEach(match => { if (match.is_important === "1") { if (!groups[match.group_number]) groups[match.group_number] = {}; if (!groups[match.group_number][match.column_number]) groups[match.group_number][match.column_number] = []; groups[match.group_number][match.column_number].push(match); } }); const sortedGroups = Object.keys(groups).sort(); const mainGroup = sortedGroups[0]; let groupScrollWrapper = $("
").addClass("group-scroll-wrapper"); for (let group of sortedGroups) { let groupSerialCounter = 1; let groupDiv = $("
").addClass("group").attr("data-group", group); let columnsContainer = $("
").addClass("columns-container"); let columns = Object.keys(groups[group]).sort((a, b) => a - b); const groupMatches = {}; const allMatches = Object.values(groups[group]).flat(); const isFiveTeam = allMatches.length === 4 && columns.length === 3; if (isFiveTeam) { allMatches.sort((a, b) => parseInt(a.name) - parseInt(b.name)); const displayOrder = [allMatches[0], allMatches[2], allMatches[1], allMatches[3]]; groupMatches[columns[0]] = [allMatches[0]]; groupMatches[columns[1]] = [allMatches[2], allMatches[1]]; groupMatches[columns[2]] = [allMatches[3]]; let roundDiv1 = $("
").addClass("round").attr("data-column", columns[0]); let roundDiv2 = $("
").addClass("round").attr("data-column", columns[1]); let roundDiv3 = $("
").addClass("round").attr("data-column", columns[2]); displayOrder.forEach((match, i) => { const serial = groupSerialCounter++; const matchId = `match-serial-${group}-${serial}`; let matchDiv = $("
") .addClass("match") .attr("id", matchId) .attr("data-match-index", match.name);let score1 = match.team1_score ?? "-"; let score2 = match.team2_score ?? "-"; let team1 = match.team_name1 ?? "Team 1"; let team2 = match.team_name2 ?? "Team 2"; let startTime = match.start_time || ""; let location = match.location || "";matchDiv.html(`
${serial}
${startTime}
${location}
${team1} ${score1}
${team2} ${score2}
`); const matchContainer = $("
").addClass("match-container"); matchContainer.append(matchDiv);match.serial = serial; serialMap[`${group}-${serial}`] = { ...match, group, column: match.column_number, serial };if (i === 0) roundDiv1.append(matchContainer); else if (i === 1 || i === 2) roundDiv2.append(matchContainer); else if (i === 3) roundDiv3.append(matchContainer); });columnsContainer.append(roundDiv1); columnsContainer.append($("
").addClass("connector-column")); columnsContainer.append(roundDiv2); columnsContainer.append($("
").addClass("connector-column")); columnsContainer.append(roundDiv3);groupDiv.append(columnsContainer); groupScrollWrapper.append(groupDiv);setTimeout(() => { positionMatches(groupMatches, group); waitForLayoutAndDraw(serialMap, 20); }, 100);continue; }columns.forEach((column, columnIndex) => { groups[group][column].sort((a, b) => parseInt(a.name) - parseInt(b.name)); let roundDiv = $("
").addClass("round").attr("data-column", column); groupMatches[column] = [];groups[group][column].forEach(match => { const serial = groupSerialCounter++; const matchId = `match-serial-${group}-${serial}`;let matchDiv = $("
") .addClass("match") .attr("id", matchId) .attr("data-match-index", match.name);let score1 = match.team1_score ?? "-"; let score2 = match.team2_score ?? "-"; let team1 = match.team_name1 ?? "Team 1"; let team2 = match.team_name2 ?? "Team 2"; let startTime = match.start_time || ""; let location = match.location || "";matchDiv.html(`
${serial}
${startTime}
${location}
${team1} ${score1}
${team2} ${score2}
`);const matchContainer = $("
").addClass("match-container"); matchContainer.append(matchDiv); roundDiv.append(matchContainer);match.serial = serial; serialMap[`${group}-${serial}`] = { ...match, group, column, serial };groupMatches[column].push(match); });columnsContainer.append(roundDiv); if (columnIndex < columns.length - 1) { columnsContainer.append($("
").addClass("connector-column")); } });groupDiv.append(columnsContainer); groupScrollWrapper.append(groupDiv);setTimeout(() => { positionMatches(groupMatches, group); waitForLayoutAndDraw(serialMap, 20); }, 100); }bracketDiv.append(groupScrollWrapper);const observer = new MutationObserver(() => { const visible = $(".bracket_wrapper:visible").length > 0; if (visible) { setTimeout(() => { waitForLayoutAndDraw(window._lastSerialMap || {}, 20); }, 100); } });observer.observe(document.body, { childList: true, subtree: true }); window.globalSerialMap = serialMap; } function positionMatches(groupMatches, group) { const levels = Object.keys(groupMatches).sort((a, b) => +a - +b); const matchCenters = {}; const spacing = 200; let bottomMost = 0;const totalMatches = Object.values(groupMatches).flat().length; const isFiveTeamLayout = totalMatches === 4; const isSixTeamLayout = totalMatches === 5; if (isSixTeamLayout) { const matchCenters = {}; let bottomMost = 0;// Step 1: Position initial matches const serialPositions = { 1: 0, 2: 100, 3: 200 };// Position matches 1-3 Object.entries(groupMatches).forEach(([level, matches]) => { matches.forEach((match) => { const matchId = `match-serial-${group}-${match.serial}`; const $el = $(`#${matchId}`).closest(".match-container");if (!$el.length) return;const y = serialPositions[match.serial] ?? 0; $el.css({ position: "absolute", top: `${y}px` });matchCenters[match.serial] = y + $el.outerHeight() / 2; bottomMost = Math.max(bottomMost, y + $el.outerHeight()); }); });// Match 4: Between 1 and 2 const match4Id = `match-serial-${group}-4`; const $match4 = $(`#${match4Id}`).closest(".match-container"); if ($match4.length) { const avgY = (matchCenters[1] + matchCenters[2]) / 2 - $match4.outerHeight() / 2; $match4.css({ position: "absolute", top: `${avgY}px` }); matchCenters[4] = avgY + $match4.outerHeight() / 2; bottomMost = Math.max(bottomMost, avgY + $match4.outerHeight()); }// Match 5: Between 3 and 4 const match5Id = `match-serial-${group}-5`; const $match5 = $(`#${match5Id}`).closest(".match-container"); if ($match5.length) { const avgY = (matchCenters[3] + matchCenters[4]) / 2 - $match5.outerHeight() / 2; $match5.css({ position: "absolute", top: `${avgY}px` }); matchCenters[5] = avgY + $match5.outerHeight() / 2; bottomMost = Math.max(bottomMost, avgY + $match5.outerHeight()); }// Step 4: Draw connector lines drawConnectorLine(group, 1, 4); drawConnectorLine(group, 2, 4); drawConnectorLine(group, 3, 5); drawConnectorLine(group, 4, 5);// Step 5: Set container height $(`.group[data-group="${group}"]`).css("height", bottomMost + 80); } function drawConnectorLine(group, fromSerial, toSerial) { const fromEl = $(`#match-serial-${group}-${fromSerial}`).closest(".match-container"); const toEl = $(`#match-serial-${group}-${toSerial}`).closest(".match-container");if (!fromEl.length || !toEl.length) { console.warn(`Cannot draw line: from ${fromSerial} or to ${toSerial} not found.`); return; }const $group = $(`.group[data-group="${group}"]`); const $svg = $group.find("svg.connector-layer");if (!$svg.length) { console.warn(`Missing SVG layer in group ${group}`); return; }const fromOffset = fromEl.position(); const toOffset = toEl.position();const fromX = fromEl.position().left + fromEl.outerWidth(); const fromY = fromOffset.top + fromEl.outerHeight() / 2; const toX = toEl.position().left; const toY = toOffset.top + toEl.outerHeight() / 2;console.log(`Drawing line: ${fromSerial} → ${toSerial}`, { fromX, fromY, toX, toY });// Create SVG line element const line = document.createElementNS("http://www.w3.org/2000/svg", "line"); line.setAttribute("x1", fromX); line.setAttribute("y1", fromY); line.setAttribute("x2", toX); line.setAttribute("y2", toY); line.setAttribute("stroke", "#333"); line.setAttribute("stroke-width", "2");$svg.append(line); }// Positioning for 5-team layout if (isFiveTeamLayout) { const serialPositions = { 1: 200, // First round (Play-in) 3: 80, // Semifinal 1 (top) 2: 320, // Semifinal 2 (bottom) 4: 200 // Final (centered between semi 1 and 2) };Object.entries(groupMatches).forEach(([level, matches]) => { matches.forEach((match) => { const matchId = `match-serial-${group}-${match.serial}`; const $el = $(`#${matchId}`).closest(".match-container");if (!$el.length) return;const y = serialPositions[match.serial] ?? 0; $el.css({ position: "absolute", top: `${y}px` });matchCenters[match.serial] = y + $el.outerHeight() / 2; bottomMost = Math.max(bottomMost, y + $el.outerHeight()); }); });$(`.group[data-group="${group}"]`).css("height", bottomMost + 160); return; }// Default layout for other brackets levels.forEach((level, levelIndex) => { const matches = groupMatches[level];matches.forEach((match, i) => { const matchId = `match-serial-${group}-${match.serial}`; const $el = $(`#${matchId}`).closest(".match-container");if (!$el.length) return;if (levelIndex === 0) { const pairIndex = Math.floor(i / 2); const y = i * spacing + pairIndex * 40; $el.css({ position: "absolute", top: `${y}px` }); matchCenters[match.serial] = y + $el.outerHeight() / 2; bottomMost = Math.max(bottomMost, y + $el.outerHeight()); } else { const prevLevel = levels[levelIndex - 1]; const prevMatches = groupMatches[prevLevel]; const prev1 = prevMatches[i * 2]; const prev2 = prevMatches[i * 2 + 1];if (prev1 && prev2) { const center1 = matchCenters[prev1.serial]; const center2 = matchCenters[prev2.serial]; const centerY = (center1 + center2) / 2; const topOffset = centerY - $el.outerHeight() / 2; $el.css({ position: "absolute", top: `${topOffset}px` }); matchCenters[match.serial] = centerY; bottomMost = Math.max(bottomMost, topOffset + $el.outerHeight()); } } }); });$(`.group[data-group="${group}"]`).css("height", bottomMost + 180); } function debounce(func, delay) { let timeout; return function (...args) { clearTimeout(timeout); timeout = setTimeout(() => func.apply(this, args), delay); }; } function waitForLayoutAndDraw(serialMap, maxTries = 10) { if (window._isDrawingScheduled) return;window._isDrawingScheduled = true; window._lastSerialMap = serialMap;let tries = 0;function tryDraw() { const wrapper = document.querySelector(".bracket_wrapper");if (!wrapper) { if (tries < maxTries) { tries++; requestAnimationFrame(tryDraw); } else { window._isDrawingScheduled = false; // Reset if failed after all tries } return; }const rect = wrapper.getBoundingClientRect(); if (rect.width < 100 || rect.height < 100) { if (tries < maxTries) { tries++; requestAnimationFrame(tryDraw); } else { window._isDrawingScheduled = false; } return; }// ✅ Only draw once per layout session if (!wrapper.dataset.hasDrawn) { drawBracketConnectors(serialMap, true); wrapper.dataset.hasDrawn = "true"; }// 🟢 Reset the flag after a short time (if needed later) setTimeout(() => { window._isDrawingScheduled = false; wrapper.dataset.hasDrawn = ""; // Allow future redraws if needed }, 1000);// 🟢 Add scroll listener once if (!wrapper.dataset.scrollListenerAdded) { console.log("Ketan testing"); wrapper.addEventListener( "scroll", debounce(() => drawBracketConnectors(window._lastSerialMap, true), 100) ); wrapper.dataset.scrollListenerAdded = "true"; } }requestAnimationFrame(tryDraw); }function drawBracketConnectors(serialMap, forceRedraw = false) { console.log("Ketan test"); const svgNS = "http://www.w3.org/2000/svg"; let svg = document.getElementById("bracket-connector-svg"); const wrapper = document.querySelector(".bracket_wrapper");const wrapperRect = wrapper.getBoundingClientRect(); const scrollLeft = wrapper.scrollLeft; const scrollTop = wrapper.scrollTop;if (!svg) { svg = document.createElementNS(svgNS, "svg"); svg.setAttribute("id", "bracket-connector-svg"); svg.style.position = "absolute"; svg.style.top = "0"; svg.style.left = "0"; svg.style.pointerEvents = "none"; wrapper.appendChild(svg); }svg.style.width = wrapper.scrollWidth + "px"; svg.style.height = wrapper.scrollHeight + "px";const layoutHash = JSON.stringify( Object.values(serialMap).map(m => { const el = document.getElementById(`match-serial-${m.group}-${m.serial}`); const rect = el?.getBoundingClientRect(); return { serial: m.serial, group: m.group, column: m.column, rect: rect ? { top: rect.top, left: rect.left, width: rect.width, height: rect.height } : null }; }) );if (!forceRedraw && window._lastLayoutHash === layoutHash) return; window._lastLayoutHash = layoutHash;while (svg.firstChild) svg.removeChild(svg.firstChild);const groupMap = {}; for (const serial in serialMap) { const match = serialMap[serial]; if (!groupMap[match.group]) groupMap[match.group] = []; groupMap[match.group].push(match); }for (const group in groupMap) { const matches = groupMap[group].sort((a, b) => +a.serial - +b.serial); const matchMap = {};matches.forEach(match => { matchMap[match.serial] = match; match.el = document.getElementById(`match-serial-${group}-${match.serial}`); match.rect = match.el?.getBoundingClientRect(); });const isFiveMatch = matches.length === 4; const isThreeTeam = matches.length === 2 && matchMap["1"] && matchMap["2"];if (isThreeTeam) { console.log("This is a testing"); const fromMatch = matchMap[1]; const toMatch = matchMap[2];if (fromMatch?.rect && toMatch?.rect) { drawLConnectorCustom(fromMatch.rect, toMatch.rect, "right", 40); }continue; // only skip current group } if (matches.length === 5) { const m1 = matchMap[1], m2 = matchMap[2]; const m3 = matchMap[3], m4 = matchMap[4], m5 = matchMap[5];if (m1?.rect && m4?.rect) drawLConnectorCustom(m1.rect, m4.rect, "top", 40); if (m2?.rect && m4?.rect) drawLConnectorCustom(m2.rect, m4.rect, "bottom", 40); if (m3?.rect && m5?.rect) drawLConnectorCustom(m3.rect, m5.rect, "top", 40); if (m4?.rect && m5?.rect) drawLConnectorCustom(m4.rect, m5.rect, "bottom", 40); }if (isFiveMatch) { const s1 = matchMap[1], s2 = matchMap[2], s3 = matchMap[3], s4 = matchMap[4];if (s1?.rect && s3?.rect) drawLConnectorCustom(s1.rect, s3.rect, "bottom"); if (s2?.rect && s4?.rect) drawLConnectorCustom(s2.rect, s4.rect, "top", 40); if (s3?.rect && s4?.rect) drawLConnectorCustom(s3.rect, s4.rect, "bottom", 80);continue; // use continue, not return — don't break whole function }const columns = [...new Set(matches.map(m => +m.column))].sort((a, b) => a - b);for (let colIndex = 1; colIndex < columns.length; colIndex++) { const currentCol = columns[colIndex]; const prevCol = columns[colIndex - 1];const currentMatches = matches.filter(m => +m.column === currentCol); const prevMatches = matches.filter(m => +m.column === prevCol);for (let i = 0; i < currentMatches.length; i++) { const targetMatch = currentMatches[i]; const input1 = prevMatches[i * 2]; const input2 = prevMatches[i * 2 + 1];if (input1?.rect && input2?.rect && targetMatch?.rect) { drawLConnectorCustom(input1.rect, targetMatch.rect, "top", 40); drawLConnectorCustom(input2.rect, targetMatch.rect, "bottom", 40); } else if ((input1?.rect || input2?.rect) && targetMatch?.rect) { const fromRect = input1?.rect || input2?.rect; const direction = input1?.rect ? "top" : "bottom"; drawLConnectorCustom(fromRect, targetMatch.rect, direction, 40); } } }function drawLConnectorCustom(fromRect, toRect, toPoint = "center", elbowOffset = 40) { const startX = fromRect.right - wrapperRect.left + scrollLeft; const startY = fromRect.top + fromRect.height / 2 - wrapperRect.top + scrollTop;let toY; const headerOffset = 48;if (toPoint === "top") { toY = toRect.top + headerOffset + 10 - wrapperRect.top + scrollTop; } else if (toPoint === "bottom") { toY = toRect.bottom - 10 - wrapperRect.top + scrollTop; } else { toY = toRect.top + toRect.height / 2 - wrapperRect.top + scrollTop; }const endX = toRect.left - wrapperRect.left + scrollLeft + 5;const path = document.createElementNS(svgNS, "path"); path.setAttribute("stroke", "#999"); path.setAttribute("stroke-width", "1.5"); path.setAttribute("fill", "none"); path.setAttribute("stroke-linecap", "round");const d = ` M ${startX},${startY} H ${endX} V ${toY} `;path.setAttribute("d", d.trim().replace(/\s+/g, " ")); svg.appendChild(path); }function drawTConnector(fromRect, toRect) { const startX = fromRect.right - wrapperRect.left + scrollLeft; const startY = fromRect.top + fromRect.height / 2 - wrapperRect.top + scrollTop;const endX = toRect.left - wrapperRect.left + scrollLeft; const endY = toRect.top + toRect.height / 2 - wrapperRect.top + scrollTop; const midX = (startX + endX) / 2;const path1 = document.createElementNS(svgNS, "path"); path1.setAttribute("stroke", "#999"); path1.setAttribute("stroke-width", "1.5"); path1.setAttribute("fill", "none"); path1.setAttribute("stroke-linecap", "round"); path1.setAttribute("d", `M ${startX},${startY} H ${midX}`); svg.appendChild(path1);const path2 = document.createElementNS(svgNS, "path"); path2.setAttribute("stroke", "#999"); path2.setAttribute("stroke-width", "1.5"); path2.setAttribute("fill", "none"); path2.setAttribute("stroke-linecap", "round"); path2.setAttribute("d", `M ${endX},${endY} H ${midX}`); svg.appendChild(path2);const verticalLine = document.createElementNS(svgNS, "path"); verticalLine.setAttribute("stroke", "#999"); verticalLine.setAttribute("stroke-width", "1.5"); verticalLine.setAttribute("fill", "none"); verticalLine.setAttribute("stroke-linecap", "round"); verticalLine.setAttribute("d", `M ${midX},${startY} V ${endY}`); svg.appendChild(verticalLine); }function drawHorizontalConnector(fromRect, toRect) { const startX = fromRect.right - wrapperRect.left + scrollLeft; const startY = fromRect.top + fromRect.height / 2 - wrapperRect.top + scrollTop;const endX = toRect.left - wrapperRect.left + scrollLeft;const path = document.createElementNS(svgNS, "path"); path.setAttribute("stroke", "#999"); path.setAttribute("stroke-width", "1.5"); path.setAttribute("fill", "none"); path.setAttribute("stroke-linecap", "round");const d = `M ${startX},${startY} H ${endX}`; path.setAttribute("d", d.trim().replace(/\s+/g, " ")); svg.appendChild(path); }function drawRightThenVertical(fromRect, toRect, align = "top") { const startX = fromRect.right - wrapperRect.left + scrollLeft; const startY = fromRect.top + fromRect.height / 2 - wrapperRect.top + scrollTop; const elbowX = startX + 40;const toY = align === "top" ? toRect.top - wrapperRect.top + scrollTop : toRect.bottom - wrapperRect.top + scrollTop;const toX = toRect.left - wrapperRect.left + scrollLeft;const path = document.createElementNS(svgNS, "path"); path.setAttribute("stroke", "#888"); path.setAttribute("stroke-width", "4"); path.setAttribute("fill", "none"); path.setAttribute("stroke-linejoin", "round"); path.setAttribute("stroke-linecap", "round");const d = ` M ${startX},${startY} H ${elbowX} V ${toY} H ${toX} `; path.setAttribute("d", d.trim().replace(/\s+/g, " ")); svg.appendChild(path); }function drawLine(from, to) { if (!from?.rect || !to?.rect) return;const x1 = from.rect.right + scrollLeft - wrapperRect.left; const y1 = from.rect.top + from.rect.height / 2 + scrollTop - wrapperRect.top;const x2 = to.rect.left + scrollLeft - wrapperRect.left; const y2 = to.rect.top + to.rect.height / 2 + scrollTop - wrapperRect.top;const midX = (x1 + x2) / 2;const path = document.createElementNS(svgNS, "path"); path.setAttribute("stroke", "#999"); path.setAttribute("stroke-width", "2"); path.setAttribute("fill", "none"); path.setAttribute("d", `M ${x1},${y1} H ${midX} V ${y2} H ${x2}`); svg.appendChild(path); }function drawDefaultConnect(input1, input2, targetMatch) { if (!input1?.rect || !input2?.rect || !targetMatch?.rect) return;const x1 = input1.rect.right + scrollLeft - wrapperRect.left; const y1 = input1.rect.top + input1.rect.height / 2 + scrollTop - wrapperRect.top;const x2 = input2.rect.right + scrollLeft - wrapperRect.left; const y2 = input2.rect.top + input2.rect.height / 2 + scrollTop - wrapperRect.top;const toX = targetMatch.rect.left + scrollLeft - wrapperRect.left; const toY = targetMatch.rect.top + targetMatch.rect.height / 2 + scrollTop - wrapperRect.top;const midX = (x1 + toX) / 2; const midY = (y1 + y2) / 2;const path = document.createElementNS(svgNS, "path"); path.setAttribute("stroke", "#999"); path.setAttribute("stroke-width", "2"); path.setAttribute("fill", "none");const d = ` M ${x1},${y1} H ${midX} M ${x2},${y2} H ${midX} M ${midX},${y1} V ${y2} M ${midX},${midY} H ${toX} `; path.setAttribute("d", d.trim().replace(/\s+/g, ' ')); svg.appendChild(path); } } }
×

Request for More Info