public void execute() throws IOException, URISyntaxException, AuthenticationException { String pa = restRequest.getParameterValue("project-area"); Map<String, JsonElement> typeMap = new TreeMap<String, JsonElement>(); try { IProjectAreaHandle targetArea = ProjectAreaHelpers.getProjectArea(pa, parentService); if(targetArea == null) { response.setStatus(400); return; } IWorkItemServer serverService = parentService.getService(IWorkItemServer.class); List<IWorkItemType> types = WorkItemTypeHelpers.getWorkItemTypes(targetArea, serverService, new NullProgressMonitor()); for(IWorkItemType type : types) { JsonObject typeObject = new JsonObject(); typeObject.addProperty("id", type.getIdentifier()); typeObject.addProperty("name", type.getDisplayName()); typeMap.put(type.getDisplayName(), typeObject); } } catch (TeamRepositoryException e) { response.setStatus(500); } response.getWriter().write(new Gson().toJson(typeMap.values())); }
public void execute() throws IOException, URISyntaxException, AuthenticationException { Gson googleJson = new Gson(); try { IProcessServerService processServerService = parentService.getService(IProcessServerService.class); IContributorHandle contribHandle = processServerService.getAuthenticatedContributor(); IRepositoryItemService itemService = parentService.getService(IRepositoryItemService.class); IContributor contributor = (IContributor) itemService.fetchItem(contribHandle, null); Map<String, ProjectArea> projectAreas = new TreeMap<String, ProjectArea>(); IProcessArea[] areas = processServerService.findProcessAreas(contributor, null, null); for(IProcessArea a : areas) { IProjectArea pa = (IProjectArea) itemService.fetchItem(a.getProjectArea(), null); String paId = pa.getItemId().toString(); projectAreas.put(pa.getName(), new ProjectArea(paId, pa.getName())); } String projectAreasJson = googleJson.toJson(projectAreas); response.getWriter().write(projectAreasJson); } catch (Exception e) { response.setStatus(500); } }
public Token authenticate() throws AuthenticationException { Token bьььь044Cь = Token.bьььь044Cь(Type.SHORT_TERM); bьььь044Cь.loadToken(this.b04140414Д0414ДД); b0439ййййй(bьььь044Cь); if (bьььь044Cь.isTokenExpired()) { Log.d(bДД04140414ДД, "Credentials expired or do not exist. Requesting new token."); rrcrcc login = new cccrrr(this.b04140414Д0414ДД, this.bД041404140414ДД, ccccrr.getAppName(), ccccrr.useSSL()).login(this.bД0414Д0414ДД.getUserName(), this.bД0414Д0414ДД.getPassword()); if (login.requestUnauthorized()) { b0449щ0449044904490449(); throw new AuthenticationException(); } else if (login.requestTimedOut()) { bщ04490449044904490449(); if (((bХ0425Х042504250425 + b04250425Х042504250425) * bХ0425Х042504250425) % bХХ0425042504250425 != bХ04250425042504250425) { bХ0425Х042504250425 = 30; bХ04250425042504250425 = 78; } return bьььь044Cь; } } bщщ0449044904490449(bьььь044Cь); return bьььь044Cь; }
/** * Produces basic authorization header for the given set of {@link Credentials}. * * @param credentials The set of credentials to be used for authentication * @param request The request being authenticated * @throws InvalidCredentialsException if authentication credentials are not * valid or not applicable for this authentication scheme * @throws AuthenticationException if authorization string cannot * be generated due to an authentication failure * * @return a basic authorization string */ @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { if (credentials == null) { throw new IllegalArgumentException("Credentials may not be null"); } if (request == null) { throw new IllegalArgumentException("HTTP request may not be null"); } String charset = AuthParams.getCredentialCharset(request.getParams()); return authenticate(credentials, charset, isProxy()); }
/** * Produces Diadoc authorization header for the given set of {@link org.apache.http.auth.Credentials}. * * @param credentials The set of credentials to be used for authentication; must be of type DiadocCredentials * @param request The request being authenticated * @return a Diadoc authorization string * @throws org.apache.http.auth.AuthenticationException * if authorization string cannot * be generated due to an authentication failure */ public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { if (credentials == null) { throw new IllegalArgumentException("Credentials may not be null"); } if (!(credentials instanceof DiadocCredentials)) { throw new IllegalArgumentException("Credentials must be of type DiadocCredentials"); } if (request == null) { throw new IllegalArgumentException("HTTP request may not be null"); } return authenticate((DiadocCredentials) credentials); }
/** * Produces a digest authorization string for the given set of * {@link Credentials}, method name and URI. * * @param credentials A set of credentials to be used for athentication * @param request The request being authenticated * * @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials * are not valid or not applicable for this authentication scheme * @throws AuthenticationException if authorization string cannot * be generated due to an authentication failure * * @return a digest authorization string */ @Override public Header authenticate( final Credentials credentials, final HttpRequest request, final HttpContext context) throws AuthenticationException { Args.notNull(credentials, "Credentials"); Args.notNull(request, "HTTP request"); if (getParameter("realm") == null) { throw new AuthenticationException("missing realm in challenge"); } if (getParameter("nonce") == null) { throw new AuthenticationException("missing nonce in challenge"); } // Add method name and request-URI to the parameter map getParameters().put("methodname", request.getRequestLine().getMethod()); getParameters().put("uri", request.getRequestLine().getUri()); final String charset = getParameter("charset"); if (charset == null) { getParameters().put("charset", getCredentialsCharset(request)); } return createDigestHeader(credentials, request); }
/** * Performs an import of the impex file * * @param file * file to be imported * @return message with import result */ public String performImport(final IFile impexFile) { updateLoginVariables(); String resultMessage; try { fetchCsrfTokenFromHac(); loginToHac(); // continues only if logged in successfully try { fetchCsrfTokenFromHac(); resultMessage = postImpex(impexFile); } finally { logoutFromHac(); } } catch (final IOException | AuthenticationException e) { resultMessage = e.getMessage(); } return resultMessage; }
/** * Send HTTP GET request to {@link #endpointUrl}, updates {@link #csrfToken} * token * * @return true if {@link #endpointUrl} is accessible * @throws IOException * @throws ClientProtocolException * @throws AuthenticationException */ protected void fetchCsrfTokenFromHac() throws ClientProtocolException, IOException, AuthenticationException { final HttpGet getRequest = new HttpGet(getEndpointUrl()); try { final HttpResponse response = httpClient.execute(getRequest, getContext()); final String responseString = new BasicResponseHandler().handleResponse(response); csrfToken = getCsrfToken(responseString); if( StringUtil.isBlank(csrfToken) ) { throw new AuthenticationException(ErrorMessage.CSRF_TOKEN_CANNOT_BE_OBTAINED); } } catch (UnknownHostException error) { final String errorMessage = error.getMessage(); final Matcher matcher = HACPreferenceConstants.HOST_REGEXP_PATTERN.matcher(getEndpointUrl()); if (matcher.find() && matcher.group(1).equals(errorMessage)) { throw new UnknownHostException( String.format(ErrorMessage.UNKNOWN_HOST_EXCEPTION_MESSAGE_FORMAT, matcher.group(1))); } throw error; } }
/** * Performs script import. * * @param scriptFile * script file to import * @param commit * flat to determinate whether script will be committed or not. */ protected void performScriptImport(final IFile scriptFile, final Boolean commit) { updateLoginVariables(); try { fetchCsrfTokenFromHac(); loginToHac(); try { fetchCsrfTokenFromHac(); postScriptExecution(scriptFile, commit); } finally { logoutFromHac(); } } catch (final IOException | AuthenticationException e) { ConsoleUtils.printError(e.getMessage()); } }
/** * Perform entire 4 steps process of Redeem OneDrive for Business API according to documentation {@link https://dev.onedrive.com/auth/aad_oauth.htm} * * Step 1: Redeem the authorization code for tokens * Step 2: Discover the OneDrive for Business resource URI * Step 3: Redeem refresh token for an access token to call OneDrive API * Step 4: It is not documented but retriever Email address for user access token. * * @param redeemRequest the redeem request * @return the one drive business object which encapsulate credential info, such as access and refresh token and sharepoint URL for further OneDrive for Business API calls * @throws AuthenticationException the authentication exception */ public static BusinessCredential redeemBusiness(RedeemRequest redeemRequest) throws AuthenticationException{ try { Map<String, Object> redeemBusinessApiResource = redeemBusinessApiResource(ApiEnviroment.graphApiUrl.getValue(), redeemRequest.getClientId(), redeemRequest.getClientSecret(), redeemRequest.getRedirectUri(), redeemRequest.getCode()); Map<String, Object> redeemBusinessApi = redeemBusinessApiResource(redeemRequest.getSharepointResourceId(), redeemRequest.getClientId(), redeemRequest.getClientSecret(), redeemRequest.getRedirectUri(), redeemRequest.getCode()); String userEmail = businessEmail((String)redeemBusinessApiResource.get("access_token")); logger.debug("Redeem for OneDrive Business API sharepoint specific URL {}", redeemBusinessApi); return BusinessCredential.builder() .sharepointEndpointUri(redeemRequest.getSharepointEndpointUri()) .sharepointResourceId(redeemRequest.getSharepointResourceId()) .accessToken((String)redeemBusinessApi.get("access_token")) .refreshToken((String)redeemBusinessApi.get("refresh_token")) .tokenType((String)redeemBusinessApi.get("token_type")) .user(userEmail) .build(); } catch (Exception e) { throw new AuthenticationException("Could not redeem code "+redeemRequest.getCode()+" for OneDrive Business API"); } }
@Override public Header authenticate(Credentials credentials, HttpRequest request, HttpContext context) throws AuthenticationException { Args.notNull(credentials, "Credentials"); Args.notNull(request, "HTTP request"); // the bearer token is stored in the password field, not credentials.getUserPrincipal().getName() String bearerToken = credentials.getPassword(); CharArrayBuffer buffer = new CharArrayBuffer(64); if (isProxy()) { buffer.append("Proxy-Authorization"); } else { buffer.append("Authorization"); } buffer.append(": Bearer "); buffer.append(bearerToken); return new BufferedHeader(buffer); }
/** * Signs an {@link HttpRequest} and returns a header with the signed * authorization value. * * @param credentials Credentials containing a username * @param request The {@link HttpRequest} to sign. * @return header with signed authorization value * @throws AuthenticationException If unable to sign the request. */ protected Header signRequestHeader(final Credentials credentials, final HttpRequest request) throws AuthenticationException { if (LOG.isDebugEnabled()) { LOG.debug(String.format("Signing request: %s", request)); } final Header date = request.getFirstHeader(HttpHeaders.DATE); final String stringDate; if (date != null) { stringDate = date.getValue(); } else { stringDate = signer.get().defaultSignDateAsString(); request.setHeader(HttpHeaders.DATE, stringDate); } // Assure that a cache object is always present for each credential signatureCacheMap.computeIfAbsent(credentials, NEW_CACHE_FUNCTION); final String authz = signatureCacheMap.get(credentials) .updateAndGetSignature(stringDate, signer.get(), keyPair); return new BasicHeader(HttpHeaders.AUTHORIZATION, authz); }
private void processChallenges( final Map<String, Header> challenges, final AuthState authState, final AuthenticationHandler authHandler, final HttpResponse response, final HttpContext context) throws MalformedChallengeException, AuthenticationException { AuthScheme authScheme = authState.getAuthScheme(); if (authScheme == null) { // Authentication not attempted before authScheme = authHandler.selectScheme(challenges, response, context); authState.setAuthScheme(authScheme); } String id = authScheme.getSchemeName(); Header challenge = challenges.get(id.toLowerCase(Locale.ENGLISH)); if (challenge == null) { throw new AuthenticationException(id + " authorization challenge expected, but not found"); } authScheme.processChallenge(challenge); this.log.debug("Authorization challenge processed"); }
private static String retryAuthentification(int retryCount, AccountManager accountManager, String authtoken, String accountName, HttpResponse response) throws AuthenticationException, OperationCanceledException, NetworkErrorException, ServerException { accountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, authtoken); String newToken = null; if (retryCount == 0) { newToken = blockingGetAuthToken(accountManager, new Account( accountName, Constants.ACCOUNT_TYPE), null); } if (newToken == null) { throw new AuthenticationException(response.getStatusLine() .toString()); } return newToken; }
/** * Produces a digest authorization string for the given set of * {@link Credentials}, method name and URI. * * @param credentials A set of credentials to be used for athentication * @param request The request being authenticated * * @throws org.apache.http.auth.InvalidCredentialsException if authentication credentials * are not valid or not applicable for this authentication scheme * @throws AuthenticationException if authorization string cannot * be generated due to an authentication failure * * @return a digest authorization string */ public Header authenticate( final Credentials credentials, final HttpRequest request) throws AuthenticationException { if (credentials == null) { throw new IllegalArgumentException("Credentials may not be null"); } if (request == null) { throw new IllegalArgumentException("HTTP request may not be null"); } // Add method name and request-URI to the parameter map getParameters().put("methodname", request.getRequestLine().getMethod()); getParameters().put("uri", request.getRequestLine().getUri()); String charset = getParameter("charset"); if (charset == null) { charset = AuthParams.getCredentialCharset(request.getParams()); getParameters().put("charset", charset); } String digest = createDigest(credentials); return createDigestHeader(credentials, digest); }
@Override public void process(HttpRequest request, HttpContext context) throws HttpException, IOException { if (request == null) throw new IllegalArgumentException("HTTP request may not be null"); if (context == null) throw new IllegalArgumentException("HTTP context may not be null"); if (!request.getRequestLine().getMethod().equalsIgnoreCase("CONNECT")) { AuthState authState = (AuthState) context.getAttribute(ClientContext.TARGET_AUTH_STATE); if (authState != null) { AuthScheme authScheme = authState.getAuthScheme(); if (authScheme != null && !authScheme.isConnectionBased()) { try { request.setHeader(authScheme.authenticate(null, request)); } catch (AuthenticationException ignored) { // ignored } } } } }
public static Response<?> postNoData(Context context, GHCredentials apiCredentials, String url, Map<String, String> headers) throws NoRouteToHostException, URISyntaxException, IOException, ClientProtocolException, AuthenticationException, UnsupportedEncodingException { if (!Utils.isInternetConnectionAvailable(context)) throw new NoRouteToHostException("Network not available"); Log.d(TAG, "Going to perform POST request to " + url); URI uri = new URI(url); DefaultHttpClient httpClient = prepareHttpClient(uri, apiCredentials); HttpPost httpPost = new HttpPost(uri); setHeaders(httpPost, headers); // create response object here to measure request duration Response<String> ret = new Response<String>(); ret.requestStartTime = System.currentTimeMillis(); HttpResponse httpResponse = httpClient.execute(httpPost); parseResponseHeaders(context, httpResponse, ret); processStandardHttpResponseCodes(httpResponse); ret.snapRequestDuration(); writeReponseInfo(ret, context); return ret; }
protected static void processStandardHttpResponseCodes(HttpResponse httpResponse) throws AuthenticationException, IOException { int code = httpResponse.getStatusLine().getStatusCode(); Log.d(TAG, "Response http code: " + code); if (code >= 200 && code <= 299) return; if (code == HttpStatus.SC_UNAUTHORIZED || code == HttpStatus.SC_FORBIDDEN) { String OTP = getHeaderValue(httpResponse, "X-GitHub-OTP"); if (code == HttpStatus.SC_UNAUTHORIZED && OTP != null && OTP.contains("required")) { throw new OTPAuthenticationException(Utils.trimToNull(OTP.replace("required;", ""))); } throw new AuthenticationException("Authentication problem: " + getResponseContentAsString(httpResponse)); } else if (code == HttpStatus.SC_BAD_REQUEST || code == HttpStatus.SC_NOT_FOUND) { throw new InvalidObjectException("HttpCode=" + code + " message: " + getResponseContentAsString(httpResponse)); } else { throw new IOException("HttpCode=" + code + " message: " + getResponseContentAsString(httpResponse)); } }
private void loadCookie(String authToken) throws AuthenticationException, IOException { String url = AUTH_COOKIE_URL.buildUpon().appendQueryParameter("auth", authToken).build().toString(); HttpGet method = new HttpGet(url); httpClient.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false); HttpResponse res = httpClient.execute(method, httpContext); Header[] headers = res.getHeaders("Set-Cookie"); if (res.getEntity() != null) { res.getEntity().consumeContent(); } if (res.getStatusLine().getStatusCode() != HttpStatus.SC_MOVED_TEMPORARILY || headers.length == 0) { throw new AuthenticationException("Failed to get cookie"); } if (!hasValidAuthCookie()) throw new AuthenticationException("Failed to get cookie"); }
private void processChallenges( final Map<String, Header> challenges, final AuthState authState, final AuthenticationHandler authHandler, final HttpResponse response, final HttpContext context) throws MalformedChallengeException, AuthenticationException { AuthScheme authScheme = authState.getAuthScheme(); if (authScheme == null) { // Authentication not attempted before authScheme = authHandler.selectScheme(challenges, response, context); authState.setAuthScheme(authScheme); } String id = authScheme.getSchemeName(); Header challenge = challenges.get(id.toLowerCase(Locale.ENGLISH)); if (challenge == null) { throw new AuthenticationException(id + " authorization challenge expected, but not found"); } authScheme.processChallenge(challenge); if (DEBUG) { Logger.debug("Authorization challenge processed"); } }
public Header authenticate(Credentials credentials, HttpRequest request) throws AuthenticationException { String uri; String method; HttpUriRequest uriRequest = getHttpUriRequest(request); if (uriRequest != null) { uri = uriRequest.getURI().toString(); method = uriRequest.getMethod(); } else { // Some requests don't include the server name in the URL. RequestLine requestLine = request.getRequestLine(); uri = requestLine.getUri(); method = requestLine.getMethod(); } try { OAuthMessage message = new OAuthMessage(method, uri, null); OAuthAccessor accessor = getAccessor(credentials); message.addRequiredParameters(accessor); String authorization = message.getAuthorizationHeader(getRealm()); return new BasicHeader("Authorization", authorization); } catch (Exception e) { throw new AuthenticationException(null, e); } }
public static void setCredentials(DefaultHttpClient client, HttpUriRequest request, String user, String password) { if (user != null && password != null) { AuthScope authScope = new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT); UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(user, password); client.getCredentialsProvider().setCredentials(authScope, credentials); try { request.addHeader(new BasicScheme().authenticate(credentials, request)); } catch (AuthenticationException e1) { e1.printStackTrace(); return; } } }
private void handleException(String authtoken, Exception e, SyncResult syncResult) { if (e instanceof AuthenticatorException) { syncResult.stats.numParseExceptions++; Log.e("SyncAdapter", "AuthenticatorException", e); } else if (e instanceof OperationCanceledException) { Log.e("SyncAdapter", "OperationCanceledExcepion", e); } else if (e instanceof IOException) { Log.e("SyncAdapter", "IOException", e); syncResult.stats.numIoExceptions++; } else if (e instanceof AuthenticationException) { accountManager.invalidateAuthToken(Authenticator.ACCOUNT_TYPE, authtoken); syncResult.stats.numIoExceptions++; if (authtoken != null) Log.e("SyncAdapter", "Auth failed, invalidating token: " + authtoken); Log.e("SyncAdapter", "AuthenticationException", e); } else if (e instanceof ParseException) { syncResult.stats.numParseExceptions++; Log.e("SyncAdapter", "ParseException", e); } else if (e instanceof JsonParseException) { syncResult.stats.numParseExceptions++; Log.e("SyncAdapter", "JSONException", e); } else if (e instanceof ServerUrlPreferenceNotSetException) { Log.e("SyncAdapter", "ServerUrlPreferenceNotSetException", e); } }
private void processChallenges( final Map<String, Header> challenges, final AuthState authState, final AuthenticationHandler authHandler, final HttpResponse response, final HttpContext context) throws MalformedChallengeException, AuthenticationException { AuthScheme authScheme = authState.getAuthScheme(); if (authScheme == null) { // Authentication not attempted before authScheme = authHandler.selectScheme(challenges, response, context); authState.setAuthScheme(authScheme); } String id = authScheme.getSchemeName(); Header challenge = challenges.get(id.toLowerCase(Locale.ENGLISH)); if (challenge == null) { throw new AuthenticationException(id + " authorization challenge expected, but not found"); } authScheme.processChallenge(challenge); if (Constants.DEBUG) { logger.debug("Authorization challenge processed"); } }
private void prepareRequest( HttpRequest request, Map<String, String> newHeaders ) { applyHeaders( request, newHeaders ); if ( authenticated ) { UsernamePasswordCredentials credentials = new UsernamePasswordCredentials( username, password ); try { request.addHeader( new BasicScheme().authenticate( credentials, request, null ) ); } catch ( AuthenticationException e ) { log.warn( "it should not happens", e ); } } }
private Definition readWsdl( WSDLReader wsdlReader, String uri, String username, String password ) throws WSDLException, KettleException, AuthenticationException { try { HTTPProtocol http = new HTTPProtocol(); Document doc = XMLHandler.loadXMLString( http.get( wsdlURI.toString(), username, password ), true, false ); if ( doc != null ) { return ( wsdlReader.readWSDL( doc.getBaseURI(), doc ) ); } else { throw new KettleException( "Unable to get document." ); } } catch ( MalformedURLException mue ) { throw new KettleException( mue ); } catch ( AuthenticationException ae ) { // re-throw this. If not IOException seems to catch it throw ae; } catch ( IOException ioe ) { throw new KettleException( ioe ); } }
private ContentValues getAnswerContentValues(JSONObject answer) throws AuthenticationException, ParseException, OperationCanceledException, AuthenticatorException, JSONException, IOException { ContentValues values = new ContentValues(); values.put(AnswersEntry.COLUMN_TIMESTAMP, answer.optString("LastChangedTime")); values.put(AnswersEntry.COLUMN_ANSWER, answer.optString("Content")); values.put(AnswersEntry.COLUMN_DATE, SyncHelper.getUnixMillisecondsFromJsonDate(answer.optString("Date"))); values.put(AnswersEntry.COLUMN_ANSWERSTATE, getAnswerStateForId(answer.optInt("answerState")).toString());//TODO String backendid = answer.optString("Id"); if (backendid != null) { values.put(AnswersEntry.COLUMN_BACKEND_ID, SyncHelper.getIdFromURI(backendid)); } String answerer = answer.optString("Answerer"); if (answerer != null && !answerer.equals("null") && answerer.length() > 0) { values.put(AnswersEntry.COLUMN_ANSWERER_ID, SyncHelper.getRealIdForObjectURI(answerer, context)); } return values; }
@OnWebSocketConnect public void onConnect(Session session) throws AuthenticationException { Map<String, List<String>> params = session.getUpgradeRequest().getParameterMap(); List<String> keys = params.get("key"); if (keys == null || keys.size() != 1 || !keys.get(0).equals(NMOConfiguration.INSTANCE.integrations.webUI.ultiwakerAPI.apiSecurityKey)) { throw new AuthenticationException("Not authorized"); } this.session = session; this.connectionIP = session.getRemoteAddress().getAddress().toString(); connections.add(this); log.info("UWAPI connect from " + this.connectionIP); }
/** * @deprecated (4.2) Use {@link ContextAwareAuthScheme#authenticate(Credentials, HttpRequest, org.apache.http.protocol.HttpContext)} */ @Deprecated public Header authenticate( final Credentials credentials, final HttpRequest request ) throws AuthenticationException { return authenticate(credentials, request, null); }
public void run() { try { this.b043Dн043Dннн.authenticate(); if (((b0417041704170417ЗЗ + b0417ЗЗЗ0417З) * b0417041704170417ЗЗ) % bЗ041704170417ЗЗ != bЗЗЗЗ0417З) { b0417041704170417ЗЗ = bЗЗ04170417ЗЗ(); bЗЗЗЗ0417З = bЗЗ04170417ЗЗ(); } } catch (AuthenticationException e) { try { e.printStackTrace(); } catch (Exception e2) { throw e2; } } }
@SuppressWarnings("deprecation") private Header authenticate( final AuthScheme authScheme, final Credentials creds, final HttpRequest request, final HttpContext context) throws AuthenticationException { if (authScheme == null) { throw new IllegalStateException("Auth state object is null"); } if (authScheme instanceof ContextAwareAuthScheme) { return ((ContextAwareAuthScheme) authScheme).authenticate(creds, request, context); } else { return authScheme.authenticate(creds, request); } }