define(function(require,exports,module){const NodeUtils=brackets.getModule("utils/NodeUtils"),NotificationUI=brackets.getModule("widgets/NotificationUI"),TaskManager=brackets.getModule("features/TaskManager"),PreferencesManager=brackets.getModule("preferences/PreferencesManager"),Metrics=brackets.getModule("utils/Metrics"),StringUtils=brackets.getModule("utils/StringUtils"),Strings=brackets.getModule("strings"),_PINS=brackets.config&&brackets.config.lsp_server_pins||{};_PINS.pyrefly&&_PINS.ruff||window.alert("[PythonSupport] lsp_server_pins missing from AppConfig - stale build? Run npm run build.");const PYREFLY_VERSION=_PINS.pyrefly||"1.1.1",RUFF_VERSION=_PINS.ruff||"0.15.20",PREF_PYTHON_CODE_INTELLIGENCE="codeIntelligence.python",UNITS={pyrefly:{pkg:"pyrefly",version:PYREFLY_VERSION},ruff:{pkg:"ruff",version:RUFF_VERSION}};let _onInstalled=null,_inFlight=null,_cancelledThisSession=!1,_cancelRequested=!1,_activeDownload=null,_onlineRetryArmed=!1;function _installDirVfs(unit){return Phoenix.VFS.getAppSupportDir()+"lspServers/"+unit.pkg+"/"}function _binaryRelPath(unit){const exe="win"===brackets.platform?".exe":"";return unit.pkg+"-"+unit.version+".data/scripts/"+unit.pkg+exe}function _binaryVfs(unit){return _installDirVfs(unit)+_binaryRelPath(unit)}function _markerVfs(unit){return _installDirVfs(unit)+"installed.json"}function _binaryPlatformPath(unit){return Phoenix.fs.getTauriPlatformPath(_binaryVfs(unit))}function getBinaryPlatformPath(){return _binaryPlatformPath(UNITS.pyrefly)}function getRuffBinaryPlatformPath(){return _binaryPlatformPath(UNITS.ruff)}async function _unitState(unit){const binExists=await Phoenix.VFS.existsAsync(_binaryVfs(unit));if(binExists)try{const marker=JSON.parse(await Phoenix.VFS.readFileAsync(_markerVfs(unit),"utf8"));return{installed:!0,pinMatches:marker.version===unit.version}}catch(e){return{installed:!0,pinMatches:!1}}const markerExists=await Phoenix.VFS.existsAsync(_markerVfs(unit));return{installed:markerExists,pinMatches:!1}}async function installedState(){const pyrefly=await _unitState(UNITS.pyrefly),ruff=await _unitState(UNITS.ruff);return{installed:pyrefly.installed,pinMatches:pyrefly.pinMatches&&ruff.installed&&ruff.pinMatches}}async function _wheelTag(){const platform=brackets.platform,arch=String(await Phoenix.app.getPlatformArch()||"").toLowerCase(),isX64="x86_64"===arch||"x64"===arch||"amd64"===arch,isArm64="aarch64"===arch||"arm64"===arch;if("win"===platform){if(isX64)return"win_amd64";if(isArm64)return"win_arm64"}else if("mac"===platform){if(isArm64)return"macosx_11_0_arm64";if(isX64)return"macosx_10_12_x86_64"}else if("linux"===platform){if(isX64)return"manylinux_2_17_x86_64.manylinux2014_x86_64";if(isArm64)return"manylinux_2_17_aarch64.manylinux2014_aarch64"}throw new Error("no "+Object.keys(UNITS).join("/")+" build for "+platform+"/"+arch)}async function _resolveWheel(unit,tag){const metaUrl="https://pypi.org/pypi/"+unit.pkg+"/"+unit.version+"/json",response=await fetch(metaUrl);if(!response.ok)throw new Error("PyPI metadata fetch failed with HTTP "+response.status);const meta=await response.json(),wheel=(meta.urls||[]).find(function(u){return u.filename&&u.filename.endsWith(".whl")&&-1!==u.filename.indexOf(tag)});if(!wheel)throw new Error("no "+unit.pkg+" "+unit.version+" wheel for "+tag);return{url:wheel.url,sha256:wheel.digests&&wheel.digests.sha256}}const NETWORK_ERROR_RE=new RegExp("failed to fetch|fetch failed|load failed|ENOTFOUND|ETIMEDOUT|ECONNRESET|ECONNREFUSED|EAI_AGAIN|ENETUNREACH|getaddrinfo|network","i");function _isNetworkError(err){return NETWORK_ERROR_RE.test(err&&err.message||String(err))}function _armOnlineRetry(){_onlineRetryArmed||(_onlineRetryArmed=!0,window.addEventListener("online",function(){_onlineRetryArmed=!1,autoInstall()},{once:!0}))}function _showFailureToast(message){const $tpl=$("