From c9b0df42bd05054d96792849ad4aff6ea2986d30 Mon Sep 17 00:00:00 2001 From: sajeetharan Date: Mon, 28 Sep 2026 19:03:21 +0530 Subject: [PATCH] fix search discovery and protocol resilience --- app/api/search/route.js | 70 ++- app/openapi.json/route.js | 1 + components/SearchBar.jsx | 71 ++- lib/analytics.js | 28 +- lib/developer-search.js | 90 +++- lib/remote-mcp.js | 30 +- package-lock.json | 882 ++++++++++++++++++++------------- package.json | 7 +- styles/main.css | 18 +- tests/analytics.test.js | 34 ++ tests/developer-search.test.js | 52 ++ tests/remote-mcp.test.js | 8 + 12 files changed, 892 insertions(+), 399 deletions(-) create mode 100644 tests/analytics.test.js diff --git a/app/api/search/route.js b/app/api/search/route.js index 204a955..9aa2efe 100644 --- a/app/api/search/route.js +++ b/app/api/search/route.js @@ -3,7 +3,11 @@ import { NextResponse } from 'next/server.js'; import { promises as fs } from 'fs'; import path from 'path'; import { apiError } from '../../../lib/api-error.js'; -import { developerMatchesSearchQuery, tokenizeDeveloperSearchQuery } from '../../../lib/developer-search.js'; +import { + rankDeveloperSearchResults, + searchTermAlternatives, + tokenizeDeveloperSearchQuery, +} from '../../../lib/developer-search.js'; import { attachSearchMatches } from '../../../lib/search-match.js'; const COSMOS_ENDPOINT = process.env.COSMOS_ENDPOINT; @@ -31,21 +35,27 @@ async function getSampleData() { } function searchSampleData(data, q, limit) { - return data - .filter(developer => developerMatchesSearchQuery(developer, q)) - .slice(0, limit); + return rankDeveloperSearchResults(data, q, limit); } -function buildTextSearch(terms, limit) { - const parameters = terms.map((term, index) => ({ name: `@q${index}`, value: term })); - const predicates = terms.map((_, index) => `( - CONTAINS(LOWER(c.login), @q${index}) - OR CONTAINS(LOWER(c.name), @q${index}) - OR CONTAINS(LOWER(c.location), @q${index}) - OR CONTAINS(LOWER(c.bio), @q${index}) - OR CONTAINS(LOWER(c.topLanguage), @q${index}) - OR EXISTS(SELECT VALUE tag FROM tag IN c.specialTags WHERE CONTAINS(LOWER(tag), @q${index})) - )`); +function buildTextSearch(terms, limit, matchAll = true) { + const parameters = []; + const predicates = terms.map((term, termIndex) => { + const alternatives = searchTermAlternatives(term); + const alternativePredicates = alternatives.map((alternative, alternativeIndex) => { + const parameterName = `@q${termIndex}_${alternativeIndex}`; + parameters.push({ name: parameterName, value: alternative }); + return `( + CONTAINS(LOWER(c.login), ${parameterName}) + OR CONTAINS(LOWER(c.name), ${parameterName}) + OR CONTAINS(LOWER(c.location), ${parameterName}) + OR CONTAINS(LOWER(c.bio), ${parameterName}) + OR CONTAINS(LOWER(c.topLanguage), ${parameterName}) + OR EXISTS(SELECT VALUE tag FROM tag IN c.specialTags WHERE CONTAINS(LOWER(tag), ${parameterName})) + )`; + }); + return `(${alternativePredicates.join(' OR ')})`; + }); return { query: ` @@ -53,7 +63,7 @@ function buildTextSearch(terms, limit) { c.id, c.login, c.name, c.avatarUrl, c.location, c.lat, c.lng, c.topLanguage, c.score, c.totalStars, c.followers, c.soReputation, c.specialTags FROM c - WHERE ${predicates.join(' AND ')} AND ${PUBLIC_FILTER} + WHERE ${predicates.join(matchAll ? ' AND ' : ' OR ')} AND ${PUBLIC_FILTER} ORDER BY c.score DESC `, parameters, @@ -61,8 +71,12 @@ function buildTextSearch(terms, limit) { } async function runTextSearch(container, terms, limit) { - const { resources } = await container.items.query(buildTextSearch(terms, limit)).fetchAll(); - return resources; + const strict = await container.items.query(buildTextSearch(terms, limit)).fetchAll(); + if (strict.resources.length || terms.length < 2) return { results: strict.resources, matchMode: 'all' }; + const candidateLimit = Math.min(Math.max(limit * 5, 50), 200); + const broadened = await container.items.query(buildTextSearch(terms, candidateLimit, false)).fetchAll(); + const ranked = rankDeveloperSearchResults(broadened.resources, terms.join(' '), limit); + return { results: ranked.results, matchMode: ranked.matchMode }; } async function runVectorSearch(container, query, limit) { @@ -117,13 +131,15 @@ export async function GET(request) { if (!COSMOS_ENDPOINT || !COSMOS_KEY) { const data = await getSampleData(); - const results = attachSearchMatches(searchSampleData(data, q, limit), q, 'text'); + const search = searchSampleData(data, q, limit); + const results = attachSearchMatches(search.results, q, 'text'); return NextResponse.json({ query: q, requestedMode: mode, mode: 'text', fallback: mode === 'text' ? null : 'semantic_unavailable', interpretedTerms, + matchMode: search.matchMode, count: results.length, results, }); @@ -135,6 +151,7 @@ export async function GET(request) { let results; let resolvedMode = mode; let fallback = null; + let matchMode = 'all'; if (mode === 'vector') { try { @@ -142,19 +159,25 @@ export async function GET(request) { results = await runVectorSearch(container, q, limit); } catch (error) { console.warn('Vector search fell back to text:', error.message); - results = await runTextSearch(container, interpretedTerms, limit); + const textSearch = await runTextSearch(container, interpretedTerms, limit); + results = textSearch.results; + matchMode = textSearch.matchMode; resolvedMode = 'text'; fallback = 'semantic_unavailable'; } } else if (mode === 'text') { - results = await runTextSearch(container, interpretedTerms, limit); + const textSearch = await runTextSearch(container, interpretedTerms, limit); + results = textSearch.results; + matchMode = textSearch.matchMode; } else { try { if (!OPENAI_CONFIGURED) throw new Error('Semantic search is not configured'); - const [vectorResults, textResults] = await Promise.all([ + const [vectorResults, textSearch] = await Promise.all([ runVectorSearch(container, q, limit), runTextSearch(container, interpretedTerms, limit), ]); + const textResults = textSearch.results; + matchMode = textSearch.matchMode; const k = 60; const rrf = new Map(); const allMap = new Map(); @@ -169,7 +192,9 @@ export async function GET(request) { results = [...rrf.entries()].sort((a, b) => b[1] - a[1]).slice(0, limit).map(([login]) => allMap.get(login)); } catch (error) { console.warn('Hybrid search fell back to text:', error.message); - results = await runTextSearch(container, interpretedTerms, limit); + const textSearch = await runTextSearch(container, interpretedTerms, limit); + results = textSearch.results; + matchMode = textSearch.matchMode; resolvedMode = 'text'; fallback = 'semantic_unavailable'; } @@ -182,6 +207,7 @@ export async function GET(request) { mode: resolvedMode, fallback, interpretedTerms, + matchMode, count: results.length, results, }); diff --git a/app/openapi.json/route.js b/app/openapi.json/route.js index 3dce5a9..c0ea6ca 100644 --- a/app/openapi.json/route.js +++ b/app/openapi.json/route.js @@ -80,6 +80,7 @@ export function GET() { mode: { type: 'string' }, fallback: { type: ['string', 'null'], enum: ['semantic_unavailable', null] }, interpretedTerms: { type: 'array', items: { type: 'string' } }, + matchMode: { type: 'string', enum: ['all', 'approximate', 'broadened', 'none'] }, count: { type: 'integer' }, results: { type: 'array', diff --git a/components/SearchBar.jsx b/components/SearchBar.jsx index 1e8a776..cea36b5 100644 --- a/components/SearchBar.jsx +++ b/components/SearchBar.jsx @@ -5,9 +5,9 @@ import SpecialTags from './SpecialTags.jsx'; import { track, trackSearchAppearances } from '../lib/analytics.js'; import { countryKey } from '../lib/country.js'; import { - developerMatchesSearchQuery, findExactLoginResult, normalizeTextSearchQuery, + rankDeveloperSearchResults, tokenizeDeveloperSearchQuery, } from '../lib/developer-search.js'; import { publicApiUrl } from '../lib/public-api.js'; @@ -93,13 +93,14 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve track('next_action_selected', { action: source, journey: 'agent_onboarding', source: 'homepage_prompt' }); }, [agentPromptKey]); - const openSearchResult = useCallback((developer, source) => { + const openSearchResult = useCallback((developer, source, resultRank) => { recordRecentProfile(developer); track('search_result_opened', { login: developer.login, action: mode, journey: 'developer_discovery', source, + ...(Number.isInteger(resultRank) ? { resultRank } : {}), }); track('personalized_profile_viewed', { login: developer.login, @@ -125,11 +126,15 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve onSelectDeveloper(developer); }, [mode, onSelectDeveloper]); - const recordSearchOutcome = useCallback((results, searchMode, source) => { + const recordSearchOutcome = useCallback((results, searchMode, source, context = {}) => { track(results.length > 0 ? 'search_results_viewed' : 'search_no_results', { action: searchMode, journey: 'developer_discovery', source, + termCount: context.interpretedTerms?.length || 0, + resultCount: results.length, + matchMode: context.matchMode || 'all', + fallback: context.fallback || 'none', }); }, []); @@ -153,13 +158,18 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve if (m === 'text') { const textQuery = normalizeTextSearchQuery(q); - const interpretedTerms = tokenizeDeveloperSearchQuery(textQuery); - let results = developers.filter(d => - developerMatchesSearchQuery(d, textQuery) || - (interpretedTerms.length === 1 && d.location && countryKey(d.location).includes(countryKey(interpretedTerms[0]))) - ).slice(0, topN); + const localSearch = rankDeveloperSearchResults(developers, textQuery, topN); + const interpretedTerms = localSearch.interpretedTerms; + let results = localSearch.results; + let outcomeContext = { interpretedTerms, fallback: null, matchMode: localSearch.matchMode }; - setSearchContext({ interpretedTerms, fallback: null }); + if (!results.length && interpretedTerms.length === 1) { + results = developers.filter(developer => + developer.location && countryKey(developer.location).includes(countryKey(interpretedTerms[0])) + ).slice(0, topN); + } + + setSearchContext(outcomeContext); if (results.length === 0) { const controller = new AbortController(); @@ -174,7 +184,12 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve if (controller.signal.aborted) return; if (!response.ok) throw new Error(data.error?.message || data.error || 'Search is unavailable.'); results = data.results || []; - setSearchContext({ interpretedTerms: data.interpretedTerms || interpretedTerms, fallback: data.fallback }); + outcomeContext = { + interpretedTerms: data.interpretedTerms || interpretedTerms, + fallback: data.fallback, + matchMode: data.matchMode || 'all', + }; + setSearchContext(outcomeContext); } catch (error) { if (error.name === 'AbortError') return; console.error('Text search fallback failed:', error); @@ -194,7 +209,7 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve setVisibleResults(results.slice(0, 3)); setSingleResult(results.length === 1 ? results[0] : null); if (remember) recordRecentSearch({ query: q, mode: m }); - recordSearchOutcome(results, m, source); + recordSearchOutcome(results, m, source, outcomeContext); trackSearchAppearances(results.map(result => result.login), m); onSearchState?.({ query: q.trim(), results }); const exactResult = openExact ? findExactLoginResult(q, results) : null; @@ -215,7 +230,12 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve if (!res.ok) throw new Error(data.error || 'Search is unavailable.'); if (!controller.signal.aborted) { const results = data.results || []; - setSearchContext({ interpretedTerms: data.interpretedTerms || [], fallback: data.fallback }); + const outcomeContext = { + interpretedTerms: data.interpretedTerms || [], + fallback: data.fallback, + matchMode: data.matchMode || 'all', + }; + setSearchContext(outcomeContext); onResults(results); setResultCount(results.length); setVisibleResults(results.slice(0, 3)); @@ -224,7 +244,7 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve : null; setSingleResult(matchedDeveloper); if (remember) recordRecentSearch({ query: q, mode: m }); - recordSearchOutcome(results, m, source); + recordSearchOutcome(results, m, source, outcomeContext); trackSearchAppearances(results.map(result => result.login), m); onSearchState?.({ query: q.trim(), results }); const exactResult = openExact ? findExactLoginResult(q, results) : null; @@ -306,8 +326,16 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve inputRef.current?.focus(); }; - const handleSelectResult = (developer) => { - openSearchResult(developer, mode); + const handleSelectResult = (developer, index) => { + openSearchResult(developer, mode, index + 1); + }; + + const handleBroadenQuery = () => { + const broaderTerms = (searchContext?.interpretedTerms || []).slice(0, -1); + if (!broaderTerms.length) return; + const broaderQuery = broaderTerms.join(' '); + setQuery(broaderQuery); + doSearch(broaderQuery, mode, { remember: true, source: 'broaden_search' }); }; const handleRecentSearch = recent => { @@ -499,7 +527,7 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve {searchContext?.interpretedTerms?.length > 1 && (
- Matched all: + {searchContext.matchMode === 'none' ? 'No strong matches for:' : searchContext.matchMode === 'broadened' ? 'Showing close matches for:' : searchContext.matchMode === 'approximate' ? 'Corrected likely typos in:' : 'Matched all:'} {searchContext.interpretedTerms.join(' + ')}
)} @@ -508,6 +536,11 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve AI ranking is unavailable, so these results use public profile keywords. )} + {resultCount === 0 && searchContext?.interpretedTerms?.length > 1 && ( + + )} {visibleResults.length > 0 && (
{visibleResults.map((developer, index) => ( @@ -515,7 +548,7 @@ export default function SearchBar({ developers, onResults, onReset, onSelectDeve {index === 0 && singleResult && ( diff --git a/lib/analytics.js b/lib/analytics.js index 81962e5..23e796b 100644 --- a/lib/analytics.js +++ b/lib/analytics.js @@ -65,11 +65,27 @@ const ENGAGEMENT_EVENT_MAP = { weekly_digest_returned: 'weekly_digest_returned', primary_action_completed: 'primary_action_completed', }; -const ALLOWED_PROPERTIES = new Set(['action', 'campaign', 'channel', 'journey', 'missionKey', 'outcome', 'responseMinutes', 'source']); +const ALLOWED_STRING_PROPERTIES = new Set([ + 'action', 'campaign', 'channel', 'fallback', 'journey', 'matchMode', 'missionKey', 'outcome', 'source', +]); +const ALLOWED_NUMBER_PROPERTIES = new Map([ + ['responseMinutes', 10080], + ['resultCount', 50], + ['resultRank', 50], + ['termCount', 20], +]); -function safeProperties(properties) { - return Object.fromEntries(Object.entries(properties || {}) - .filter(([key, value]) => ALLOWED_PROPERTIES.has(key) && typeof value === 'string')); +export function safeAnalyticsProperties(properties) { + const safe = {}; + for (const [key, value] of Object.entries(properties || {})) { + if (ALLOWED_STRING_PROPERTIES.has(key) && typeof value === 'string') { + safe[key] = value.slice(0, 100); + } + if (ALLOWED_NUMBER_PROPERTIES.has(key) && Number.isFinite(value)) { + safe[key] = Math.max(0, Math.min(Math.round(value), ALLOWED_NUMBER_PROPERTIES.get(key))); + } + } + return safe; } function send(events) { @@ -93,7 +109,7 @@ export function track(name, properties = {}) { ? { ...properties, source: 'local' } : properties; try { - window.__DEVGLOBE_APP_INSIGHTS__?.trackEvent({ name }, safeProperties(boundedProperties)); + window.__DEVGLOBE_APP_INSIGHTS__?.trackEvent({ name }, safeAnalyticsProperties(boundedProperties)); } catch { // Continue with durable ingestion when the optional RUM client fails. } @@ -102,7 +118,7 @@ export function track(name, properties = {}) { send([{ eventName, targetLogin: properties.login, - properties: safeProperties(boundedProperties), + properties: safeAnalyticsProperties(boundedProperties), }]); } diff --git a/lib/developer-search.js b/lib/developer-search.js index b1cf2cf..baa9071 100644 --- a/lib/developer-search.js +++ b/lib/developer-search.js @@ -8,6 +8,17 @@ const SEARCH_STOP_WORDS = new Set([ 'tools', 'using', 'with', 'working', ]); +const SEARCH_ALIASES = new Map([ + ['ai', ['artificial intelligence']], + ['golang', ['go']], + ['js', ['javascript']], + ['k8s', ['kubernetes']], + ['nodejs', ['node.js', 'node']], + ['py', ['python']], + ['reactjs', ['react']], + ['ts', ['typescript']], +]); + export function tokenizeDeveloperSearchQuery(query) { const normalized = normalizeTextSearchQuery(query).toLowerCase(); const terms = normalized.match(/"[^"]+"|[\p{L}\p{N}+#.-]+/gu) || []; @@ -18,11 +29,12 @@ export function tokenizeDeveloperSearchQuery(query) { return [...new Set(meaningfulTerms.length ? meaningfulTerms : [normalized].filter(Boolean))]; } -export function developerMatchesSearchQuery(developer, query) { - const terms = tokenizeDeveloperSearchQuery(query); - if (!terms.length) return false; +export function searchTermAlternatives(term) { + return [term, ...(SEARCH_ALIASES.get(term) || [])]; +} - const searchableText = [ +function searchableDeveloperText(developer) { + return [ developer?.login, developer?.name, developer?.location, @@ -33,8 +45,76 @@ export function developerMatchesSearchQuery(developer, query) { .filter(Boolean) .join(' ') .toLowerCase(); +} + +function editDistanceWithin(left, right, maximum) { + if (Math.abs(left.length - right.length) > maximum) return false; + let previous = Array.from({ length: right.length + 1 }, (_, index) => index); + for (let leftIndex = 1; leftIndex <= left.length; leftIndex += 1) { + const current = [leftIndex]; + let rowMinimum = current[0]; + for (let rightIndex = 1; rightIndex <= right.length; rightIndex += 1) { + const cost = left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1; + current[rightIndex] = Math.min( + current[rightIndex - 1] + 1, + previous[rightIndex] + 1, + previous[rightIndex - 1] + cost, + ); + rowMinimum = Math.min(rowMinimum, current[rightIndex]); + } + if (rowMinimum > maximum) return false; + previous = current; + } + return previous[right.length] <= maximum; +} + +function matchSearchTerm(text, words, term) { + const alternatives = searchTermAlternatives(term); + if (alternatives.some(alternative => text.includes(alternative))) return 'exact'; + if (term.includes(' ') || term.length < 4) return null; + const maximumDistance = term.length >= 8 ? 2 : 1; + return words.some(word => editDistanceWithin(term, word, maximumDistance)) ? 'approximate' : null; +} + +function scoreDeveloperSearchTerms(developer, terms) { + const text = searchableDeveloperText(developer); + const words = text.match(/[\p{L}\p{N}+#.-]+/gu) || []; + const matches = terms.map(term => matchSearchTerm(text, words, term)); + return { + matchedTerms: matches.filter(Boolean).length, + exactTerms: matches.filter(match => match === 'exact').length, + }; +} + +export function developerMatchesSearchQuery(developer, query) { + const terms = tokenizeDeveloperSearchQuery(query); + if (!terms.length) return false; + return scoreDeveloperSearchTerms(developer, terms).exactTerms === terms.length; +} + +export function rankDeveloperSearchResults(developers, query, limit = 20) { + const interpretedTerms = tokenizeDeveloperSearchQuery(query); + if (!interpretedTerms.length) return { results: [], interpretedTerms, matchMode: 'all' }; + + const scored = developers.map(developer => ({ + developer, + ...scoreDeveloperSearchTerms(developer, interpretedTerms), + })); + const exact = scored.filter(candidate => candidate.exactTerms === interpretedTerms.length); + const approximate = scored.filter(candidate => candidate.matchedTerms === interpretedTerms.length); + const minimumTerms = interpretedTerms.length === 1 ? 1 : Math.max(2, Math.ceil(interpretedTerms.length * 0.6)); + const broadened = scored.filter(candidate => candidate.matchedTerms >= minimumTerms); + const candidates = exact.length ? exact : approximate.length ? approximate : broadened; + const matchMode = exact.length ? 'all' : approximate.length ? 'approximate' : broadened.length ? 'broadened' : 'none'; + const results = candidates + .sort((left, right) => + right.matchedTerms - left.matchedTerms + || right.exactTerms - left.exactTerms + || Number(right.developer?.score || 0) - Number(left.developer?.score || 0)) + .slice(0, limit) + .map(candidate => candidate.developer); - return terms.every(term => searchableText.includes(term)); + return { results, interpretedTerms, matchMode }; } export function findExactLoginResult(query, results = []) { diff --git a/lib/remote-mcp.js b/lib/remote-mcp.js index 669defb..7336df2 100644 --- a/lib/remote-mcp.js +++ b/lib/remote-mcp.js @@ -1,4 +1,5 @@ import { WebStandardStreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js'; +import { LATEST_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS } from '@modelcontextprotocol/sdk/types.js'; import { createDevGlobeMcpClient } from './devglobe-mcp-client.js'; import { createDevGlobeMcpServer } from './devglobe-mcp-server.js'; import { createMcpCallerHash, describeMcpRequest, recordMcpMetric } from './mcp-observability.js'; @@ -118,12 +119,37 @@ export async function handleRemoteMcpRequest(request, { }), request.headers.get('origin')); } - const authorization = request.headers.get('authorization') || ''; const startedAt = performance.now(); + const requestBody = await request.clone().json().catch(() => null); const requestDescription = describeMcpRequest( - await request.clone().json().catch(() => null), + requestBody, request.headers.get('user-agent') || '', ); + const protocolVersion = request.headers.get('mcp-protocol-version'); + if (protocolVersion && !SUPPORTED_PROTOCOL_VERSIONS.includes(protocolVersion)) { + const requestDimensions = { ...requestDescription }; + delete requestDimensions.requestErrorCode; + metricRecorder({ + ...requestDimensions, + outcome: 'error', + durationMs: Math.max(0, Math.round(performance.now() - startedAt)), + callerHash: createMcpCallerHash(request), + errorCode: 'unsupported_protocol_version', + }); + return withSecurityHeaders(Response.json({ + jsonrpc: '2.0', + error: { + code: -32000, + message: `Unsupported protocol version: ${protocolVersion}. Supported versions: ${SUPPORTED_PROTOCOL_VERSIONS.join(', ')}`, + }, + id: requestBody?.id ?? null, + }, { + status: 400, + headers: { 'Mcp-Protocol-Version': LATEST_PROTOCOL_VERSION }, + }), request.headers.get('origin')); + } + + const authorization = request.headers.get('authorization') || ''; const agentToken = authorization.match(/^Bearer\s+(.+)$/i)?.[1]; const client = createDevGlobeMcpClient({ baseUrl: new URL(request.url).origin, diff --git a/package-lock.json b/package-lock.json index 432dce1..356b7c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@fontsource/manrope": "^5.3.0", "@microsoft/applicationinsights-web": "^3.4.3", "@modelcontextprotocol/sdk": "^1.30.0", - "@vercel/og": "^0.11.1", + "@vercel/og": "1.0.1", "d3": "^7.9.0", "dotenv": "^16.4.5", "jose": "^6.2.4", @@ -26,7 +26,7 @@ "rehype-raw": "^7.0.0", "rehype-sanitize": "^6.0.0", "remark-gfm": "^4.0.1", - "sharp": "^0.34.5", + "sharp": "^0.35.4", "simple-icons": "^16.28.0", "twitter-api-v2": "^1.29.1", "zod": "^4.4.3" @@ -632,9 +632,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha1-xxhKMmUz/N8bjuBzPiHHE7l1V18=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha1-gPy+NhMOWLdnBRHoiLjoiiWe12w=", "cpu": [ "ppc64" ], @@ -645,13 +645,13 @@ "aix" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha1-mwQ4T7dxkm36bXrQQyTssqubLig=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha1-MAcSEB9/UPHSYnoWLm4JsQm2dno=", "cpu": [ "arm" ], @@ -662,13 +662,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha1-Cdm0NXeA2p6jp9+4M6Hx/0ObQFI=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha1-iqSWX40KeYLcIXNL9mATI6Ztp1I=", "cpu": [ "arm64" ], @@ -679,13 +679,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha1-KZGOwtt1TO3LbBsE3ozWVHr2Rh4=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha1-h9+ycWEgK9yVjvSLthsJx1j67hY=", "cpu": [ "x64" ], @@ -696,13 +696,13 @@ "android" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha1-5JW1OWYOUWkPOSivUKdvsKbM/yo=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha1-eRl4mOwf90XSHAceHHzDyALwwf0=", "cpu": [ "arm64" ], @@ -713,13 +713,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha1-wTg4+lc3KDmr3dyR1xVCzuouHiI=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha1-FGQAqFYhM/RcTS6tzzfd0JcYB54=", "cpu": [ "x64" ], @@ -730,13 +730,13 @@ "darwin" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha1-ZGuYmqIL+J/Qcd1dv61po1QuVQ4=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha1-HF+bpyBuFY/SskxZ+i0si7R8oP4=", "cpu": [ "arm64" ], @@ -747,13 +747,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha1-qmFc/ICvlU00WJBuOMoiwYz1wmE=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha1-6mMfSja+qsS5J5+g/MbKKerusrM=", "cpu": [ "x64" ], @@ -764,13 +764,13 @@ "freebsd" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha1-/G/RGorKVsH284lPK+oEefj2Jrk=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha1-RSzWayCTLQi9xTqLYcDjC69DSLk=", "cpu": [ "arm" ], @@ -781,13 +781,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha1-cKxvoU9ct+H3+Ie8/7aArQmSK1s=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha1-4QZrzlg5TxsRQd7shVel8KIvWXc=", "cpu": [ "arm64" ], @@ -798,13 +798,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha1-MnH1Oz+T49CT1RjRZJ1taNNG7eI=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha1-sk+KzEW89UGSx/LzvhtT5lUer+A=", "cpu": [ "ia32" ], @@ -815,13 +815,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha1-7WLgQjjFcCauqDHFoTC3PA+fJt8=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha1-+c//p/yDIlcfvEyLMmjK8VvYGtA=", "cpu": [ "loong64" ], @@ -832,13 +832,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha1-55uOtIvzsQb63sGsgkD7l7TmTL4=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha1-V1oUvXRkT/q4ka3H1+YNJ1KW8s0=", "cpu": [ "mips64el" ], @@ -849,13 +849,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha1-XyIDhgoUO5kZ04PvdXNSH7FUw+Q=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha1-dbmccKlfvV93OddpK+/mBgFZGGk=", "cpu": [ "ppc64" ], @@ -866,13 +866,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha1-B7yv2ZMi1a9i9hjLnmqbf0u4Jdw=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha1-LjJZRAMhpE553fdTXDJQV9qHXNY=", "cpu": [ "riscv64" ], @@ -883,13 +883,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha1-t8z2hnUdaj5EuGJ6uryL4+9i2N4=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha1-F2dsq7/lko2lsqDW311YzQjbJmM=", "cpu": [ "s390x" ], @@ -900,13 +900,13 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha1-bY8Mdo4HDmQwmvgAS7lOaKsrs7A=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha1-BYN3VoXKggZtBMNQfwlSTTzXowY=", "cpu": [ "x64" ], @@ -917,13 +917,30 @@ "linux" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha1-8ExAScsuJS/paxb+2Q9wdGsT9KQ=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha1-u+Qw9g03jsuI3sshnGAmZzh6YEc=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha1-d9oNCg2CbXySHuo9QCklSLJYoHY=", "cpu": [ "x64" ], @@ -934,13 +951,30 @@ "netbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha1-Ypb1hnrt7yioGyKrIAnHhqlS3M0=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha1-mdHPKTcnlWDSEEgh9czOIgyyr3A=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha1-+NIzAzYOJ7Fs8GWyO7/0PBQUJnk=", "cpu": [ "x64" ], @@ -951,13 +985,30 @@ "openbsd" ], "engines": { - "node": ">=12" + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha1-SeC3aHRKOSS+DX/ZfdbOmykj2I0=", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha1-CHQVEsENUpVmurqDe0/gUsjzSHs=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha1-pu19Z3jWflKMgfsWWyP0kRubE9Y=", "cpu": [ "x64" ], @@ -968,13 +1019,13 @@ "sunos" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha1-Z1tzhTmEESQHNQFhRKsumaYPx10=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha1-msFMN44bZTrxfQjn0840yu9YcyM=", "cpu": [ "arm64" ], @@ -985,13 +1036,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha1-G/w86YqmypoJaeTSr3IUTFnBGTs=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha1-kYlC3LuzXMFPyjmvuRteaj0Scmc=", "cpu": [ "ia32" ], @@ -1002,13 +1053,13 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha1-rK01HVgtFXuxRVNdsqb/U91RS1w=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha1-m9rYF2vngRrRSNH4dyNZBB9GxsU=", "cpu": [ "x64" ], @@ -1019,7 +1070,7 @@ "win32" ], "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -1280,9 +1331,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.34.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.5.tgz", - "integrity": "sha1-bgcy3K3hJrZnCveqFwYLkmg16oY=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", + "integrity": "sha1-vBCyYt4vyACIAT9fmYKY0ciQn78=", "cpu": [ "arm64" ], @@ -1292,19 +1343,19 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.2.4" + "@img/sharp-libvips-darwin-arm64": "1.3.3" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.34.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.5.tgz", - "integrity": "sha1-Gbwd1uum1alig0mLnJ9AEYDunHs=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", + "integrity": "sha1-dsSf8E+z+dhGsNBXWEG37lm+7Gg=", "cpu": [ "x64" ], @@ -1314,19 +1365,38 @@ "darwin" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.2.4" + "@img/sharp-libvips-darwin-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", + "integrity": "sha1-ulX9YDxdHQGhyxT/tNlwvGztgOE=", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.2.4", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.4.tgz", - "integrity": "sha1-KJTAy4fUInbDiJlC6OLbUXpJLEM=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", + "integrity": "sha1-CKbPT7TujUX5lASladyqayk5HZc=", "cpu": [ "arm64" ], @@ -1340,9 +1410,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.2.4", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.4.tgz", - "integrity": "sha1-5jaB9FOalK+c0XJG7YiBc0OG+Mw=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", + "integrity": "sha1-FGHm+zEKhps8E1BFibjdXAZiTag=", "cpu": [ "x64" ], @@ -1356,12 +1426,15 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.2.4", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.4.tgz", - "integrity": "sha1-uSYN0evm+eO9vL3KydKsEl81hS0=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", + "integrity": "sha1-cQMpQbn8v468PBtilJknuETLrWI=", "cpu": [ "arm" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1372,12 +1445,15 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.2.4", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.4.tgz", - "integrity": "sha1-sbKIs2hks7zlRa2R+m2tzxpK0xg=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", + "integrity": "sha1-y5OKOXG5o2MpvJlCfx5bcuJmui4=", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1388,12 +1464,15 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.2.4", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.4.tgz", - "integrity": "sha1-S4Ps8qgpBXIis4hIx7Ai57TQeqc=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", + "integrity": "sha1-gkbS3sFSNP0cxUzFXcuhrrwmxBQ=", "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1404,12 +1483,15 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.2.4", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.2.4.tgz", - "integrity": "sha1-iAtGeACeWiCArxkjMrALCq+KSN4=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", + "integrity": "sha1-Wf9mPCqmtBiFc1fNd8pMyuzpWHY=", "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1420,12 +1502,15 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.2.4", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.4.tgz", - "integrity": "sha1-dPNDyOEPrYIbOPdc7TBIiTncWew=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", + "integrity": "sha1-vBdFH4DZ8xZjs+kGFJ8Vmg7LHKg=", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1436,12 +1521,15 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.2.4", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.4.tgz", - "integrity": "sha1-30GD6L2EEPfWG2aFmjXt6rClMc4=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", + "integrity": "sha1-x9H4O8HP4iLNnckn88UTeql5HnY=", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1452,12 +1540,15 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.2.4", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.4.tgz", - "integrity": "sha1-yNa0ghHfZxN1QQB+6NG3sfjKjgY=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", + "integrity": "sha1-MD3+Ko5tH9J56tVZ9NLM/yVF4qI=", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1468,12 +1559,15 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.2.4", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.4.tgz", - "integrity": "sha1-vhHHW+5bCAy+4xoVOod5RI+Rn3U=", + "version": "1.3.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", + "integrity": "sha1-N1D3CtRq2H5KCO6NNyq5p+F+K2w=", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "LGPL-3.0-or-later", "optional": true, "os": [ @@ -1484,204 +1578,244 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.34.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.5.tgz", - "integrity": "sha1-X7DDaV3RJSLTnD/3pryBZGF4Cg0=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", + "integrity": "sha1-3o2g2i7lUiZ8rncVlzMqhjN45Ds=", "cpu": [ "arm" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.2.4" + "@img/sharp-libvips-linux-arm": "1.3.3" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.34.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.5.tgz", - "integrity": "sha1-eqd2TvnAAfFeYQVG1C/OVpEXkMw=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", + "integrity": "sha1-wvU7+RP6G0Z2KxksUnorNkeiEag=", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.2.4" + "@img/sharp-libvips-linux-arm64": "1.3.3" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.34.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.5.tgz", - "integrity": "sha1-nCE6gVIKIMr2aXjz1MB0Vv8uCBM=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", + "integrity": "sha1-xA18X4ziFsNSJMWO3O+OZEWTUlY=", "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.2.4" + "@img/sharp-libvips-linux-ppc64": "1.3.3" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.34.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.34.5.tgz", - "integrity": "sha1-zdKBgndOrb4E9iZ1oWqrvMuDP2A=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", + "integrity": "sha1-AyyiBucTsRee/g4Y1SUYjGcndzA=", "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.2.4" + "@img/sharp-libvips-linux-riscv64": "1.3.3" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.34.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.5.tgz", - "integrity": "sha1-k+rGAbnzKbsnkX4OGQmMci1jDfc=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", + "integrity": "sha1-GdrHUBoVyHSLx6ESGfyjkeQkttc=", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.2.4" + "@img/sharp-libvips-linux-s390x": "1.3.3" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.34.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.5.tgz", - "integrity": "sha1-VavHzXVP/KUAK2wrcZq9/IRoGag=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", + "integrity": "sha1-fR1BTUpTjgcEumt2zmVH5g9iEc4=", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.2.4" + "@img/sharp-libvips-linux-x64": "1.3.3" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.34.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.5.tgz", - "integrity": "sha1-1lFe6XG7YvcwAaSCm52GWhG3cIY=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", + "integrity": "sha1-lTTJOAeCL0KC0HmjIvrMbbU9UPY=", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.34.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.5.tgz", - "integrity": "sha1-2Xl4rsfFIS+ZlxTy9bc2RX4S7p8=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", + "integrity": "sha1-9IjnoCkZkb/2Q874K1r9PP1w/PI=", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "Apache-2.0", "optional": true, "os": [ "linux" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.2.4" + "@img/sharp-libvips-linuxmusl-x64": "1.3.3" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.34.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-wasm32/-/sharp-wasm32-0.34.5.tgz", - "integrity": "sha1-LxWAOqYm+MWd18nQu8dm8atSz6A=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", + "integrity": "sha1-gfcfP8DYRH3Dr2yzeOJOdY/1QiU=", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", + "integrity": "sha1-d9LoiS06OCXw3JWrAs62E8shMoY=", "cpu": [ "wasm32" ], - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "license": "Apache-2.0", "optional": true, "dependencies": { - "@emnapi/runtime": "^1.7.0" + "@img/sharp-wasm32": "0.35.4" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.34.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.5.tgz", - "integrity": "sha1-Nwbp46w1/d/ByH+U6Enxt1MHzgo=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", + "integrity": "sha1-QQG0Tj+5fW8ac8KpxhQtSR0aqDE=", "cpu": [ "arm64" ], @@ -1691,16 +1825,16 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.34.5", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.5.tgz", - "integrity": "sha1-C3EWZZmwSeAy8IX7kmPgL05HiN4=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", + "integrity": "sha1-jUdVvSbV/zT7iceQe9icCApdyfU=", "cpu": [ "ia32" ], @@ -1710,16 +1844,16 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": "^20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.34.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.5.tgz", - "integrity": "sha1-qB/7AOaSZ80KHWJurtuKhDCysvg=", + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", + "integrity": "sha1-C2e9Cx8BEjqYKvzGug3AC4d7igo=", "cpu": [ "x64" ], @@ -1729,7 +1863,7 @@ "win32" ], "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" @@ -2001,9 +2135,9 @@ "license": "MIT" }, "node_modules/@next/env": { - "version": "15.5.22", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/env/-/env-15.5.22.tgz", - "integrity": "sha1-yzIbfq/HUhheThQglXgs9srX7qQ=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/env/-/env-15.5.25.tgz", + "integrity": "sha1-v35a/Q8Yan09d+XRrIu0pos0giA=", "license": "MIT" }, "node_modules/@next/eslint-plugin-next": { @@ -2017,9 +2151,9 @@ } }, "node_modules/@next/swc-darwin-arm64": { - "version": "15.5.22", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.22.tgz", - "integrity": "sha1-jPXF/FnCaFpYYiLKrvO5DHIiPiE=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.25.tgz", + "integrity": "sha1-QFES9BcXaqwpzDR9LppIUbVuI/c=", "cpu": [ "arm64" ], @@ -2033,9 +2167,9 @@ } }, "node_modules/@next/swc-darwin-x64": { - "version": "15.5.22", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.22.tgz", - "integrity": "sha1-EWALp7jKiihrtlV6J/wpTuH4mKs=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.25.tgz", + "integrity": "sha1-OWy67VclDB8Xa9KomPOR5Wp2edo=", "cpu": [ "x64" ], @@ -2049,12 +2183,15 @@ } }, "node_modules/@next/swc-linux-arm64-gnu": { - "version": "15.5.22", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.22.tgz", - "integrity": "sha1-Db0pHu57pgAL4dE+xK5LHrMX2U8=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.25.tgz", + "integrity": "sha1-rkWneNBP1koo/eEcnJSpShw3EmI=", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2065,12 +2202,15 @@ } }, "node_modules/@next/swc-linux-arm64-musl": { - "version": "15.5.22", - "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.22.tgz", - "integrity": "sha1-LnZXaory1qOP/frVdzcYj117Jas=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.25.tgz", + "integrity": "sha1-ZaUwOePkX48SKrY8C0jGNj1rLa4=", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2081,12 +2221,15 @@ } }, "node_modules/@next/swc-linux-x64-gnu": { - "version": "15.5.22", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.22.tgz", - "integrity": "sha1-RkbqKMQwc8clSy52wCDwOwdJxT8=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.25.tgz", + "integrity": "sha1-KrAluam6X2phj7IQrLaHTQzpQuI=", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2097,12 +2240,15 @@ } }, "node_modules/@next/swc-linux-x64-musl": { - "version": "15.5.22", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.22.tgz", - "integrity": "sha1-7mjSbrSd2eweiboX/vk3/st0bqo=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.25.tgz", + "integrity": "sha1-HI8zvmGhzOuRc2Ijom3Y3x9nUqQ=", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2113,9 +2259,9 @@ } }, "node_modules/@next/swc-win32-arm64-msvc": { - "version": "15.5.22", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.22.tgz", - "integrity": "sha1-hDouR0QskDN/9zuF3/e8nvexo0w=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.25.tgz", + "integrity": "sha1-kJWlmAdUmaM9qXPFB/sCp/DKhtU=", "cpu": [ "arm64" ], @@ -2129,9 +2275,9 @@ } }, "node_modules/@next/swc-win32-x64-msvc": { - "version": "15.5.22", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.22.tgz", - "integrity": "sha1-cLmH1FRJnrjijpE1DRYRL45vcfk=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.25.tgz", + "integrity": "sha1-ZgzEefxnfpkFBolaGL/p+UzF0x4=", "cpu": [ "x64" ], @@ -2193,9 +2339,9 @@ } }, "node_modules/@resvg/resvg-wasm": { - "version": "2.4.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@resvg/resvg-wasm/-/resvg-wasm-2.4.0.tgz", - "integrity": "sha1-4BFkuaJnyCLh/3l9qi+5G2Y+pvA=", + "version": "2.4.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@resvg/resvg-wasm/-/resvg-wasm-2.4.1.tgz", + "integrity": "sha1-iPeggQe/XqaRsBblXm25VchdhFw=", "license": "MPL-2.0", "engines": { "node": ">= 10" @@ -2693,7 +2839,7 @@ }, "node_modules/@shuding/opentype.js": { "version": "1.4.0-beta.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@shuding/opentype.js/-/opentype.js-1.4.0-beta.0.tgz", "integrity": "sha1-XR5+ngVvVGqtQd8cUEP4+F054ks=", "license": "MIT", "dependencies": { @@ -3527,19 +3673,19 @@ ] }, "node_modules/@vercel/og": { - "version": "0.11.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vercel/og/-/og-0.11.1.tgz", - "integrity": "sha1-mF0DUKpX5BmF5tOq4t/yXSyVzUY=", + "version": "1.0.1", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/@vercel/og/-/og-1.0.1.tgz", + "integrity": "sha1-gHqsyYhKndm+l1Kp6ehwPAdWmGE=", "license": "MPL-2.0", "dependencies": { - "@resvg/resvg-wasm": "2.4.0", - "satori": "0.25.0" + "@resvg/resvg-wasm": "2.4.1", + "satori": "0.29.0" }, "engines": { - "node": ">=16" + "node": ">=22" }, "optionalDependencies": { - "sharp": "^0.34.5" + "sharp": "^0.35.3" } }, "node_modules/@vitejs/plugin-vue": { @@ -4206,7 +4352,7 @@ }, "node_modules/base64-js": { "version": "0.0.8", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/base64-js/-/base64-js-0.0.8.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/base64-js/-/base64-js-0.0.8.tgz", "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", "license": "MIT", "engines": { @@ -4369,7 +4515,7 @@ }, "node_modules/camelize": { "version": "1.0.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/camelize/-/camelize-1.0.1.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/camelize/-/camelize-1.0.1.tgz", "integrity": "sha1-ibfhaIQFYzGjXWta0GQzLJHapsM=", "license": "MIT", "funding": { @@ -4603,19 +4749,19 @@ }, "node_modules/css-background-parser": { "version": "0.1.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-background-parser/-/css-background-parser-0.1.0.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-background-parser/-/css-background-parser-0.1.0.tgz", "integrity": "sha1-SKF/f+bU1PG8oxd93xbFYXlQdBs=", "license": "MIT" }, "node_modules/css-box-shadow": { "version": "1.0.0-3", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-box-shadow/-/css-box-shadow-1.0.0-3.tgz", "integrity": "sha1-nq63FAlHv11kn8SaGeS7ql9gJxM=", "license": "MIT" }, "node_modules/css-color-keywords": { "version": "1.0.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-color-keywords/-/css-color-keywords-1.0.0.tgz", "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=", "license": "ISC", "engines": { @@ -4624,7 +4770,7 @@ }, "node_modules/css-gradient-parser": { "version": "0.0.17", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-gradient-parser/-/css-gradient-parser-0.0.17.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-gradient-parser/-/css-gradient-parser-0.0.17.tgz", "integrity": "sha1-mlI0GfMorSd3rnkMKWppMtRwqpo=", "license": "MIT", "engines": { @@ -4633,7 +4779,7 @@ }, "node_modules/css-to-react-native": { "version": "3.2.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-to-react-native/-/css-to-react-native-3.2.0.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/css-to-react-native/-/css-to-react-native-3.2.0.tgz", "integrity": "sha1-zdgJn3ECThSeT2/hen1G7NVfHjI=", "license": "MIT", "dependencies": { @@ -5347,7 +5493,7 @@ }, "node_modules/emoji-regex-xs": { "version": "2.0.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/emoji-regex-xs/-/emoji-regex-xs-2.0.1.tgz", "integrity": "sha1-AS9OTYjs7IOX3zLVtO+J1CJVnA4=", "license": "MIT", "engines": { @@ -5573,9 +5719,9 @@ } }, "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha1-nKMBsSCSKVm3ZjYNisgw2g0CmX0=", + "version": "0.25.12", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha1-l6HQQfSrAML84vg40rmWmi0ql6U=", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -5583,32 +5729,35 @@ "esbuild": "bin/esbuild" }, "engines": { - "node": ">=12" + "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" } }, "node_modules/escape-html": { @@ -6202,9 +6351,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-uri/-/fast-uri-3.1.5.tgz", - "integrity": "sha1-YQ83QZoDAnBDDOzWjXTj1NlnJdA=", + "version": "3.1.8", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fast-uri/-/fast-uri-3.1.8.tgz", + "integrity": "sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==", "funding": [ { "type": "github", @@ -6252,7 +6401,7 @@ }, "node_modules/fflate": { "version": "0.7.5", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fflate/-/fflate-0.7.5.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fflate/-/fflate-0.7.5.tgz", "integrity": "sha1-Hfy3GJvBBNWZ2gQ26s4U7Sbeh58=", "license": "MIT" }, @@ -6905,7 +7054,7 @@ }, "node_modules/hex-rgb": { "version": "4.3.0", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hex-rgb/-/hex-rgb-4.3.0.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hex-rgb/-/hex-rgb-4.3.0.tgz", "integrity": "sha1-r16XToO7L+/kTVUYKwBOyBjAd3Y=", "license": "MIT", "engines": { @@ -6916,9 +7065,9 @@ } }, "node_modules/hono": { - "version": "4.13.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hono/-/hono-4.13.0.tgz", - "integrity": "sha1-rBuhZQtP2cvlPhe+oFJfU8tlgT0=", + "version": "4.13.8", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/hono/-/hono-4.13.8.tgz", + "integrity": "sha512-/Gng7NfoykZl2pjukW5Z6+8Yxm3BPRf86GTbQnt0SbySkvax4fyL4H3HhY1cCpBGmiW9XDRFzRV+CXK2W8QudQ==", "license": "MIT", "engines": { "node": ">=16.9.0" @@ -7658,9 +7807,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "4.3.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/js-yaml/-/js-yaml-4.3.1.tgz", - "integrity": "sha1-ASFsAB1n9I4s1WDXCMevIQkKOEg=", + "version": "4.3.2", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha1-jkT7FKJkPFlya7FXh7XxUSyz0/s=", "dev": true, "funding": [ { @@ -7794,7 +7943,7 @@ }, "node_modules/linebreak": { "version": "1.1.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/linebreak/-/linebreak-1.1.0.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/linebreak/-/linebreak-1.1.0.tgz", "integrity": "sha1-gxzzeNmLztOB2KsRj4Ur1Q2B5Gs=", "license": "MIT", "dependencies": { @@ -8911,12 +9060,12 @@ } }, "node_modules/next": { - "version": "15.5.22", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/next/-/next-15.5.22.tgz", - "integrity": "sha1-Ag3eo6bpvtYLUYF/TNWFhwKEf1M=", + "version": "15.5.25", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/next/-/next-15.5.25.tgz", + "integrity": "sha1-ViYFs0OHFgAUgx5gTKo/m8/Diqo=", "license": "MIT", "dependencies": { - "@next/env": "15.5.22", + "@next/env": "15.5.25", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", @@ -8929,15 +9078,15 @@ "node": "^18.18.0 || ^19.8.0 || >= 20.0.0" }, "optionalDependencies": { - "@next/swc-darwin-arm64": "15.5.22", - "@next/swc-darwin-x64": "15.5.22", - "@next/swc-linux-arm64-gnu": "15.5.22", - "@next/swc-linux-arm64-musl": "15.5.22", - "@next/swc-linux-x64-gnu": "15.5.22", - "@next/swc-linux-x64-musl": "15.5.22", - "@next/swc-win32-arm64-msvc": "15.5.22", - "@next/swc-win32-x64-msvc": "15.5.22", - "sharp": "^0.34.3" + "@next/swc-darwin-arm64": "15.5.25", + "@next/swc-darwin-x64": "15.5.25", + "@next/swc-linux-arm64-gnu": "15.5.25", + "@next/swc-linux-arm64-musl": "15.5.25", + "@next/swc-linux-x64-gnu": "15.5.25", + "@next/swc-linux-x64-musl": "15.5.25", + "@next/swc-win32-arm64-msvc": "15.5.25", + "@next/swc-win32-x64-msvc": "15.5.25", + "sharp": "^0.34.3 || ^0.35.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", @@ -9280,7 +9429,7 @@ }, "node_modules/parse-css-color": { "version": "0.2.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/parse-css-color/-/parse-css-color-0.2.1.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/parse-css-color/-/parse-css-color-0.2.1.tgz", "integrity": "sha1-toelg/LkLmb/386ApXBwaWboB8k=", "license": "MIT", "dependencies": { @@ -9561,9 +9710,9 @@ } }, "node_modules/qs": { - "version": "6.15.3", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/qs/-/qs-6.15.3.tgz", - "integrity": "sha1-doUhMqWO1cfA72fkRBubtdYGGzs=", + "version": "6.16.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/qs/-/qs-6.16.0.tgz", + "integrity": "sha1-wixyOiipIPOqzc6Cifq9Q+zLef0=", "license": "BSD-3-Clause", "dependencies": { "es-define-property": "^1.0.1", @@ -10124,9 +10273,9 @@ "license": "MIT" }, "node_modules/satori": { - "version": "0.25.0", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/satori/-/satori-0.25.0.tgz", - "integrity": "sha1-bQglSvvU4BDLAaeGKOwBAfHhT6Y=", + "version": "0.29.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/satori/-/satori-0.29.0.tgz", + "integrity": "sha1-3XSZC3zBPWgFi2618KhCmM+AR/4=", "license": "MPL-2.0", "dependencies": { "@shuding/opentype.js": "1.4.0-beta.0", @@ -10280,47 +10429,52 @@ "license": "ISC" }, "node_modules/sharp": { - "version": "0.34.5", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/sharp/-/sharp-0.34.5.tgz", - "integrity": "sha1-tvFI5LjGHxeXveEanRz+u64sV7A=", - "hasInstallScript": true, + "version": "0.35.4", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/sharp/-/sharp-0.35.4.tgz", + "integrity": "sha1-Nh3zspWdrrOAVBKJlgRWxr4Pkt4=", "license": "Apache-2.0", "dependencies": { - "@img/colour": "^1.0.0", + "@img/colour": "^1.1.0", "detect-libc": "^2.1.2", - "semver": "^7.7.3" + "semver": "^7.8.5" }, "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + "node": ">=20.9.0" }, "funding": { "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.34.5", - "@img/sharp-darwin-x64": "0.34.5", - "@img/sharp-libvips-darwin-arm64": "1.2.4", - "@img/sharp-libvips-darwin-x64": "1.2.4", - "@img/sharp-libvips-linux-arm": "1.2.4", - "@img/sharp-libvips-linux-arm64": "1.2.4", - "@img/sharp-libvips-linux-ppc64": "1.2.4", - "@img/sharp-libvips-linux-riscv64": "1.2.4", - "@img/sharp-libvips-linux-s390x": "1.2.4", - "@img/sharp-libvips-linux-x64": "1.2.4", - "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", - "@img/sharp-libvips-linuxmusl-x64": "1.2.4", - "@img/sharp-linux-arm": "0.34.5", - "@img/sharp-linux-arm64": "0.34.5", - "@img/sharp-linux-ppc64": "0.34.5", - "@img/sharp-linux-riscv64": "0.34.5", - "@img/sharp-linux-s390x": "0.34.5", - "@img/sharp-linux-x64": "0.34.5", - "@img/sharp-linuxmusl-arm64": "0.34.5", - "@img/sharp-linuxmusl-x64": "0.34.5", - "@img/sharp-wasm32": "0.34.5", - "@img/sharp-win32-arm64": "0.34.5", - "@img/sharp-win32-ia32": "0.34.5", - "@img/sharp-win32-x64": "0.34.5" + "@img/sharp-darwin-arm64": "0.35.4", + "@img/sharp-darwin-x64": "0.35.4", + "@img/sharp-freebsd-wasm32": "0.35.4", + "@img/sharp-libvips-darwin-arm64": "1.3.3", + "@img/sharp-libvips-darwin-x64": "1.3.3", + "@img/sharp-libvips-linux-arm": "1.3.3", + "@img/sharp-libvips-linux-arm64": "1.3.3", + "@img/sharp-libvips-linux-ppc64": "1.3.3", + "@img/sharp-libvips-linux-riscv64": "1.3.3", + "@img/sharp-libvips-linux-s390x": "1.3.3", + "@img/sharp-libvips-linux-x64": "1.3.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", + "@img/sharp-libvips-linuxmusl-x64": "1.3.3", + "@img/sharp-linux-arm": "0.35.4", + "@img/sharp-linux-arm64": "0.35.4", + "@img/sharp-linux-ppc64": "0.35.4", + "@img/sharp-linux-riscv64": "0.35.4", + "@img/sharp-linux-s390x": "0.35.4", + "@img/sharp-linux-x64": "0.35.4", + "@img/sharp-linuxmusl-arm64": "0.35.4", + "@img/sharp-linuxmusl-x64": "0.35.4", + "@img/sharp-webcontainers-wasm32": "0.35.4", + "@img/sharp-win32-arm64": "0.35.4", + "@img/sharp-win32-ia32": "0.35.4", + "@img/sharp-win32-x64": "0.35.4" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, "node_modules/shebang-command": { @@ -10519,7 +10673,7 @@ }, "node_modules/string.prototype.codepointat": { "version": "0.2.1", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz", "integrity": "sha1-AErUTIr8cnUnsQjNRitNlxzUabw=", "license": "MIT" }, @@ -10874,7 +11028,7 @@ }, "node_modules/tiny-inflate": { "version": "1.0.3", - "resolved": "https://ms-feed-2.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tiny-inflate/-/tiny-inflate-1.0.3.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/tiny-inflate/-/tiny-inflate-1.0.3.tgz", "integrity": "sha1-EicVSUkToYBRZqr3yTRnkz7qJsQ=", "license": "MIT" }, @@ -11170,7 +11324,7 @@ }, "node_modules/unicode-trie": { "version": "2.0.0", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unicode-trie/-/unicode-trie-2.0.0.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/unicode-trie/-/unicode-trie-2.0.0.tgz", "integrity": "sha1-j9iEVpbi4UqLZ9ePqeDdLK1i/sg=", "license": "MIT", "dependencies": { @@ -11374,21 +11528,24 @@ } }, "node_modules/vite": { - "version": "5.4.21", - "resolved": "https://ms-feed-12.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vite/-/vite-5.4.21.tgz", - "integrity": "sha1-hKT3xdhgsHFnbTm6UTwNWY/ccCc=", + "version": "6.4.3", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vite/-/vite-6.4.3.tgz", + "integrity": "sha1-haFk23znBvKndoEu+is0DxchhY4=", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" }, "engines": { - "node": "^18.0.0 || >=20.0.0" + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" }, "funding": { "url": "https://github.com/vitejs/vite?sponsor=1" @@ -11397,19 +11554,25 @@ "fsevents": "~2.3.3" }, "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", - "terser": "^5.4.0" + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" }, "peerDependenciesMeta": { "@types/node": { "optional": true }, + "jiti": { + "optional": true + }, "less": { "optional": true }, @@ -11430,9 +11593,46 @@ }, "terser": { "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha1-7Sq5Z6MxreYvGNB32uGSaE1Q01A=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true } } }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha1-YxM2ADTMs2s9xh7L3/eBIfkP4h8=", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vitepress": { "version": "1.6.4", "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/vitepress/-/vitepress-1.6.4.tgz", @@ -11651,7 +11851,7 @@ }, "node_modules/yoga-layout": { "version": "3.2.1", - "resolved": "https://ms-feed-17.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yoga-layout/-/yoga-layout-3.2.1.tgz", + "resolved": "https://ms-feed-25.pkgs.visualstudio.com/1es-public/_packaging/npm-public/npm/registry/yoga-layout/-/yoga-layout-3.2.1.tgz", "integrity": "sha1-0tG6BvDoHC62UMPlrYsLSt3h6EM=", "license": "MIT" }, diff --git a/package.json b/package.json index 439a985..612efc4 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "@fontsource/manrope": "^5.3.0", "@microsoft/applicationinsights-web": "^3.4.3", "@modelcontextprotocol/sdk": "^1.30.0", - "@vercel/og": "^0.11.1", + "@vercel/og": "1.0.1", "d3": "^7.9.0", "dotenv": "^16.4.5", "jose": "^6.2.4", @@ -64,7 +64,7 @@ "rehype-raw": "^7.0.0", "rehype-sanitize": "^6.0.0", "remark-gfm": "^4.0.1", - "sharp": "^0.34.5", + "sharp": "^0.35.4", "simple-icons": "^16.28.0", "twitter-api-v2": "^1.29.1", "zod": "^4.4.3" @@ -76,6 +76,7 @@ }, "overrides": { "nanoid": "3.3.18", - "postcss": "8.5.26" + "postcss": "8.5.26", + "vite": "6.4.3" } } diff --git a/styles/main.css b/styles/main.css index 2479024..e479421 100644 --- a/styles/main.css +++ b/styles/main.css @@ -944,7 +944,7 @@ body { .search-bar__advanced-content { display: flex; - align-items: end; + align-items: flex-end; gap: 10px; padding: 0 12px 12px; border-top: 1px solid var(--border); @@ -1260,6 +1260,22 @@ body { color: var(--accent-github); } +.search-bar__broaden { + min-height: 32px; + margin-top: 8px; + padding: 5px 9px; + border: 1px solid var(--border); + border-radius: 6px; + background: var(--overlay-hover); + color: var(--text-primary); + font: inherit; + cursor: pointer; +} + +.search-bar__broaden:hover { + border-color: var(--accent-github); +} + .search-bar__reset { display: inline-flex; align-items: center; diff --git a/tests/analytics.test.js b/tests/analytics.test.js new file mode 100644 index 0000000..ac1880f --- /dev/null +++ b/tests/analytics.test.js @@ -0,0 +1,34 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import { safeAnalyticsProperties } from '../lib/analytics.js'; + +test('keeps bounded search dimensions without retaining raw queries', () => { + assert.deepEqual(safeAnalyticsProperties({ + query: 'private search wording', + termCount: 4, + resultCount: 12, + resultRank: 3, + matchMode: 'broadened', + fallback: 'none', + }), { + termCount: 4, + resultCount: 12, + resultRank: 3, + matchMode: 'broadened', + fallback: 'none', + }); +}); + +test('clamps numeric analytics dimensions and bounds strings', () => { + assert.deepEqual(safeAnalyticsProperties({ + resultCount: 500, + resultRank: -2, + termCount: 100, + source: 'x'.repeat(120), + }), { + resultCount: 50, + resultRank: 0, + termCount: 20, + source: 'x'.repeat(100), + }); +}); \ No newline at end of file diff --git a/tests/developer-search.test.js b/tests/developer-search.test.js index e723ed0..bbf1f4c 100644 --- a/tests/developer-search.test.js +++ b/tests/developer-search.test.js @@ -4,6 +4,8 @@ import { developerMatchesSearchQuery, findExactLoginResult, normalizeTextSearchQuery, + rankDeveloperSearchResults, + searchTermAlternatives, tokenizeDeveloperSearchQuery, } from '../lib/developer-search.js'; @@ -51,4 +53,54 @@ test('matches natural-language intent across developer fields and tags', () => { assert.equal(developerMatchesSearchQuery(developer, 'open source maintainer'), true); assert.equal(developerMatchesSearchQuery(developer, 'AI agent builder using MCP'), true); assert.equal(developerMatchesSearchQuery(developer, 'Python developer in India'), false); +}); + +test('expands bounded programming aliases without changing the interpreted query', () => { + assert.deepEqual(searchTermAlternatives('ts'), ['ts', 'typescript']); + assert.deepEqual(searchTermAlternatives('unknown'), ['unknown']); + assert.deepEqual(tokenizeDeveloperSearchQuery('TS developer in India'), ['ts', 'india']); +}); + +test('ranks exact all-term matches before profile score', () => { + const developers = [ + { login: 'high-score', topLanguage: 'Python', location: 'India', score: 99 }, + { login: 'exact-match', topLanguage: 'TypeScript', location: 'India', score: 40 }, + ]; + + const search = rankDeveloperSearchResults(developers, 'TypeScript developer in India'); + + assert.equal(search.matchMode, 'all'); + assert.deepEqual(search.results.map(developer => developer.login), ['exact-match']); +}); + +test('uses bounded typo tolerance before broadening', () => { + const developers = [ + { login: 'typed', topLanguage: 'TypeScript', location: 'Bengaluru, India', score: 60 }, + ]; + + const search = rankDeveloperSearchResults(developers, 'Typescrpt developer in India'); + + assert.equal(search.matchMode, 'approximate'); + assert.deepEqual(search.results.map(developer => developer.login), ['typed']); +}); + +test('broadens multi-term searches only when strict matching has no results', () => { + const developers = [ + { login: 'partial', bio: 'Open source maintainer', topLanguage: 'Go', score: 80 }, + { login: 'weak', bio: 'Open source contributor', topLanguage: 'Rust', score: 95 }, + ]; + + const search = rankDeveloperSearchResults(developers, 'open source maintainer kubernetes'); + + assert.equal(search.matchMode, 'broadened'); + assert.deepEqual(search.results.map(developer => developer.login), ['partial']); +}); + +test('reports no match mode when broadening finds no relevant candidates', () => { + const search = rankDeveloperSearchResults([ + { login: 'python-dev', topLanguage: 'Python' }, + ], 'typescript maintainer canada'); + + assert.equal(search.matchMode, 'none'); + assert.deepEqual(search.results, []); }); \ No newline at end of file diff --git a/tests/remote-mcp.test.js b/tests/remote-mcp.test.js index 1086597..9dce160 100644 --- a/tests/remote-mcp.test.js +++ b/tests/remote-mcp.test.js @@ -298,13 +298,21 @@ test('MCP classifies malformed and unknown requests with bounded error codes', a test('MCP classifies unsupported protocol versions separately from upstream failures', async () => { const metrics = []; + let serverCreated = false; const response = await handleRemoteMcpRequest(mcpRequest({ jsonrpc: '2.0', id: 20, method: 'tools/list', params: {}, }, { 'Mcp-Protocol-Version': '2099-01-01' }), { metricRecorder: metric => metrics.push(metric), + serverFactory: () => { + serverCreated = true; + throw new Error('unsupported requests must not allocate a server'); + }, }); assert.equal(response.status, 400); + assert.equal(serverCreated, false); + assert.match(response.headers.get('mcp-protocol-version'), /^\d{4}-\d{2}-\d{2}$/); + assert.match((await response.json()).error.message, /Supported versions:/); assert.equal(metrics[0].outcome, 'error'); assert.equal(metrics[0].errorCode, 'unsupported_protocol_version'); });