streamlink

Collaboration Metrics for streamlink/streamlink

Utility

Streamlink is a CLI utility which pipes video streams from various services into a video player

Feedback Compare

Contributor Distribution

Core Team PRs
Percentage of PRs created by the core team
90.0%
Community PRs
Percentage of PRs created by the community
6.0%
Bot PRs
Percentage of PRs created by bots
4.0%

Review-Merge Coverage

Review-Merge Rate
Percentage of merged PRs that received reviews
3.0%

Merge Time

Overall Median Merge Time
Median time from PR creation to merge
7.9 minutes

Request Approval Time

No approval time data available

Bot Activity

Bot Activity
Percentage of repository events performed by bots
1.7%
Unique Bots
Number of unique bots active in this repository
1

Review Funnel

Review Rate
Percentage of PRs that received reviews
3.0%
Approval Rate
Percentage of reviewed PRs that were approved
33.3%

Review Turnaround

Turnaround Time
Median time to first review
1.4 hours
Reviewed in an Hour
PRs that received a review within 1 hour
33.3%

Review Wait Time

Overall Median Wait Time
Median overall wait time per PR
0 seconds

`; } else { console.error( "Error element not found for ID:", `wait-time-breakdown-${state.chartId}` ); } } function updateChart() { console.log("Updating chart with state:", { hasAllData: !!state.allData, hasData: !!state.allData?.data, dataLength: state.allData?.data?.length, }); if ( !state.allData || !state.allData.data || !state.allData.data[0] ) { showError("No chart data available"); return; } try { let numPrs = 10; let showLongest = true; if (state.isMaintainer) { const numPrsElement = document.getElementById( `num-prs-${state.chartId}` ); const longestElement = document.getElementById( `longest-${state.chartId}` ); if (numPrsElement && longestElement) { numPrs = parseInt(numPrsElement.value); showLongest = longestElement.checked; } } const prs = []; for (let i = 0; i < state.allData.data[0].x.length; i++) { let total = 0; state.allData.data.forEach(function (trace) { total += trace.y[i] || 0; }); prs.push({ index: i, total: total }); } let filteredPrs = prs.filter((pr) => pr.total > 0); if (filteredPrs.length === 0 || showLongest) { filteredPrs = prs; } filteredPrs.sort(function (a, b) { return showLongest ? b.total - a.total : a.total - b.total; }); filteredPrs = filteredPrs.slice(0, numPrs); if (filteredPrs.length === 0) { showError("No PRs with wait time data available"); return; } console.log("Preparing chart data with filtered PRs:", { numPrs: filteredPrs.length, showLongest, }); const newData = state.allData.data.map(function (trace) { return { type: "bar", name: trace.name, x: filteredPrs.map((pr) => trace.x[pr.index]), y: filteredPrs.map((pr) => trace.y[pr.index]), customdata: filteredPrs.map( (pr) => trace.customdata[pr.index] ), marker: trace.marker, hovertemplate: trace.hovertemplate, }; }); const newLayout = Object.assign({}, state.allData.layout); if (newLayout.title) { delete newLayout.title; } const config = { displayModeBar: false, responsive: true, displaylogo: false, modeBarButtonsToRemove: [ "sendDataToCloud", "autoScale2d", "resetScale2d", ], }; console.log("Plotting chart with data:", { dataLength: newData.length, hasLayout: !!newLayout, targetElement: `wait-time-breakdown-${state.chartId}`, }); Plotly.newPlot( `wait-time-breakdown-${state.chartId}`, newData, newLayout, config ); } catch (err) { console.error("Error updating chart:", err); showError("Error updating chart"); } } function setupEventListeners() { if (!state.isMaintainer) { return; } const numPrsElement = document.getElementById( `num-prs-${state.chartId}` ); if (numPrsElement) { numPrsElement.addEventListener("input", function (e) { const valueElement = document.getElementById( `num-prs-value-${state.chartId}` ); if (valueElement) { valueElement.textContent = e.target.value; } updateChart(); }); } const radioElements = document.getElementsByName( `wait-time-option-${state.chartId}` ); radioElements.forEach(function (radio) { radio.addEventListener("change", updateChart); }); } // Initialize everything when the DOM is ready document.addEventListener("DOMContentLoaded", function () { console.log("DOM loaded, initializing chart..."); if (initializeChart()) { updateChart(); setupEventListeners(); } }); } catch (err) { console.error("Error in chart initialization:", err); const element = document.getElementById("chart-data"); if (element) { console.log("Data attributes on error:", { chartId: element.dataset.chartId, isMaintainer: element.dataset.isMaintainer, chartData: element.dataset.chartData?.substring(0, 100) + "...", }); } } })();