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

test event

03/30/2025 - 05/16/2025
boston , Armed Forces Americas

INFORMATION

  • Age groups:
    1 Divisions 11U – 14U
  • Pool Play:
    Sunday, March 30th through Thursday, May 15th, 2025
  • Price:
    11U – 14U - $
  • Playoffs/Championships:
    Friday, May 16th, 2025

Registration

  • DIVISION:
    • 11U – 14U
    • Champions
    3 Teams Registered
    COST: $

College Coaches Attending

Teams

(3 teams) - Champions

Locations

Alumni Field

50 Alumni Road

Newington ,

Get Directions
Fields
  • Field - 1
    • Lights
    • Grass
VENUE DETAILS

Alumni Field

Abe Levitt Park

52 Stewart Ave

Hicksville ,

Get Directions
Fields
  • field 3
    • Permanent Bathrooms
  • field 4
    • Permanent Bathrooms
VENUE DETAILS

Abe Levitt Park

American Legion Field

10200 Seaview Ave

Brooklyn ,

Get Directions
Fields
  • test on
    • Grass
  • test off
    • Turf
VENUE DETAILS

American Legion Field

schedule

HOTELS

SCHEDULES & STANDINGS

Standings

 TeamWLTRARSW%
DateTimeGameDivisionLocationTeamScoreTeamNotes

Brackets

TOP PERFORMERS

RULES

There is no rules.

WEATHER

`);printWindow.document.close(); }); function gpe_get_schedules_list() { const event_id = '41769';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 = '41769'; 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 = '41769';// 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 (!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