diff --git a/.eslintrc.json b/.eslintrc.json index 323f39c69835b6b8cd90b8316edecc62ea63c37f..cb22919c9061a4caff4705c395251ad1a3b5ab18 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -19,7 +19,15 @@ "sourceType": "module", "project": "./tsconfig.json" }, - "ignorePatterns": ["**/bootstrap4.5.2.min.js", "**/prism-java.min.js", "**/prism*.js", "**/jquery*.js", "**/popper*.js", "**/joypixels.min.js", "**/katex.min.js"], + "ignorePatterns": [ + "**/bootstrap4.5.2.min.js", + "**/prism-java.min.js", + "**/prism*.js", + "**/jquery*.js", + "**/popper*.js", + "**/joypixels.min.js", + "**/katex.min.js" + ], "rules": { "@angular-eslint/component-selector": [ "off", diff --git a/angular.json b/angular.json index 7b3231274d23000075fb4353747a5d01ce983019..499b6d0138294782cacb76c0bbb1afd6f5de6896 100644 --- a/angular.json +++ b/angular.json @@ -43,7 +43,11 @@ { "glob": "axios.min.js", "input": "./node_modules/axios/dist", "output": "swagger-ui" }, { "glob": "**/*", "input": "src/main/webapp/swagger-ui/", "output": "swagger-ui" } ], - "styles": ["src/main/webapp/content/scss/vendor.scss", "src/main/webapp/content/scss/global.scss", "node_modules/katex/dist/katex.min.css"], + "styles": [ + "src/main/webapp/content/scss/vendor.scss", + "src/main/webapp/content/scss/global.scss", + "node_modules/katex/dist/katex.min.css" + ], "scripts": ["node_modules/emoji-toolkit/lib/js/joypixels.min.js", "node_modules/katex/dist/katex.min.js"] }, "configurations": { diff --git a/docker-compose.yml b/docker-compose.yml index 8da373646b5c18848008f8dd74c25e65be006a45..7af78250de56046768e59e6ec52e005aa1312e2a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,9 +7,9 @@ services: environment: - bootstrap.memory_lock=true - cluster.name=docker-cluster-test - - "xpack.license.self_generated.type=basic" - - "xpack.security.enabled=true" - - "ES_JAVA_OPTS=-Xms512m -Xmx512m" + - 'xpack.license.self_generated.type=basic' + - 'xpack.security.enabled=true' + - 'ES_JAVA_OPTS=-Xms512m -Xmx512m' ulimits: memlock: soft: -1 @@ -17,14 +17,14 @@ services: networks: - bridge_es ports: - - "9200:9200" + - '9200:9200' kibana: container_name: kibana image: docker.elastic.co/kibana/kibana:6.8.8 networks: - bridge_es ports: - - "5601:5601" + - '5601:5601' networks: bridge_es: diff --git a/src/main/java/at/ac/uibk/gitsearch/GitsearchApp.java b/src/main/java/at/ac/uibk/gitsearch/GitsearchApp.java index 5d7ed88dfbfba87074ccc941167ab1e7f8300217..b2f08fa859ea3f627c0508c6fcb96d37f99fd0fd 100644 --- a/src/main/java/at/ac/uibk/gitsearch/GitsearchApp.java +++ b/src/main/java/at/ac/uibk/gitsearch/GitsearchApp.java @@ -1,5 +1,6 @@ package at.ac.uibk.gitsearch; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.Arrays; @@ -14,8 +15,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.liquibase.LiquibaseProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.core.env.Environment; - -import at.ac.uibk.gitsearch.properties.ApplicationProperties; import tech.jhipster.config.DefaultProfileUtil; import tech.jhipster.config.JHipsterConstants; diff --git a/src/main/java/at/ac/uibk/gitsearch/config/SecurityConfiguration.java b/src/main/java/at/ac/uibk/gitsearch/config/SecurityConfiguration.java index 26cb0d568d96256bf3a43f701d74e71659697775..c60c13b1bd9791b221a3ae71680870334a5f0d09 100644 --- a/src/main/java/at/ac/uibk/gitsearch/config/SecurityConfiguration.java +++ b/src/main/java/at/ac/uibk/gitsearch/config/SecurityConfiguration.java @@ -2,6 +2,15 @@ package at.ac.uibk.gitsearch.config; import static org.springframework.http.MediaType.APPLICATION_FORM_URLENCODED_VALUE; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.security.jwt.JWTConfigurer; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; +import at.ac.uibk.gitsearch.security.oauth2.GitSearchOAuth2AuthorizationRequestRepository; +import at.ac.uibk.gitsearch.security.oauth2.SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport; +import at.ac.uibk.gitsearch.security.oauth2.UserDetailsFetcher; +import at.ac.uibk.gitsearch.service.UserService; +import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; +import at.ac.uibk.gitsearch.service.mapper.UserMapper; import java.net.URI; import java.util.Collections; import java.util.HashMap; @@ -9,9 +18,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.Set; - import javax.servlet.DispatcherType; - import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; @@ -70,16 +77,6 @@ import org.springframework.web.filter.ForwardedHeaderFilter; import org.springframework.web.util.UriComponentsBuilder; import org.zalando.problem.spring.web.advice.security.SecurityProblemSupport; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.security.jwt.JWTConfigurer; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; -import at.ac.uibk.gitsearch.security.oauth2.GitSearchOAuth2AuthorizationRequestRepository; -import at.ac.uibk.gitsearch.security.oauth2.SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport; -import at.ac.uibk.gitsearch.security.oauth2.UserDetailsFetcher; -import at.ac.uibk.gitsearch.service.UserService; -import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; -import at.ac.uibk.gitsearch.service.mapper.UserMapper; - @EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) @Import(SecurityProblemSupport.class) @@ -87,16 +84,19 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Value("${spring.security.oauth2.client.provider.gitlabOidc.issuer-uri}") private String gitLabIssuerUri; - + private final TokenProvider tokenProvider; private final CorsFilter corsFilter; private final SecurityProblemSupport problemSupport; - private UserDetailsFetcher userDetailsFetcher; - - public SecurityConfiguration(TokenProvider tokenProvider, CorsFilter corsFilter, - UserDetailsFetcher userDetailsFetcher, - SecurityProblemSupport problemSupport) { + private UserDetailsFetcher userDetailsFetcher; + + public SecurityConfiguration( + TokenProvider tokenProvider, + CorsFilter corsFilter, + UserDetailsFetcher userDetailsFetcher, + SecurityProblemSupport problemSupport + ) { this.tokenProvider = tokenProvider; this.corsFilter = corsFilter; this.problemSupport = problemSupport; @@ -110,7 +110,8 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) { - web.ignoring() + web + .ignoring() .antMatchers(HttpMethod.OPTIONS, "/**") .antMatchers("/app/**/*.{js,html}") .antMatchers("/i18n/**") @@ -199,46 +200,43 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { .oauth2Client(); http.oauth2Login().tokenEndpoint().accessTokenResponseClient(accessTokenResponseClient()); - - -// .apply(securityConfigurerAdapter()) + // .apply(securityConfigurerAdapter()) // @formatter:on } Converter<org.springframework.security.oauth2.jwt.Jwt, AbstractAuthenticationToken> authenticationConverter() { JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter(); - jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter(new at.ac.uibk.gitsearch.security.oauth2.JwtGrantedAuthorityConverter()); + jwtAuthenticationConverter.setJwtGrantedAuthoritiesConverter( + new at.ac.uibk.gitsearch.security.oauth2.JwtGrantedAuthorityConverter() + ); return jwtAuthenticationConverter; } - + private JWTConfigurer securityConfigurerAdapter() { return new JWTConfigurer(tokenProvider); } - public AuthenticationProvider customJWTauthenticationProvider() { - return new AuthenticationProvider() { - - @Override - public boolean supports(Class<?> authentication) { - return BearerTokenAuthenticationToken.class.isAssignableFrom(authentication); - } - - @Override - public Authentication authenticate(Authentication authentication) throws AuthenticationException { - if(authentication.isAuthenticated()) return authentication; - if (authentication instanceof BearerTokenAuthenticationToken) { - BearerTokenAuthenticationToken bearerToken = (BearerTokenAuthenticationToken) authentication; - if(tokenProvider.validateToken(bearerToken.getToken())) { - return tokenProvider.getAuthentication(bearerToken.getToken()); - } - -} - return null; - } - }; + return new AuthenticationProvider() { + @Override + public boolean supports(Class<?> authentication) { + return BearerTokenAuthenticationToken.class.isAssignableFrom(authentication); + } + + @Override + public Authentication authenticate(Authentication authentication) throws AuthenticationException { + if (authentication.isAuthenticated()) return authentication; + if (authentication instanceof BearerTokenAuthenticationToken) { + BearerTokenAuthenticationToken bearerToken = (BearerTokenAuthenticationToken) authentication; + if (tokenProvider.validateToken(bearerToken.getToken())) { + return tokenProvider.getAuthentication(bearerToken.getToken()); + } + } + return null; + } + }; } - + /** * not used by OidcAuthorizationCodeAuthenticationProvider :-( * @return @@ -247,23 +245,23 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { JwtDecoder jwtDecoder() { NimbusJwtDecoder oidcJwtDecoder = (NimbusJwtDecoder) JwtDecoders.fromOidcIssuerLocation(gitLabIssuerUri); - OAuth2TokenValidator<org.springframework.security.oauth2.jwt.Jwt> withIssuer = JwtValidators.createDefaultWithIssuer(gitLabIssuerUri); + OAuth2TokenValidator<org.springframework.security.oauth2.jwt.Jwt> withIssuer = JwtValidators.createDefaultWithIssuer( + gitLabIssuerUri + ); oidcJwtDecoder.setJwtValidator(withIssuer); - + return oidcJwtDecoder; } - + // @Bean - private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient(){ - DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient = - new DefaultAuthorizationCodeTokenResponseClient(); - accessTokenResponseClient.setRequestEntityConverter(new CustomOAuth2AuthorizationCodeGrantRequestEntityConverter()); + private OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> accessTokenResponseClient() { + DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient = new DefaultAuthorizationCodeTokenResponseClient(); + accessTokenResponseClient.setRequestEntityConverter(new CustomOAuth2AuthorizationCodeGrantRequestEntityConverter()); return accessTokenResponseClient; } - - -// @Bean + + // @Bean public FilterRegistrationBean<ForwardedHeaderFilter> forwardedHeaderFilter() { ForwardedHeaderFilter filter = new ForwardedHeaderFilter(); FilterRegistrationBean<ForwardedHeaderFilter> registration = new FilterRegistrationBean<>(filter); @@ -278,151 +276,159 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter { * @author Michael Breu * */ - public static class CustomOAuth2AuthorizationCodeGrantRequestEntityConverter extends OAuth2AuthorizationCodeGrantRequestEntityConverter { - - /** - * Returns the {@link RequestEntity} used for the Access Token Request. - * - * @param authorizationCodeGrantRequest the authorization code grant request - * @return the {@link RequestEntity} used for the Access Token Request - */ - @Override - public RequestEntity<?> convert(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) { - ClientRegistration clientRegistration = authorizationCodeGrantRequest.getClientRegistration(); - - HttpHeaders headers = getTokenRequestHeaders(clientRegistration); - MultiValueMap<String, String> formParameters = this.buildFormParameters(authorizationCodeGrantRequest); - URI uri = UriComponentsBuilder.fromUriString(clientRegistration.getProviderDetails().getTokenUri()) - .build() - .toUri(); - - return new RequestEntity<>(formParameters, headers, HttpMethod.POST, uri); - } - - static org.springframework.http.HttpHeaders getTokenRequestHeaders(ClientRegistration clientRegistration) { - org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders(); - headers.addAll(getDefaultTokenRequestHeaders()); -// if (ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) { -// headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret()); -// } - return headers; - } - - private static org.springframework.http.HttpHeaders getDefaultTokenRequestHeaders() { - HttpHeaders headers = new HttpHeaders(); - headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - final MediaType contentType = MediaType.valueOf(APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8"); - headers.setContentType(contentType); - return headers; - } - - /** - * Returns a {@link MultiValueMap} of the form parameters used for the Access Token Request body. - * - * @param authorizationCodeGrantRequest the authorization code grant request - * @return a {@link MultiValueMap} of the form parameters used for the Access Token Request body - */ - private MultiValueMap<String, String> buildFormParameters(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) { - ClientRegistration clientRegistration = authorizationCodeGrantRequest.getClientRegistration(); - OAuth2AuthorizationExchange authorizationExchange = authorizationCodeGrantRequest.getAuthorizationExchange(); - - MultiValueMap<String, String> formParameters = new LinkedMultiValueMap<>(); - formParameters.add(OAuth2ParameterNames.GRANT_TYPE, authorizationCodeGrantRequest.getGrantType().getValue()); - formParameters.add(OAuth2ParameterNames.CODE, authorizationExchange.getAuthorizationResponse().getCode()); - String redirectUri = authorizationExchange.getAuthorizationRequest().getRedirectUri(); - String codeVerifier = authorizationExchange.getAuthorizationRequest().getAttribute(PkceParameterNames.CODE_VERIFIER); - if (redirectUri != null) { - formParameters.add(OAuth2ParameterNames.REDIRECT_URI, redirectUri); - } - - formParameters.add(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId()); - -// if (!ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) { -// formParameters.add(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId()); -// } -// if (ClientAuthenticationMethod.POST.equals(clientRegistration.getClientAuthenticationMethod())) { -// formParameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRegistration.getClientSecret()); -// } - if (codeVerifier != null) { - formParameters.add(PkceParameterNames.CODE_VERIFIER, codeVerifier); - } - - return formParameters; - } - + public static class CustomOAuth2AuthorizationCodeGrantRequestEntityConverter + extends OAuth2AuthorizationCodeGrantRequestEntityConverter { + + /** + * Returns the {@link RequestEntity} used for the Access Token Request. + * + * @param authorizationCodeGrantRequest the authorization code grant request + * @return the {@link RequestEntity} used for the Access Token Request + */ + @Override + public RequestEntity<?> convert(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) { + ClientRegistration clientRegistration = authorizationCodeGrantRequest.getClientRegistration(); + + HttpHeaders headers = getTokenRequestHeaders(clientRegistration); + MultiValueMap<String, String> formParameters = this.buildFormParameters(authorizationCodeGrantRequest); + URI uri = UriComponentsBuilder.fromUriString(clientRegistration.getProviderDetails().getTokenUri()).build().toUri(); + + return new RequestEntity<>(formParameters, headers, HttpMethod.POST, uri); + } + + static org.springframework.http.HttpHeaders getTokenRequestHeaders(ClientRegistration clientRegistration) { + org.springframework.http.HttpHeaders headers = new org.springframework.http.HttpHeaders(); + headers.addAll(getDefaultTokenRequestHeaders()); + // if (ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) { + // headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret()); + // } + return headers; + } + + private static org.springframework.http.HttpHeaders getDefaultTokenRequestHeaders() { + HttpHeaders headers = new HttpHeaders(); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + final MediaType contentType = MediaType.valueOf(APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8"); + headers.setContentType(contentType); + return headers; + } + + /** + * Returns a {@link MultiValueMap} of the form parameters used for the Access Token Request body. + * + * @param authorizationCodeGrantRequest the authorization code grant request + * @return a {@link MultiValueMap} of the form parameters used for the Access Token Request body + */ + private MultiValueMap<String, String> buildFormParameters(OAuth2AuthorizationCodeGrantRequest authorizationCodeGrantRequest) { + ClientRegistration clientRegistration = authorizationCodeGrantRequest.getClientRegistration(); + OAuth2AuthorizationExchange authorizationExchange = authorizationCodeGrantRequest.getAuthorizationExchange(); + + MultiValueMap<String, String> formParameters = new LinkedMultiValueMap<>(); + formParameters.add(OAuth2ParameterNames.GRANT_TYPE, authorizationCodeGrantRequest.getGrantType().getValue()); + formParameters.add(OAuth2ParameterNames.CODE, authorizationExchange.getAuthorizationResponse().getCode()); + String redirectUri = authorizationExchange.getAuthorizationRequest().getRedirectUri(); + String codeVerifier = authorizationExchange.getAuthorizationRequest().getAttribute(PkceParameterNames.CODE_VERIFIER); + if (redirectUri != null) { + formParameters.add(OAuth2ParameterNames.REDIRECT_URI, redirectUri); + } + + formParameters.add(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId()); + + // if (!ClientAuthenticationMethod.BASIC.equals(clientRegistration.getClientAuthenticationMethod())) { + // formParameters.add(OAuth2ParameterNames.CLIENT_ID, clientRegistration.getClientId()); + // } + // if (ClientAuthenticationMethod.POST.equals(clientRegistration.getClientAuthenticationMethod())) { + // formParameters.add(OAuth2ParameterNames.CLIENT_SECRET, clientRegistration.getClientSecret()); + // } + if (codeVerifier != null) { + formParameters.add(PkceParameterNames.CODE_VERIFIER, codeVerifier); + } + + return formParameters; + } + } + public AuthenticationSuccessHandler getAuthenticationSuccessHandler() { + return new SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport(tokenProvider); } - - public AuthenticationSuccessHandler getAuthenticationSuccessHandler() { - return new SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport(tokenProvider); - } - - @Bean - public AuthorizationRequestRepository<OAuth2AuthorizationRequest> getOAuth2AuthorizatinRequestRepository() { - return new GitSearchOAuth2AuthorizationRequestRepository(); - } - - private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() { - final OidcUserService delegate = new OidcUserService(); - - final Set<String> defaultAuthorities = new HashSet<>(); - defaultAuthorities.add(AuthoritiesConstants.USER); - final UserService userService = getApplicationContext().getBean(UserService.class); - final UserMapper userMapper = getApplicationContext().getBean(UserMapper.class); - - return userRequest -> { - // Delegate to the default implementation for loading a user - OidcUser oidcUser = delegate.loadUser(userRequest); - - Set<GrantedAuthority> mappedAuthorities = new HashSet<>(); - mappedAuthorities.addAll(oidcUser.getAuthorities()); - - String email = oidcUser.getEmail(); - - Optional<at.ac.uibk.gitsearch.domain.User> userO = userService.getUserWithAuthoritiesByEmail(email); - - if(userO.isPresent()) { - AdminUserDTO adminUserDto = userMapper.userToAdminUserDTO(userO.get()); - boolean hasChanged = userDetailsFetcher.updateUserDetails(adminUserDto, oidcUser, userRequest.getAccessToken(), userRequest.getClientRegistration()); - if (hasChanged) - userService.updateUser(adminUserDto); - - userO.get().getAuthorities() - .forEach( - - auth -> { - if(mappedAuthorities.stream() - .filter(existingAuth -> existingAuth.getAuthority().equals(auth.getName())) - .findAny().isEmpty()) { - mappedAuthorities.add(new SimpleGrantedAuthority(auth.getName()));} - } - ); - } else { - AdminUserDTO u = new AdminUserDTO(); - u.setFirstName(oidcUser.getGivenName()); - u.setLastName(oidcUser.getFamilyName()); - u.setLogin(email); - u.setActivated(true); - u.setLastModifiedBy("system"); - u.setCreatedDate(java.time.Instant.now()); - - u.setAuthorities(defaultAuthorities); - u.setEmail(oidcUser.getEmail()); - @SuppressWarnings("unused") - boolean hasChanged = userDetailsFetcher.updateUserDetails(u, oidcUser, userRequest.getAccessToken(), userRequest.getClientRegistration()); - userService.createUser(u); - } - - Map<String, Object> claims = new HashMap<>( oidcUser.getUserInfo().getClaims()); - claims.put(TokenProvider.GITLAB_ACCESS_TOKEN, userRequest.getAccessToken().getTokenValue()); - claims.put(TokenProvider.GITLAB_ACCESS_ISSUER, userRequest.getClientRegistration().getRegistrationId()); - OidcUserInfo userInfo = new OidcUserInfo(claims); - - oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), userInfo); - - return oidcUser; - }; - } - -} + @Bean + public AuthorizationRequestRepository<OAuth2AuthorizationRequest> getOAuth2AuthorizatinRequestRepository() { + return new GitSearchOAuth2AuthorizationRequestRepository(); + } + + private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService() { + final OidcUserService delegate = new OidcUserService(); + + final Set<String> defaultAuthorities = new HashSet<>(); + defaultAuthorities.add(AuthoritiesConstants.USER); + final UserService userService = getApplicationContext().getBean(UserService.class); + final UserMapper userMapper = getApplicationContext().getBean(UserMapper.class); + + return userRequest -> { + // Delegate to the default implementation for loading a user + OidcUser oidcUser = delegate.loadUser(userRequest); + + Set<GrantedAuthority> mappedAuthorities = new HashSet<>(); + mappedAuthorities.addAll(oidcUser.getAuthorities()); + + String email = oidcUser.getEmail(); + + Optional<at.ac.uibk.gitsearch.domain.User> userO = userService.getUserWithAuthoritiesByEmail(email); + + if (userO.isPresent()) { + AdminUserDTO adminUserDto = userMapper.userToAdminUserDTO(userO.get()); + boolean hasChanged = userDetailsFetcher.updateUserDetails( + adminUserDto, + oidcUser, + userRequest.getAccessToken(), + userRequest.getClientRegistration() + ); + if (hasChanged) userService.updateUser(adminUserDto); + + userO + .get() + .getAuthorities() + .forEach(auth -> { + if ( + mappedAuthorities + .stream() + .filter(existingAuth -> existingAuth.getAuthority().equals(auth.getName())) + .findAny() + .isEmpty() + ) { + mappedAuthorities.add(new SimpleGrantedAuthority(auth.getName())); + } + }); + } else { + AdminUserDTO u = new AdminUserDTO(); + u.setFirstName(oidcUser.getGivenName()); + u.setLastName(oidcUser.getFamilyName()); + u.setLogin(email); + u.setActivated(true); + u.setLastModifiedBy("system"); + u.setCreatedDate(java.time.Instant.now()); + + u.setAuthorities(defaultAuthorities); + u.setEmail(oidcUser.getEmail()); + @SuppressWarnings("unused") + boolean hasChanged = userDetailsFetcher.updateUserDetails( + u, + oidcUser, + userRequest.getAccessToken(), + userRequest.getClientRegistration() + ); + userService.createUser(u); + } + + Map<String, Object> claims = new HashMap<>(oidcUser.getUserInfo().getClaims()); + claims.put(TokenProvider.GITLAB_ACCESS_TOKEN, userRequest.getAccessToken().getTokenValue()); + claims.put(TokenProvider.GITLAB_ACCESS_ISSUER, userRequest.getClientRegistration().getRegistrationId()); + OidcUserInfo userInfo = new OidcUserInfo(claims); + + oidcUser = new DefaultOidcUser(mappedAuthorities, oidcUser.getIdToken(), userInfo); + + return oidcUser; + }; + } +} diff --git a/src/main/java/at/ac/uibk/gitsearch/domain/Authority.java b/src/main/java/at/ac/uibk/gitsearch/domain/Authority.java index 687930941e91144519eca68262abfcab79b5988a..0911e6c5e88d1839597fbd5727def283c9f60631 100644 --- a/src/main/java/at/ac/uibk/gitsearch/domain/Authority.java +++ b/src/main/java/at/ac/uibk/gitsearch/domain/Authority.java @@ -1,15 +1,15 @@ package at.ac.uibk.gitsearch.domain; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; +import java.io.Serializable; +import java.util.Objects; +import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; -import javax.persistence.Column; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; -import java.io.Serializable; -import java.util.Objects; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; /** * An authority (a security role) used by Spring Security. @@ -22,13 +22,13 @@ public class Authority implements Serializable { private static final long serialVersionUID = 1L; public Authority(@NotNull @Size(max = 50) String name) { - super(); - this.name = name; - } + super(); + this.name = name; + } public Authority() { - // For JPA - } + // For JPA + } @NotNull @Size(max = 50) @@ -67,13 +67,12 @@ public class Authority implements Serializable { "name='" + name + '\'' + "}"; } - + public boolean isStandardRole() { - return isStandardRole(name); + return isStandardRole(name); } - + public static boolean isStandardRole(String name) { - return name.startsWith("ROLE_"); + return name.startsWith("ROLE_"); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/domain/Likes.java b/src/main/java/at/ac/uibk/gitsearch/domain/Likes.java index 779b34f1d4e6e231bd307cd6b77a3b381df67c01..316553320712b1f340bc89f4e0d0eea14e53288e 100644 --- a/src/main/java/at/ac/uibk/gitsearch/domain/Likes.java +++ b/src/main/java/at/ac/uibk/gitsearch/domain/Likes.java @@ -2,7 +2,6 @@ package at.ac.uibk.gitsearch.domain; import java.io.Serializable; import java.time.LocalDate; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -10,7 +9,6 @@ import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; import javax.validation.constraints.NotNull; - import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @@ -88,6 +86,7 @@ public class Likes implements Serializable { public void setExerciseID(String exerciseID) { this.exerciseID = exerciseID; } + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here @Override diff --git a/src/main/java/at/ac/uibk/gitsearch/domain/PersistentAuditEvent.java b/src/main/java/at/ac/uibk/gitsearch/domain/PersistentAuditEvent.java index a62dca09dad52a9acb00800038ef7d149533262a..790c72560f48f9e6f0fa6b345575f21fb2cf6c1f 100644 --- a/src/main/java/at/ac/uibk/gitsearch/domain/PersistentAuditEvent.java +++ b/src/main/java/at/ac/uibk/gitsearch/domain/PersistentAuditEvent.java @@ -1,11 +1,11 @@ package at.ac.uibk.gitsearch.domain; -import javax.persistence.*; -import javax.validation.constraints.NotNull; import java.io.Serializable; import java.time.Instant; import java.util.HashMap; import java.util.Map; +import javax.persistence.*; +import javax.validation.constraints.NotNull; /** * Persist AuditEvent managed by the Spring Boot actuator. @@ -36,7 +36,7 @@ public class PersistentAuditEvent implements Serializable { @ElementCollection @MapKeyColumn(name = "name") @Column(name = "value") - @CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns=@JoinColumn(name="event_id")) + @CollectionTable(name = "jhi_persistent_audit_evt_data", joinColumns = @JoinColumn(name = "event_id")) private Map<String, String> data = new HashMap<>(); public Long getId() { diff --git a/src/main/java/at/ac/uibk/gitsearch/domain/Statistics.java b/src/main/java/at/ac/uibk/gitsearch/domain/Statistics.java index 3c1ece460cd05aab3c7bb7c333c7678f8ffa014c..ace3712aff4cbecf15a27fcae4da9a48de3a07ec 100644 --- a/src/main/java/at/ac/uibk/gitsearch/domain/Statistics.java +++ b/src/main/java/at/ac/uibk/gitsearch/domain/Statistics.java @@ -1,12 +1,10 @@ package at.ac.uibk.gitsearch.domain; -import org.hibernate.annotations.Cache; -import org.hibernate.annotations.CacheConcurrencyStrategy; - +import java.io.Serializable; import javax.persistence.*; import javax.validation.constraints.*; - -import java.io.Serializable; +import org.hibernate.annotations.Cache; +import org.hibernate.annotations.CacheConcurrencyStrategy; /** * A Statistics. @@ -80,6 +78,7 @@ public class Statistics implements Serializable { public void setExerciseID(String exerciseID) { this.exerciseID = exerciseID; } + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here @Override diff --git a/src/main/java/at/ac/uibk/gitsearch/domain/User.java b/src/main/java/at/ac/uibk/gitsearch/domain/User.java index 8f3fa99111cca15cd969ea54474b256eaae44243..71622b231053793a284822641119b78331d1a6d3 100644 --- a/src/main/java/at/ac/uibk/gitsearch/domain/User.java +++ b/src/main/java/at/ac/uibk/gitsearch/domain/User.java @@ -1,11 +1,12 @@ package at.ac.uibk.gitsearch.domain; +import at.ac.uibk.gitsearch.config.Constants; +import com.fasterxml.jackson.annotation.JsonIgnore; import java.io.Serializable; import java.time.Instant; import java.util.HashSet; import java.util.Locale; import java.util.Set; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -19,16 +20,11 @@ import javax.validation.constraints.Email; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; - import org.apache.commons.lang3.StringUtils; import org.hibernate.annotations.BatchSize; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; -import com.fasterxml.jackson.annotation.JsonIgnore; - -import at.ac.uibk.gitsearch.config.Constants; - /** * A user. */ @@ -94,7 +90,6 @@ public class User extends AbstractAuditingEntity implements Serializable { @Column(name = "reset_date") private Instant resetDate = null; - @Column(name = "last_login", nullable = true) private Instant lastLogin; @@ -233,7 +228,6 @@ public class User extends AbstractAuditingEntity implements Serializable { this.lastMailSent = lastMailSent; } - @Override public boolean equals(Object o) { if (this == o) { diff --git a/src/main/java/at/ac/uibk/gitsearch/domain/UserWatchList.java b/src/main/java/at/ac/uibk/gitsearch/domain/UserWatchList.java index dcdc724c98c148fa75144661af1df90e4d72927a..9b4e6a20e291700ad9aec9d2273305e72f45e2a0 100644 --- a/src/main/java/at/ac/uibk/gitsearch/domain/UserWatchList.java +++ b/src/main/java/at/ac/uibk/gitsearch/domain/UserWatchList.java @@ -1,9 +1,10 @@ package at.ac.uibk.gitsearch.domain; +import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.io.Serializable; import java.util.HashSet; import java.util.Set; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; @@ -17,14 +18,9 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; - import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; - /** * A UserWatchList. */ @@ -34,19 +30,19 @@ import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; @org.springframework.data.elasticsearch.annotations.Document(indexName = "userwatchlist") public class UserWatchList implements Serializable { - public UserWatchList(@NotNull @Size(min = 1) String name, @NotNull CheckFrequency checkFrequency, - @NotNull User user) { - super(); - this.name = name; - this.checkFrequency = checkFrequency; - this.user = user; - this.watchListEntries = new HashSet<>(); - } + public UserWatchList(@NotNull @Size(min = 1) String name, @NotNull CheckFrequency checkFrequency, @NotNull User user) { + super(); + this.name = name; + this.checkFrequency = checkFrequency; + this.user = user; + this.watchListEntries = new HashSet<>(); + } public UserWatchList() { - // JPA + // JPA } - private static final long serialVersionUID = 1L; + + private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -70,7 +66,7 @@ public class UserWatchList implements Serializable { @OneToMany(mappedBy = "watchlist", orphanRemoval = true) private Set<WatchListEntry> watchListEntries; - + // jhipster-needle-entity-add-field - JHipster will add fields here public Long getId() { return id; @@ -113,21 +109,22 @@ public class UserWatchList implements Serializable { public void setUser(User user) { this.user = user; } + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here /** - * @return the watchListEntries - */ - public Set<WatchListEntry> getWatchListEntries() { - return watchListEntries; - } - - /** - * @param watchListEntries the watchListEntries to set - */ - public void setWatchListEntries(Set<WatchListEntry> watchListEntries) { - this.watchListEntries = watchListEntries; - } + * @return the watchListEntries + */ + public Set<WatchListEntry> getWatchListEntries() { + return watchListEntries; + } + + /** + * @param watchListEntries the watchListEntries to set + */ + public void setWatchListEntries(Set<WatchListEntry> watchListEntries) { + this.watchListEntries = watchListEntries; + } @Override public boolean equals(Object o) { diff --git a/src/main/java/at/ac/uibk/gitsearch/domain/WatchListEntry.java b/src/main/java/at/ac/uibk/gitsearch/domain/WatchListEntry.java index aed72ecec2eecd067c56e0fc95bf4fabba61430e..d2aa7df73db9e7abddde93f4ce66d46e53be048d 100644 --- a/src/main/java/at/ac/uibk/gitsearch/domain/WatchListEntry.java +++ b/src/main/java/at/ac/uibk/gitsearch/domain/WatchListEntry.java @@ -1,7 +1,7 @@ package at.ac.uibk.gitsearch.domain; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.io.Serializable; - import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -10,12 +10,9 @@ import javax.persistence.Id; import javax.persistence.ManyToOne; import javax.persistence.Table; import javax.validation.constraints.NotNull; - import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - /** * A WatchListEntry. */ @@ -90,6 +87,7 @@ public class WatchListEntry implements Serializable { public void setWatchlist(UserWatchList userWatchList) { this.watchlist = userWatchList; } + // jhipster-needle-entity-add-getters-setters - JHipster will add getters and setters here @Override diff --git a/src/main/java/at/ac/uibk/gitsearch/domain/enumeration/CheckFrequency.java b/src/main/java/at/ac/uibk/gitsearch/domain/enumeration/CheckFrequency.java index 1296cc32c0abd51fc25c7f4f61aa3ea457fa0000..319b05c0aa6d25af6973c7a07f82cc74b8405ab8 100644 --- a/src/main/java/at/ac/uibk/gitsearch/domain/enumeration/CheckFrequency.java +++ b/src/main/java/at/ac/uibk/gitsearch/domain/enumeration/CheckFrequency.java @@ -7,17 +7,24 @@ import java.time.temporal.ChronoUnit; * The CheckFrequency enumeration. */ public enum CheckFrequency { - NEVER, DAILY, WEEKLY, MONTHLY; - - public Instant getChangedBefore() { - Instant now = Instant.now(); - switch(this) { - case NEVER: return now; - case DAILY: return now.minus(1, ChronoUnit.DAYS); - case WEEKLY: return now.minus(7, ChronoUnit.DAYS); - case MONTHLY: return now.minus(30, ChronoUnit.DAYS); - default: // should never happen - return now; - } - } + NEVER, + DAILY, + WEEKLY, + MONTHLY; + + public Instant getChangedBefore() { + Instant now = Instant.now(); + switch (this) { + case NEVER: + return now; + case DAILY: + return now.minus(1, ChronoUnit.DAYS); + case WEEKLY: + return now.minus(7, ChronoUnit.DAYS); + case MONTHLY: + return now.minus(30, ChronoUnit.DAYS); + default: // should never happen + return now; + } + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/es/model/ArtemisExerciseInfo.java b/src/main/java/at/ac/uibk/gitsearch/es/model/ArtemisExerciseInfo.java index f63a6526851ff19d4cf8968ba377519273932c26..67d07e74dd9356a09723764f6e160c43b70260a8 100644 --- a/src/main/java/at/ac/uibk/gitsearch/es/model/ArtemisExerciseInfo.java +++ b/src/main/java/at/ac/uibk/gitsearch/es/model/ArtemisExerciseInfo.java @@ -2,7 +2,6 @@ package at.ac.uibk.gitsearch.es.model; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - import java.util.Objects; @JsonIgnoreProperties(ignoreUnknown = true) @@ -24,9 +23,7 @@ public class ArtemisExerciseInfo extends ExerciseInfo { private Boolean sequentialTestRuns; - public ArtemisExerciseInfo() { - - } + public ArtemisExerciseInfo() {} public Float getMaxPoints() { return maxPoints; @@ -249,15 +246,37 @@ public class ArtemisExerciseInfo extends ExerciseInfo { public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; - if(!super.equals(o)) return false; + if (!super.equals(o)) return false; ArtemisExerciseInfo that = (ArtemisExerciseInfo) o; - return Objects.equals(getMaxPoints(), that.getMaxPoints()) && Objects.equals(getBonusPoints(), that.getBonusPoints()) && getMode() == that.getMode() && Objects.equals(getStaticCodeAnalysis(), that.getStaticCodeAnalysis()) && Objects.equals(getAllowOfflineIDE(), that.getAllowOfflineIDE()) && Objects.equals(getAllowOnlineEditor(), that.getAllowOnlineEditor()) && Objects.equals(getShowTestNamesToStudents(), that.getShowTestNamesToStudents()) && Objects.equals(getSequentialTestRuns(), that.getSequentialTestRuns()); + return ( + Objects.equals(getMaxPoints(), that.getMaxPoints()) && + Objects.equals(getBonusPoints(), that.getBonusPoints()) && + getMode() == that.getMode() && + Objects.equals(getStaticCodeAnalysis(), that.getStaticCodeAnalysis()) && + Objects.equals(getAllowOfflineIDE(), that.getAllowOfflineIDE()) && + Objects.equals(getAllowOnlineEditor(), that.getAllowOnlineEditor()) && + Objects.equals(getShowTestNamesToStudents(), that.getShowTestNamesToStudents()) && + Objects.equals(getSequentialTestRuns(), that.getSequentialTestRuns()) + ); } @Override public int hashCode() { - return Objects.hash(super.hashCode(), getMaxPoints(), getBonusPoints(), getMode(), getStaticCodeAnalysis(), getAllowOfflineIDE(), getAllowOnlineEditor(), getShowTestNamesToStudents(), getSequentialTestRuns()); + return Objects.hash( + super.hashCode(), + getMaxPoints(), + getBonusPoints(), + getMode(), + getStaticCodeAnalysis(), + getAllowOfflineIDE(), + getAllowOnlineEditor(), + getShowTestNamesToStudents(), + getSequentialTestRuns() + ); } - public enum ExerciseMode {INDIVIDUAL, TEAM} + public enum ExerciseMode { + INDIVIDUAL, + TEAM, + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/es/model/DocumentInfo.java b/src/main/java/at/ac/uibk/gitsearch/es/model/DocumentInfo.java index c74d9644e22c7f044197e1d2317deaa73bddf992..948696cde1e316dd33b36f5e9cfd62dab84dac37 100644 --- a/src/main/java/at/ac/uibk/gitsearch/es/model/DocumentInfo.java +++ b/src/main/java/at/ac/uibk/gitsearch/es/model/DocumentInfo.java @@ -1,12 +1,12 @@ package at.ac.uibk.gitsearch.es.model; +import static org.springframework.data.elasticsearch.annotations.FieldType.Text; + import org.springframework.data.annotation.Id; import org.springframework.data.elasticsearch.annotations.Document; import org.springframework.data.elasticsearch.annotations.Field; -import static org.springframework.data.elasticsearch.annotations.FieldType.Text; - -@Document(indexName="codeability.sharing" /*, type = "_doc"*/) +@Document(indexName = "codeability.sharing"/*, type = "_doc"*/) public class DocumentInfo { @Id @@ -20,12 +20,12 @@ public class DocumentInfo { private ProjectInfo project; public DocumentInfo() { - // JSON + // JSON } @Override public String toString() { - return "Document{" + "content='" + content + ", " + file.toString() + ", " + project.toString() + '}'; + return "Document{" + "content='" + content + ", " + file.toString() + ", " + project.toString() + '}'; } public String getId() { diff --git a/src/main/java/at/ac/uibk/gitsearch/es/model/ExerciseInfo.java b/src/main/java/at/ac/uibk/gitsearch/es/model/ExerciseInfo.java index 2cedec4419e12271bb24964c8a19e56c9b0a687c..fd96fd2dba4988917217a12279732bb2f511e524 100644 --- a/src/main/java/at/ac/uibk/gitsearch/es/model/ExerciseInfo.java +++ b/src/main/java/at/ac/uibk/gitsearch/es/model/ExerciseInfo.java @@ -1,12 +1,10 @@ package at.ac.uibk.gitsearch.es.model; +import at.ac.uibk.gitsearch.service.dto.MetadataUserDTO; +import com.fasterxml.jackson.annotation.*; import java.util.List; -import java.util.stream.Collectors; import java.util.Objects; - -import com.fasterxml.jackson.annotation.*; - -import at.ac.uibk.gitsearch.service.dto.MetadataUserDTO; +import java.util.stream.Collectors; @JsonInclude(JsonInclude.Include.NON_NULL) public class ExerciseInfo { @@ -44,7 +42,7 @@ public class ExerciseInfo { private String version; public ExerciseInfo() { - // for JSON + // for JSON } public List<String> getAssesses() { @@ -179,15 +177,18 @@ public class ExerciseInfo { public List<String> getLanguage() { // re-map to metadata conform values if (language != null) { - return language.stream().map(entry -> { - switch (entry) { - case "english": - return "en"; - case "german": - return "de"; - } - return entry; - }).collect(Collectors.toList()); + return language + .stream() + .map(entry -> { + switch (entry) { + case "english": + return "en"; + case "german": + return "de"; + } + return entry; + }) + .collect(Collectors.toList()); } else { return null; } @@ -312,39 +313,72 @@ public class ExerciseInfo { @Override public String toString() { - return "ExerciseInfo {" - + ", assesses=" + assesses - + ", audience=" + audience - + ", contributor=" + contributor - + ", creator=" + creator - + ", description=" + description - + ", difficulty=" + difficulty - + ", educationalAlignment=" + educationalAlignment - + ", educationalFramework=" + educationalFramework - + ", educationalLevel=" + educationalLevel - + ", educationalUse=" + educationalUse - + ", format=" + format - + ", identifier=" + identifier - + ", image=" + image - + ", interactivityType=" + interactivityType - + ", isBasedOn=" + isBasedOn - + ", keyword=" + keyword - + ", language=" + language - + ", learningResourceType=" + learningResourceType - + ", license=" + license - + ", metadataVersion=" + metadataVersion - + ", programmingLanguage=" + programmingLanguage - + ", publisher=" + publisher - + ", requires=" + requires - + ", status=" + status - + ", structure=" + structure - + ", subject=" + subject - + ", teaches=" + teaches - + ", timeRequired=" + timeRequired - + ", title=" + title - + ", typicalAgeRange=" + typicalAgeRange - + ", version=" + version - + '}'; + return ( + "ExerciseInfo {" + + ", assesses=" + + assesses + + ", audience=" + + audience + + ", contributor=" + + contributor + + ", creator=" + + creator + + ", description=" + + description + + ", difficulty=" + + difficulty + + ", educationalAlignment=" + + educationalAlignment + + ", educationalFramework=" + + educationalFramework + + ", educationalLevel=" + + educationalLevel + + ", educationalUse=" + + educationalUse + + ", format=" + + format + + ", identifier=" + + identifier + + ", image=" + + image + + ", interactivityType=" + + interactivityType + + ", isBasedOn=" + + isBasedOn + + ", keyword=" + + keyword + + ", language=" + + language + + ", learningResourceType=" + + learningResourceType + + ", license=" + + license + + ", metadataVersion=" + + metadataVersion + + ", programmingLanguage=" + + programmingLanguage + + ", publisher=" + + publisher + + ", requires=" + + requires + + ", status=" + + status + + ", structure=" + + structure + + ", subject=" + + subject + + ", teaches=" + + teaches + + ", timeRequired=" + + timeRequired + + ", title=" + + title + + ", typicalAgeRange=" + + typicalAgeRange + + ", version=" + + version + + '}' + ); } @JsonFormat(with = JsonFormat.Feature.ACCEPT_CASE_INSENSITIVE_PROPERTIES) @@ -352,7 +386,8 @@ public class ExerciseInfo { ACTIVE("active"), EXPOSITIVE("expositive"), MIXED("mixed"), - @JsonEnumDefaultValue UNSPECIFIED("unspecified"); + @JsonEnumDefaultValue + UNSPECIFIED("unspecified"); InteractivityType(String s) {} @@ -372,7 +407,8 @@ public class ExerciseInfo { SIMPLE("simple"), MEDIUM("medium"), ADVANCED("advanced"), - @JsonEnumDefaultValue NONE("none"); + @JsonEnumDefaultValue + NONE("none"); ExerciseDifficulty(String s) {} @@ -387,10 +423,10 @@ public class ExerciseInfo { } } - @Override - public int hashCode() { - final int prime = 31; - int result = 1; + @Override + public int hashCode() { + final int prime = 31; + int result = 1; result = prime * result + ((assesses == null) ? 0 : assesses.hashCode()); result = prime * result + ((audience == null) ? 0 : audience.hashCode()); result = prime * result + ((contributor == null) ? 0 : contributor.hashCode()); @@ -422,48 +458,47 @@ public class ExerciseInfo { result = prime * result + ((title == null) ? 0 : title.hashCode()); result = prime * result + ((typicalAgeRange == null) ? 0 : typicalAgeRange.hashCode()); result = prime * result + ((version == null) ? 0 : version.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof ExerciseInfo)) - return false; - ExerciseInfo other = (ExerciseInfo) obj; - return Objects.equals(this.assesses, other.assesses) - && Objects.equals(this.audience, other.audience) - && Objects.equals(this.contributor, other.contributor) - && Objects.equals(this.creator, other.creator) - && Objects.equals(this.description, other.description) - && Objects.equals(this.difficulty, other.difficulty) - && Objects.equals(this.educationalAlignment, other.educationalAlignment) - && Objects.equals(this.educationalFramework, other.educationalFramework) - && Objects.equals(this.educationalLevel, other.educationalLevel) - && Objects.equals(this.educationalUse, other.educationalUse) - && Objects.equals(this.format, other.format) - && Objects.equals(this.identifier, other.identifier) - && Objects.equals(this.image, other.image) - && this.interactivityType == other.interactivityType - && Objects.equals(this.isBasedOn, other.isBasedOn) - && Objects.equals(this.keyword, other.keyword) - && Objects.equals(this.language, other.language) - && Objects.equals(this.learningResourceType, other.learningResourceType) - && Objects.equals(this.license, other.license) - && Objects.equals(this.metadataVersion, other.metadataVersion) - && Objects.equals(this.programmingLanguage, other.programmingLanguage) - && Objects.equals(this.publisher, other.publisher) - && Objects.equals(this.requires, other.requires) - && Objects.equals(this.status, other.status) - && Objects.equals(this.structure, other.structure) - && Objects.equals(this.subject, other.subject) - && Objects.equals(this.teaches, other.teaches) - && Objects.equals(this.timeRequired, other.timeRequired) - && Objects.equals(this.title, other.title) - && Objects.equals(this.typicalAgeRange, other.typicalAgeRange) - && Objects.equals(this.version, other.version); - } + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (!(obj instanceof ExerciseInfo)) return false; + ExerciseInfo other = (ExerciseInfo) obj; + return ( + Objects.equals(this.assesses, other.assesses) && + Objects.equals(this.audience, other.audience) && + Objects.equals(this.contributor, other.contributor) && + Objects.equals(this.creator, other.creator) && + Objects.equals(this.description, other.description) && + Objects.equals(this.difficulty, other.difficulty) && + Objects.equals(this.educationalAlignment, other.educationalAlignment) && + Objects.equals(this.educationalFramework, other.educationalFramework) && + Objects.equals(this.educationalLevel, other.educationalLevel) && + Objects.equals(this.educationalUse, other.educationalUse) && + Objects.equals(this.format, other.format) && + Objects.equals(this.identifier, other.identifier) && + Objects.equals(this.image, other.image) && + this.interactivityType == other.interactivityType && + Objects.equals(this.isBasedOn, other.isBasedOn) && + Objects.equals(this.keyword, other.keyword) && + Objects.equals(this.language, other.language) && + Objects.equals(this.learningResourceType, other.learningResourceType) && + Objects.equals(this.license, other.license) && + Objects.equals(this.metadataVersion, other.metadataVersion) && + Objects.equals(this.programmingLanguage, other.programmingLanguage) && + Objects.equals(this.publisher, other.publisher) && + Objects.equals(this.requires, other.requires) && + Objects.equals(this.status, other.status) && + Objects.equals(this.structure, other.structure) && + Objects.equals(this.subject, other.subject) && + Objects.equals(this.teaches, other.teaches) && + Objects.equals(this.timeRequired, other.timeRequired) && + Objects.equals(this.title, other.title) && + Objects.equals(this.typicalAgeRange, other.typicalAgeRange) && + Objects.equals(this.version, other.version) + ); + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/es/model/ProjectInfo.java b/src/main/java/at/ac/uibk/gitsearch/es/model/ProjectInfo.java index ccc98fd1d3acd7c79397fb9670821b964bacd5db..71a7ea7b148b7979b41076c35f762279a7100850 100644 --- a/src/main/java/at/ac/uibk/gitsearch/es/model/ProjectInfo.java +++ b/src/main/java/at/ac/uibk/gitsearch/es/model/ProjectInfo.java @@ -1,6 +1,7 @@ package at.ac.uibk.gitsearch.es.model; public class ProjectInfo { + private long project_id; private String project_name; private String url; diff --git a/src/main/java/at/ac/uibk/gitsearch/properties/ApplicationProperties.java b/src/main/java/at/ac/uibk/gitsearch/properties/ApplicationProperties.java index 967f41e80f47aa5445e67342c38a5da01795dec0..bcaadc3f19f9ac3635af3fc69ffa60e2a6ed9eca 100644 --- a/src/main/java/at/ac/uibk/gitsearch/properties/ApplicationProperties.java +++ b/src/main/java/at/ac/uibk/gitsearch/properties/ApplicationProperties.java @@ -1,7 +1,6 @@ package at.ac.uibk.gitsearch.properties; import java.util.List; - import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -16,80 +15,84 @@ public class ApplicationProperties { private Search search; private GitLab gitLab; - + private String registeredConnectorsCallBackURL; - + private String installationName; - private String oerLink; - - private DeploymentInfo deploymentInfo; - - private List<RegisteredConnector> registeredConnectorss; + private String oerLink; + + private DeploymentInfo deploymentInfo; + + private List<RegisteredConnector> registeredConnectorss; public static class RegisteredConnector { - private String url; - private String accessToken; - /** - * @return the url - */ - public String getUrl() { - return url; - } - /** - * @param url the url to set - */ - public void setUrl(String url) { - this.url = url; - } - /** - * @return the accessToken - */ - public String getAccessToken() { - return accessToken; - } - /** - * @param accessToken the accessToken to set - */ - public void setAccessToken(String accessToken) { - this.accessToken = accessToken; - } - @Override - public String toString() { - String anonymizedAccessToken = accessToken; - if (accessToken!=null && accessToken.length() > 3) { - anonymizedAccessToken = accessToken.substring(3) + "..."; - } - return "RegisteredConnector [url=" + url + ", accessToken=" + anonymizedAccessToken + "]"; - } - - - + + private String url; + private String accessToken; + + /** + * @return the url + */ + public String getUrl() { + return url; + } + + /** + * @param url the url to set + */ + public void setUrl(String url) { + this.url = url; + } + + /** + * @return the accessToken + */ + public String getAccessToken() { + return accessToken; + } + + /** + * @param accessToken the accessToken to set + */ + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + @Override + public String toString() { + String anonymizedAccessToken = accessToken; + if (accessToken != null && accessToken.length() > 3) { + anonymizedAccessToken = accessToken.substring(3) + "..."; + } + return "RegisteredConnector [url=" + url + ", accessToken=" + anonymizedAccessToken + "]"; + } } + /** * a list of URLs of Connectors to be registered. - * @return the registeredConnectors - */ - public List<RegisteredConnector> getRegisteredConnectors() { - return registeredConnectorss; - } - - public String getOerLink() { - return oerLink; - } - - public void setOerLink(String oerLink) { - this.oerLink = oerLink; - } - - /** - * @param registeredConnectors the registeredConnectors to set - */ - public void setRegisteredConnectors(List<RegisteredConnector> registeredConnectors) { - this.registeredConnectorss = registeredConnectors; - } - - public Search getSearch() { + * @return the registeredConnectors + */ + public List<RegisteredConnector> getRegisteredConnectors() { + return registeredConnectorss; + } + + public String getOerLink() { + return oerLink; + } + + public void setOerLink(String oerLink) { + this.oerLink = oerLink; + } + + /** + * @param registeredConnectors the registeredConnectors to set + */ + public void setRegisteredConnectors(List<RegisteredConnector> registeredConnectors) { + this.registeredConnectorss = registeredConnectors; + } + + public Search getSearch() { return search; } @@ -97,7 +100,7 @@ public class ApplicationProperties { this.search = search; } - public GitLab getGitLab() { + public GitLab getGitLab() { return gitLab; } @@ -106,48 +109,48 @@ public class ApplicationProperties { } /** - * @return the registeredConnectorsCallBackURL - */ - public String getRegisteredConnectorsCallBackURL() { - return registeredConnectorsCallBackURL; - } - - /** - * @param registeredConnectorsCallBackURL the registeredConnectorsCallBackURL to set - */ - public void setRegisteredConnectorsCallBackURL(String registeredConnectorsCallBackURL) { - this.registeredConnectorsCallBackURL = registeredConnectorsCallBackURL; - } - - /** - * @return the name of this installation - */ - public String getInstallationName() { - return installationName; - } - - /** - * @param installationName the installationName to set - */ - public void setInstallationName(String installationName) { - this.installationName = installationName; - } - - /** - * @return the deploymentInfo - */ - public DeploymentInfo getDeploymentInfo() { - return deploymentInfo; - } - - /** - * @param deploymentInfo the deploymentInfo to set - */ - public void setDeploymentInfo(DeploymentInfo deploymentInfo) { - this.deploymentInfo = deploymentInfo; - } - - public static class Search { + * @return the registeredConnectorsCallBackURL + */ + public String getRegisteredConnectorsCallBackURL() { + return registeredConnectorsCallBackURL; + } + + /** + * @param registeredConnectorsCallBackURL the registeredConnectorsCallBackURL to set + */ + public void setRegisteredConnectorsCallBackURL(String registeredConnectorsCallBackURL) { + this.registeredConnectorsCallBackURL = registeredConnectorsCallBackURL; + } + + /** + * @return the name of this installation + */ + public String getInstallationName() { + return installationName; + } + + /** + * @param installationName the installationName to set + */ + public void setInstallationName(String installationName) { + this.installationName = installationName; + } + + /** + * @return the deploymentInfo + */ + public DeploymentInfo getDeploymentInfo() { + return deploymentInfo; + } + + /** + * @param deploymentInfo the deploymentInfo to set + */ + public void setDeploymentInfo(DeploymentInfo deploymentInfo) { + this.deploymentInfo = deploymentInfo; + } + + public static class Search { private String highlightPre; private String highlightPost; @@ -170,10 +173,11 @@ public class ApplicationProperties { } public static class GitLab { + private String url; private String guestAccessToken; private String adminAccessToken; - + public String getUrl() { return url; } @@ -182,79 +186,86 @@ public class ApplicationProperties { this.url = url; } - /** - * @return the guestAccessToken - */ - public String getGuestAccessToken() { - return guestAccessToken; - } - - /** - * @param guestAccessToken the guestAccessToken to set - */ - public void setGuestAccessToken(String guestAccessToken) { - this.guestAccessToken = guestAccessToken; - } - - /** - * @return the adminAccessToken - */ - public String getAdminAccessToken() { - return adminAccessToken; - } - - /** - * @param adminAccessToken the adminAccessToken to set - */ - public void setAdminAccessToken(String adminAccessToken) { - this.adminAccessToken = adminAccessToken; - } - + /** + * @return the guestAccessToken + */ + public String getGuestAccessToken() { + return guestAccessToken; + } + + /** + * @param guestAccessToken the guestAccessToken to set + */ + public void setGuestAccessToken(String guestAccessToken) { + this.guestAccessToken = guestAccessToken; + } + + /** + * @return the adminAccessToken + */ + public String getAdminAccessToken() { + return adminAccessToken; + } + + /** + * @param adminAccessToken the adminAccessToken to set + */ + public void setAdminAccessToken(String adminAccessToken) { + this.adminAccessToken = adminAccessToken; + } } - + public static class DeploymentInfo { - @Override - public String toString() { - return "DeploymentInfo [" + commitId + "/" + branch + "]"; - } - private String commitId = "---"; - private String branch = "---"; - private String deploymentDate = ""; - /** - * @return the commitId - */ - public String getCommitId() { - return commitId; - } - /** - * @param commitId the commitId to set - */ - public void setCommitId(String commitId) { - this.commitId = commitId; - } - /** - * @return the branch - */ - public String getBranch() { - return branch; - } - /** - * @param branch the branch to set - */ - public void setBranch(String branch) { - this.branch = branch; - } - /** - * @return the deploymentDate - */ - public String getDeploymentDate() { - return deploymentDate; - } - /** - * @param deploymentDate the deploymentDate to set - */ - public void setDeploymentDate(String deploymentDate) { - this.deploymentDate = deploymentDate; - } + + @Override + public String toString() { + return "DeploymentInfo [" + commitId + "/" + branch + "]"; + } + + private String commitId = "---"; + private String branch = "---"; + private String deploymentDate = ""; + + /** + * @return the commitId + */ + public String getCommitId() { + return commitId; + } + + /** + * @param commitId the commitId to set + */ + public void setCommitId(String commitId) { + this.commitId = commitId; + } + + /** + * @return the branch + */ + public String getBranch() { + return branch; + } + + /** + * @param branch the branch to set + */ + public void setBranch(String branch) { + this.branch = branch; + } + + /** + * @return the deploymentDate + */ + public String getDeploymentDate() { + return deploymentDate; + } + + /** + * @param deploymentDate the deploymentDate to set + */ + public void setDeploymentDate(String deploymentDate) { + this.deploymentDate = deploymentDate; + } } } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/AuditEventConverter.java b/src/main/java/at/ac/uibk/gitsearch/repository/AuditEventConverter.java index 30546166b9e973595df5dbc8d2108704451db364..bca0604f20eb89092276dcb51ea5bca96cab296f 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/AuditEventConverter.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/AuditEventConverter.java @@ -1,13 +1,11 @@ package at.ac.uibk.gitsearch.repository; import at.ac.uibk.gitsearch.domain.PersistentAuditEvent; - +import java.util.*; import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.stereotype.Component; -import java.util.*; - @Component public class AuditEventConverter { @@ -38,8 +36,12 @@ public class AuditEventConverter { if (persistentAuditEvent == null) { return null; } - return new AuditEvent(persistentAuditEvent.getAuditEventDate(), persistentAuditEvent.getPrincipal(), - persistentAuditEvent.getAuditEventType(), convertDataToObjects(persistentAuditEvent.getData())); + return new AuditEvent( + persistentAuditEvent.getAuditEventDate(), + persistentAuditEvent.getPrincipal(), + persistentAuditEvent.getAuditEventType(), + convertDataToObjects(persistentAuditEvent.getData()) + ); } /** diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/AuthorityRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/AuthorityRepository.java index e2015b1ce55a1c5e5ae183bc1d853a6efb17a4ca..ed12bdedf8ae0cb821e643033cae9f85f6280178 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/AuthorityRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/AuthorityRepository.java @@ -1,9 +1,7 @@ package at.ac.uibk.gitsearch.repository; import at.ac.uibk.gitsearch.domain.Authority; - import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; @@ -12,16 +10,14 @@ import org.springframework.data.jpa.repository.Query; * Spring Data JPA repository for the {@link Authority} entity. */ public interface AuthorityRepository extends JpaRepository<Authority, String> { - - @Query("DELETE FROM Authority auth WHERE not exists (SELECT u FROM User u WHERE auth member u.authorities)") - @Modifying - void deleteUnusedAuthorities(); - - /** - * mainly for test purposes only. Returns all authentications that are used by some user - * @return - */ - @Query("SELECT DISTINCT u.authorities FROM User u ") - List<Authority> getUsedAuthorities(); + @Query("DELETE FROM Authority auth WHERE not exists (SELECT u FROM User u WHERE auth member u.authorities)") + @Modifying + void deleteUnusedAuthorities(); + /** + * mainly for test purposes only. Returns all authentications that are used by some user + * @return + */ + @Query("SELECT DISTINCT u.authorities FROM User u ") + List<Authority> getUsedAuthorities(); } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/CustomAuditEventRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/CustomAuditEventRepository.java index 4b0ea692549aa8d981bc39c31c68b65573a5de2f..bb82956747ad2ffe209e3a340fb5d3cf42ab04dc 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/CustomAuditEventRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/CustomAuditEventRepository.java @@ -2,7 +2,8 @@ package at.ac.uibk.gitsearch.repository; import at.ac.uibk.gitsearch.config.Constants; import at.ac.uibk.gitsearch.domain.PersistentAuditEvent; - +import java.time.Instant; +import java.util.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.actuate.audit.AuditEvent; @@ -11,9 +12,6 @@ import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; -import java.time.Instant; -import java.util.*; - /** * An implementation of Spring Boot's {@link AuditEventRepository}. */ @@ -33,26 +31,28 @@ public class CustomAuditEventRepository implements AuditEventRepository { private final Logger log = LoggerFactory.getLogger(getClass()); - public CustomAuditEventRepository(PersistenceAuditEventRepository persistenceAuditEventRepository, - AuditEventConverter auditEventConverter) { - + public CustomAuditEventRepository( + PersistenceAuditEventRepository persistenceAuditEventRepository, + AuditEventConverter auditEventConverter + ) { this.persistenceAuditEventRepository = persistenceAuditEventRepository; this.auditEventConverter = auditEventConverter; } @Override public List<AuditEvent> find(String principal, Instant after, String type) { - Iterable<PersistentAuditEvent> persistentAuditEvents = - persistenceAuditEventRepository.findByPrincipalAndAuditEventDateAfterAndAuditEventType(principal, after, type); + Iterable<PersistentAuditEvent> persistentAuditEvents = persistenceAuditEventRepository.findByPrincipalAndAuditEventDateAfterAndAuditEventType( + principal, + after, + type + ); return auditEventConverter.convertToAuditEvent(persistentAuditEvents); } @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void add(AuditEvent event) { - if (!AUTHORIZATION_FAILURE.equals(event.getType()) && - !Constants.ANONYMOUS_USER.equals(event.getPrincipal())) { - + if (!AUTHORIZATION_FAILURE.equals(event.getType()) && !Constants.ANONYMOUS_USER.equals(event.getPrincipal())) { PersistentAuditEvent persistentAuditEvent = new PersistentAuditEvent(); persistentAuditEvent.setPrincipal(truncatePrincipal(event.getPrincipal())); persistentAuditEvent.setAuditEventType(event.getType()); @@ -67,12 +67,10 @@ public class CustomAuditEventRepository implements AuditEventRepository { * an OAuth2-Principal can get very long, so we truncate it here to 50 characters. */ private String truncatePrincipal(String principal) { - if(principal==null) return null; - if (principal.length() <= 50) // TODO make a constant - return principal; - else return principal.substring(0,50); - + if (principal == null) return null; + if (principal.length() <= 50) return principal; else return principal.substring(0, 50); // TODO make a constant } + /** * Truncate event data that might exceed column length. */ @@ -86,8 +84,12 @@ public class CustomAuditEventRepository implements AuditEventRepository { int length = value.length(); if (length > EVENT_DATA_COLUMN_MAX_LENGTH) { value = value.substring(0, EVENT_DATA_COLUMN_MAX_LENGTH); - log.warn("Event data for {} too long ({}) has been truncated to {}. Consider increasing column width.", - entry.getKey(), length, EVENT_DATA_COLUMN_MAX_LENGTH); + log.warn( + "Event data for {} too long ({}) has been truncated to {}. Consider increasing column width.", + entry.getKey(), + length, + EVENT_DATA_COLUMN_MAX_LENGTH + ); } } results.put(entry.getKey(), value); diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/LikesRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/LikesRepository.java index e8737cf1bb741d220dfd36aec154e98b3d3658d6..36a70a114c6594f6ae3eb0e4c0fb10681223245f 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/LikesRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/LikesRepository.java @@ -1,7 +1,6 @@ package at.ac.uibk.gitsearch.repository; import at.ac.uibk.gitsearch.domain.Likes; - import org.springframework.data.jpa.repository.*; import org.springframework.stereotype.Repository; @@ -10,7 +9,6 @@ import org.springframework.stereotype.Repository; */ @Repository public interface LikesRepository extends JpaRepository<Likes, Long>, JpaSpecificationExecutor<Likes> { - @Query(value = "SELECT * FROM likes u where u.user_id = ?1 and exercise_id = ?2", nativeQuery = true) Likes findLikesByUserIDandExerciseID(Integer userID, String exerciseID); diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/PersistenceAuditEventRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/PersistenceAuditEventRepository.java index 4b65971b0fc9d6e5996090087dda5bbdc4a5e930..5951bd528ac0dae37e04d2db5ae8158ee610a8f6 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/PersistenceAuditEventRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/PersistenceAuditEventRepository.java @@ -1,18 +1,16 @@ package at.ac.uibk.gitsearch.repository; import at.ac.uibk.gitsearch.domain.PersistentAuditEvent; +import java.time.Instant; +import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import java.time.Instant; -import java.util.List; - /** * Spring Data JPA repository for the {@link PersistentAuditEvent} entity. */ public interface PersistenceAuditEventRepository extends JpaRepository<PersistentAuditEvent, Long> { - List<PersistentAuditEvent> findByPrincipal(String principal); List<PersistentAuditEvent> findByPrincipalAndAuditEventDateAfterAndAuditEventType(String principal, Instant after, String type); diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/StatisticsRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/StatisticsRepository.java index b954c4fc9b1cc0d3ae5339c0d0e04cde977576a0..05b78584705890e0d55efb9b74c71440d95f10be 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/StatisticsRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/StatisticsRepository.java @@ -1,24 +1,21 @@ package at.ac.uibk.gitsearch.repository; +import at.ac.uibk.gitsearch.domain.Statistics; import java.util.List; import java.util.Optional; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; -import at.ac.uibk.gitsearch.domain.Statistics; - /** * Spring Data repository for the Statistics entity. */ @Repository public interface StatisticsRepository extends JpaRepository<Statistics, Long> { - Optional<Statistics> findByExerciseID(String id); @Query(value = "SELECT SUM(u.views) FROM statistics u WHERE u.exercise_id IN (?1)", nativeQuery = true) - Optional<Integer> findNumberOfViewsByExerciseIDs(List<String> list); + Optional<Integer> findNumberOfViewsByExerciseIDs(List<String> list); @Query(value = "SELECT SUM(u.downloads) FROM statistics u WHERE u.exercise_id IN (?1)", nativeQuery = true) Optional<Integer> findNumberOfDownloadsByExerciseIDs(List<String> list); diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/UserRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/UserRepository.java index 280bc286bbc550dbec67727f22d5166387355023..7f9fe727342ea22723d1f7671b8acb03e05e06c7 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/UserRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/UserRepository.java @@ -39,7 +39,6 @@ public interface UserRepository extends JpaRepository<User, Long> { Optional<User> findOneWithAuthoritiesByEmailIgnoreCase(String email); Page<User> findAllByIdNotNullAndActivatedIsTrue(Pageable pageable); - - Page<User> findAllByLoginNot(Pageable pageable, String login); + Page<User> findAllByLoginNot(Pageable pageable, String login); } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/UserWatchListRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/UserWatchListRepository.java index b590656ee8ac7b45836103e60a5d618134f39a49..2bf0ae307656e542f3c7c48e177c43c339744d4f 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/UserWatchListRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/UserWatchListRepository.java @@ -2,7 +2,7 @@ package at.ac.uibk.gitsearch.repository; import at.ac.uibk.gitsearch.domain.User; import at.ac.uibk.gitsearch.domain.UserWatchList; - +import java.util.List; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; @@ -11,29 +11,25 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import java.util.List; /** * Spring Data repository for the UserWatchList entity. */ @Repository public interface UserWatchListRepository extends JpaRepository<UserWatchList, Long>, JpaSpecificationExecutor<UserWatchList> { - @Query("select userWatchList from UserWatchList userWatchList where userWatchList.user.login = ?#{principal.username}") List<UserWatchList> findByUserIsCurrentUser(); - + @Query("select uwl from UserWatchList uwl where uwl.name LIKE CONCAT('%',:query,'%')") Page<UserWatchList> search(@Param("query") String query, Pageable pageable); - + /** - * Returns all watchlists of the current user. - * - * @param user the user - * @return the list of watchlists - */ - List<UserWatchList> findByUser(User user); + * Returns all watchlists of the current user. + * + * @param user the user + * @return the list of watchlists + */ + List<UserWatchList> findByUser(User user); @Query("select uwl from UserWatchList uwl where uwl.user.login = ?#{principal.username} AND uwl.name LIKE CONCAT('%',:query,'%')") Page<UserWatchList> searchForCurrentUser(@Param("query") String query, Pageable pageable); - - } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/WatchListEntryRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/WatchListEntryRepository.java index b20af840b1e2c5925cfe23fcb2af348ca2c56e65..0439d95017e2a9efffaeb8a1932963f39fcc39ae 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/WatchListEntryRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/WatchListEntryRepository.java @@ -1,24 +1,23 @@ package at.ac.uibk.gitsearch.repository; +import at.ac.uibk.gitsearch.domain.WatchListEntry; import java.util.List; - import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; -import at.ac.uibk.gitsearch.domain.WatchListEntry; - /** * Spring Data repository for the WatchListEntry entity. */ @Repository public interface WatchListEntryRepository extends JpaRepository<WatchListEntry, Long> { - - @Query("SELECT wle FROM WatchListEntry wle WHERE wle.watchlist.id=:watchListId") - public List<WatchListEntry> getEntriesByWatchlist(@Param("watchListId") Long watchListId); - - @Query("SELECT wle FROM WatchListEntry wle WHERE wle.watchlist.id=:watchListId AND wle.exerciseId=:exerciseId ") - public List<WatchListEntry> getEntriesByWatchlistAndExerciseId(@Param("watchListId") Long watchListId, @Param("exerciseId") String exerciseId); - + @Query("SELECT wle FROM WatchListEntry wle WHERE wle.watchlist.id=:watchListId") + public List<WatchListEntry> getEntriesByWatchlist(@Param("watchListId") Long watchListId); + + @Query("SELECT wle FROM WatchListEntry wle WHERE wle.watchlist.id=:watchListId AND wle.exerciseId=:exerciseId ") + public List<WatchListEntry> getEntriesByWatchlistAndExerciseId( + @Param("watchListId") Long watchListId, + @Param("exerciseId") String exerciseId + ); } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepository.java index 01bc823ca8216a987c999aea1276b419669fbf61..bda9f12315ccd3aa3f5c62031e8be20a749ee072 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepository.java @@ -1,7 +1,9 @@ package at.ac.uibk.gitsearch.repository.gitlab; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider.GitLabAccessInfo; import java.util.Optional; - import org.gitlab4j.api.Constants.TokenType; import org.gitlab4j.api.GitLabApi; import org.slf4j.Logger; @@ -10,83 +12,78 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; -import at.ac.uibk.gitsearch.properties.ApplicationProperties; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider.GitLabAccessInfo; - @Repository public class GitLabRepository { - - @SuppressWarnings("unused") - private final Logger log = LoggerFactory.getLogger(GitLabRepository.class); - + + @SuppressWarnings("unused") + private final Logger log = LoggerFactory.getLogger(GitLabRepository.class); + @Value("${application.gitlab.url}") private String repositoryURL; + @Value("${application.gitlab.guestAccessToken}") private String guestAccessToken; + @Value("${application.gitlab.adminAccessToken}") private String adminAccessToken; + @Autowired + protected TokenProvider tokenProvider; - @Autowired - protected TokenProvider tokenProvider; - @Autowired - protected ApplicationProperties applicationProperties; - - - public GitLabApi getGitLabApi() { - Optional<String> accessTokenO = getAccessTokenOfCurrentUser(); - boolean isPresent = accessTokenO.isPresent(); - GitLabApi gitLabApi = null; - if(isPresent) { - String idToken = accessTokenO.get(); - gitLabApi = new GitLabApi(repositoryURL, TokenType.OAUTH2_ACCESS, idToken); - } else { - gitLabApi = getGuestGitLabApi(); - } - return gitLabApi; - } - - /** - * returns the gitlab api authenticated as guest. - * @return - */ - public GitLabApi getGuestGitLabApi() { - GitLabApi gitLabApi; - gitLabApi = new GitLabApi(repositoryURL, TokenType.PRIVATE, guestAccessToken); - return gitLabApi; - } - - public GitLabApi getGitLabApi(Optional<GitLabAccessInfo> accessInfo) { - if(accessInfo.isPresent()) { - return new GitLabApi(accessInfo.get().getGitLabAccessIssuer(), TokenType.OAUTH2_ACCESS, accessInfo.get().getAccessToken()); - } - return new GitLabApi(repositoryURL, TokenType.PRIVATE, guestAccessToken); - } - - public GitLabApi getAdminGitLabApi() { - return new GitLabApi(repositoryURL, TokenType.PRIVATE, adminAccessToken); - } - - public GitLabApi getGitLabApi(String oAuth2Token) { - return new GitLabApi(repositoryURL, TokenType.OAUTH2_ACCESS, oAuth2Token); - } - - private Optional<String> getAccessTokenOfCurrentUser() { - Optional<String> accessTokenO = tokenProvider.getGitLabAccessToken(); - return accessTokenO; - } - - public Optional<GitLabAccessInfo> getGitLabAccessInfo() { - return tokenProvider.getGitLabAccessInfo(); + @Autowired + protected ApplicationProperties applicationProperties; + + public GitLabApi getGitLabApi() { + Optional<String> accessTokenO = getAccessTokenOfCurrentUser(); + boolean isPresent = accessTokenO.isPresent(); + GitLabApi gitLabApi = null; + if (isPresent) { + String idToken = accessTokenO.get(); + gitLabApi = new GitLabApi(repositoryURL, TokenType.OAUTH2_ACCESS, idToken); + } else { + gitLabApi = getGuestGitLabApi(); + } + return gitLabApi; + } + + /** + * returns the gitlab api authenticated as guest. + * @return + */ + public GitLabApi getGuestGitLabApi() { + GitLabApi gitLabApi; + gitLabApi = new GitLabApi(repositoryURL, TokenType.PRIVATE, guestAccessToken); + return gitLabApi; } - /** - * @return the repositoryURL - */ - public String getRepositoryURL() { - return repositoryURL; - } + public GitLabApi getGitLabApi(Optional<GitLabAccessInfo> accessInfo) { + if (accessInfo.isPresent()) { + return new GitLabApi(accessInfo.get().getGitLabAccessIssuer(), TokenType.OAUTH2_ACCESS, accessInfo.get().getAccessToken()); + } + return new GitLabApi(repositoryURL, TokenType.PRIVATE, guestAccessToken); + } + public GitLabApi getAdminGitLabApi() { + return new GitLabApi(repositoryURL, TokenType.PRIVATE, adminAccessToken); + } + + public GitLabApi getGitLabApi(String oAuth2Token) { + return new GitLabApi(repositoryURL, TokenType.OAUTH2_ACCESS, oAuth2Token); + } + private Optional<String> getAccessTokenOfCurrentUser() { + Optional<String> accessTokenO = tokenProvider.getGitLabAccessToken(); + return accessTokenO; + } + + public Optional<GitLabAccessInfo> getGitLabAccessInfo() { + return tokenProvider.getGitLabAccessInfo(); + } + + /** + * @return the repositoryURL + */ + public String getRepositoryURL() { + return repositoryURL; + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepository.java index 750df7fbb672c613f4a5b90eb06169bc8475baf6..2ad17cb1326b48bf7676e3664c09368b66a10f49 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepository.java @@ -1,14 +1,11 @@ package at.ac.uibk.gitsearch.repository.search; -import java.io.IOException; - -import org.codeability.sharing.plugins.api.search.SearchInputDTO; - import at.ac.uibk.gitsearch.service.dto.GitFilesAggregationDTO; import at.ac.uibk.gitsearch.service.dto.GitFilesPageDetailsDTO; +import java.io.IOException; +import org.codeability.sharing.plugins.api.search.SearchInputDTO; public interface GitFilesRepository { - GitFilesPageDetailsDTO pageDetails(SearchInputDTO searchInputDTO) throws IOException; GitFilesAggregationDTO aggregation(String query) throws IOException; diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepositoryImpl.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepositoryImpl.java index 25ca4c60e9ed6f617327c0971629f85cd65ba5a9..7521977ffbba3154dd7cdcea2401dda743e22dba 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepositoryImpl.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepositoryImpl.java @@ -1,10 +1,16 @@ package at.ac.uibk.gitsearch.repository.search; +import at.ac.uibk.gitsearch.es.model.DocumentInfo; +import at.ac.uibk.gitsearch.service.dto.GitFilesAggregationDTO; +import at.ac.uibk.gitsearch.service.dto.GitFilesDTO; +import at.ac.uibk.gitsearch.service.dto.GitFilesPageDetailsDTO; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.List; - import org.codeability.sharing.plugins.api.search.SearchInputDTO; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; @@ -20,24 +26,14 @@ import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Repository; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; - -import at.ac.uibk.gitsearch.es.model.DocumentInfo; -import at.ac.uibk.gitsearch.service.dto.GitFilesAggregationDTO; -import at.ac.uibk.gitsearch.service.dto.GitFilesDTO; -import at.ac.uibk.gitsearch.service.dto.GitFilesPageDetailsDTO; - @Repository public class GitFilesRepositoryImpl implements GitFilesRepository { - + @Value("${application.search.highlight-pre}") - private String preTags; + private String preTags; + @Value("${application.search.highlight-post}") - private String postTags; - - + private String postTags; private final RestHighLevelClient elasticsearchClient; @@ -48,26 +44,25 @@ public class GitFilesRepositoryImpl implements GitFilesRepository { } @SuppressWarnings("deprecation") - @Override + @Override public GitFilesPageDetailsDTO pageDetails(SearchInputDTO searchInputDTO) throws IOException { Collection<String> projectIDs = searchProjectsIDsMetadata(searchInputDTO); SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_FULLTEXT); - BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery() - .must(QueryBuilders - .simpleQueryStringQuery(searchInputDTO.getFulltextQuery()) - .field(SearchRepositoryConstants.FULLTEXT_CONTENT)); - + BoolQueryBuilder queryBuilder = QueryBuilders + .boolQuery() + .must( + QueryBuilders.simpleQueryStringQuery(searchInputDTO.getFulltextQuery()).field(SearchRepositoryConstants.FULLTEXT_CONTENT) + ); addFulltextSelection(queryBuilder, searchInputDTO.getSelectedRepository(), SearchRepositoryConstants.FULLTEXT_REPOSITORY); addFulltextSelection(queryBuilder, searchInputDTO.getSelectedRepository(), SearchRepositoryConstants.FULLTEXT_SUB_GROUP); addFulltextSelection(queryBuilder, searchInputDTO.getSelectedFileFormat(), SearchRepositoryConstants.FULLTEXT_FILE_EXTENSION); if (projectIDs != null) { - queryBuilder - .filter(QueryBuilders.termsQuery(SearchRepositoryConstants.FULLTEXT_PROJECT_ID, projectIDs)); + queryBuilder.filter(QueryBuilders.termsQuery(SearchRepositoryConstants.FULLTEXT_PROJECT_ID, projectIDs)); } - char[] boundaryChars = {'\n'}; + char[] boundaryChars = { '\n' }; HighlightBuilder highlightBuilder = new HighlightBuilder() .highlighterType("plain") @@ -82,7 +77,8 @@ public class GitFilesRepositoryImpl implements GitFilesRepository { //String[] excludes = {HighlightRepositoryConstants.CONTENT_FIELD}; SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - sourceBuilder.query(queryBuilder) + sourceBuilder + .query(queryBuilder) .highlighter(highlightBuilder) .size(searchInputDTO.getPageSize()) .from((searchInputDTO.getPage() - 1) * searchInputDTO.getPageSize()); @@ -116,7 +112,8 @@ public class GitFilesRepositoryImpl implements GitFilesRepository { public GitFilesAggregationDTO aggregation(String query) throws IOException { SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_FULLTEXT); - BoolQueryBuilder matchQueryBuilder = QueryBuilders.boolQuery() + BoolQueryBuilder matchQueryBuilder = QueryBuilders + .boolQuery() .must(QueryBuilders.simpleQueryStringQuery(query).field(SearchRepositoryConstants.FULLTEXT_CONTENT)); TermsAggregationBuilder groupSubGroup = AggregationBuilders @@ -151,7 +148,11 @@ public class GitFilesRepositoryImpl implements GitFilesRepository { } SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); - addMetadataQueryShould(queryBuilder, searchInputDTO.getMetadata().getProgrammingLanguage(), SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES); + addMetadataQueryShould( + queryBuilder, + searchInputDTO.getMetadata().getProgrammingLanguage(), + SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES + ); addMetadataQueryShould(queryBuilder, searchInputDTO.getMetadata().getKeyword(), SearchRepositoryConstants.METADATA_KEYWORDS); addMetadataQueryMust(queryBuilder, searchInputDTO.getMetadata().getAuthor(), SearchRepositoryConstants.METADATA_CREATOR); addMetadataQueryMust(queryBuilder, searchInputDTO.getMetadata().getLicense(), SearchRepositoryConstants.METADATA_LICENSE); @@ -174,6 +175,7 @@ public class GitFilesRepositoryImpl implements GitFilesRepository { } queryBuilder.should(QueryBuilders.termsQuery(field, value)); } + private static void addMetadataQueryMust(BoolQueryBuilder queryBuilder, String value, String field) { if (value == null) { return; diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/LikesSearchRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/LikesSearchRepository.java index 2c2dc39abb2b8d6a8bf368fd3472a9824aad3881..4d9fae30e5e717684901ca6abb1ecadc039322bc 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/LikesSearchRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/LikesSearchRepository.java @@ -3,9 +3,7 @@ package at.ac.uibk.gitsearch.repository.search; import at.ac.uibk.gitsearch.domain.Likes; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; - /** * Spring Data Elasticsearch repository for the {@link Likes} entity. */ -public interface LikesSearchRepository extends ElasticsearchRepository<Likes, Long> { -} +public interface LikesSearchRepository extends ElasticsearchRepository<Likes, Long> {} diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/MetaDataRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/MetaDataRepository.java index 14f1abd5d9a0e951183fbbcebc541296b94a2109..479e9f2d1888a6cb13bec1c72a45a47258d5d3c4 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/MetaDataRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/MetaDataRepository.java @@ -1,5 +1,12 @@ package at.ac.uibk.gitsearch.repository.search; +import at.ac.uibk.gitsearch.domain.Authority; +import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import java.io.IOException; import java.time.Instant; import java.util.ArrayList; @@ -17,10 +24,8 @@ import java.util.TreeMap; import java.util.function.Consumer; import java.util.stream.Collectors; import java.util.stream.Stream; - import javax.annotation.PostConstruct; import javax.ws.rs.NotFoundException; - import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -50,647 +55,663 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Repository; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; - -import at.ac.uibk.gitsearch.domain.Authority; -import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; - @Repository public class MetaDataRepository { - private final RestHighLevelClient elasticsearchClient; + private final RestHighLevelClient elasticsearchClient; - private static final Logger LOGGER = LogManager.getLogger(MetaDataRepository.class); + private static final Logger LOGGER = LogManager.getLogger(MetaDataRepository.class); - private static final int FRAGMENT_SIZE = 5000; + private static final int FRAGMENT_SIZE = 5000; - private static final long AUTOCOMPLETION_RECHECK_TIMEOUT = 5 * 60 * 1000L; // every 5 Minutes - private Timer autocompletionReloadTimer = new Timer("AutocompletionReloadTimer"); + private static final long AUTOCOMPLETION_RECHECK_TIMEOUT = 5 * 60 * 1000L; // every 5 Minutes + private Timer autocompletionReloadTimer = new Timer("AutocompletionReloadTimer"); - public static final String EXERCISE_BY_ID_CACHE = "at.ac.uibk.gitsearch.repository.search.MetaDataRepository.ExerciseByIdCache"; + public static final String EXERCISE_BY_ID_CACHE = "at.ac.uibk.gitsearch.repository.search.MetaDataRepository.ExerciseByIdCache"; @Value("${application.search.highlight-pre}") - private String preTags; + private String preTags; + @Value("${application.search.highlight-post}") - private String postTags; - - public MetaDataRepository(RestHighLevelClient elasticsearchClient) { - this.elasticsearchClient = elasticsearchClient; - } - - /** - * contains for each Field, a list of Strings mapped to a completion. Together - * with hit counts E.g. "metadata.creator" -> Kerstin -> {"Kerstin Limbeck" -> - * 3, "Kerstin Mair" -> 2)} - */ - private Map<String, Map<String, Map<String, Integer>>> cachedCompletions = null; - - /** - * returns all keyword autocompletes for keyWord - * - * @param keyWordPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getKeywordsAutoComplete(String keyWordPrefix, int max) throws IOException { - return getFieldAutoCompletion(keyWordPrefix, SearchRepositoryConstants.METADATA_KEYWORDS, max); - } - - /** - * returns all keyword autocompletes for keyWord - * - * @param formatPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getFormatsAutoComplete(String formatPrefix, int max) throws IOException { - return getFieldAutoCompletion(formatPrefix, SearchRepositoryConstants.METADATA_FORMATS, max); - } - - /** - * returns all programmingLanguage autocompletes for keyWord - * - * @param programmingLanguagePrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getProgrammingLanguageAutoComplete(String programmingLanguagePrefix, int max) - throws IOException { - return getFieldAutoCompletion(programmingLanguagePrefix, - SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES, max); - } - - /** - * returns all creator autocompletes - * - * @param creatorPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getCreatorAutoComplete(String creatorPrefix, int max) throws IOException { - return getFieldAutoCompletion(creatorPrefix, SearchRepositoryConstants.METADATA_CREATOR, max); - } - - /** - * returns all contributor autocompletes - * - * @param contributorPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getContributorAutoComplete(String contributorPrefix, int max) throws IOException { - return getFieldAutoCompletion(contributorPrefix, SearchRepositoryConstants.METADATA_CONTRIBUTOR, max); - } - - /** - * returns all contributor and creator autocompletes - * - * @param contributorPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getContributorCreatorAutoComplete(String contributorPrefix, int max) throws IOException { - final List<AutoCompleteEntry> contributors = getContributorAutoComplete(contributorPrefix, max); - final List<AutoCompleteEntry> creatorAutoComplete = getCreatorAutoComplete(contributorPrefix, max); - // merging - for (AutoCompleteEntry creator : creatorAutoComplete) { - contributors.stream().filter(entry -> entry.getTarget().equals(creator.getTarget())).findAny() - .ifPresentOrElse(entry -> { - contributors.remove(entry); - contributors.add(new AutoCompleteEntry(creator.getTarget(), - creator.getHitCount() + entry.getHitCount())); - }, () -> contributors.add(creator)); - } - return contributors; - } - - /** - * returns a list of hits together with the number of occurences - * - * @param prefix the prefix - * @param metaDataField the meta data field - * @param maxCount the maximum of hits, returned - * @return - * @throws IOException - * @throws JsonProcessingException - * @throws JsonMappingException - */ - private List<AutoCompleteEntry> getFieldAutoCompletion(String prefix, final String metaDataField, int maxCount) - throws IOException { - fillAutoCompletion(); - - String lcKeyWordPrefix = prefix.toLowerCase(); - // höllisch kompliziert und höllisch unverständlich mit Streams :-) - // idea - // 1. Filtern nach Prefix - // 2. Zusammenzählen der möglichen Hits (Besser Max statt Sum?) - // 3. Auf MAX_AUTO_COMPLETION_RESULTS begrenzen und nur die Trefferstrings - // ausgeben. - final Stream<Entry<String, Map<String, Integer>>> filteredEntries = cachedCompletions.get(metaDataField) - .entrySet().stream() // Map<String, Map<String, Integer>> -> Stream<Entry<String, Map<String, - // Integer>> - .filter(s -> s.getKey().startsWith(lcKeyWordPrefix)); - final Map<String, Integer> combinedHits = filteredEntries // s = String -> bool -> Stream<Entry<String, - // Map<String, Integer>> - .flatMap(e -> e.getValue().entrySet().stream()) // Stream< Map<String, Integer>> with duplicates - .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::max)); - return combinedHits.entrySet().stream().sorted((e1, e2) -> e2.getValue() - e1.getValue()) - .limit(maxCount).map(s -> new AutoCompleteEntry(s.getKey(), s.getValue())) - .collect(Collectors.toList()); // Map.Entry<String, - // Map<String, - // Integer>> - - } - - @PostConstruct - private void setUpAutocompletion() { - - autocompletionReloadTimer.schedule(new TimerTask() { - - @Override - public void run() { - try { - updateAutocompletionCache(); - } catch (IOException e) { - LOGGER.warn("Cannot refresh Autocompletion Cache", e); - } - } - }, 0L, AUTOCOMPLETION_RECHECK_TIMEOUT); - } - - /** - * stops the cache reload timer, during shutdown or between tests. - * - * @param event ContextStoppedEvent - */ - @EventListener - protected void stopReloadTimer(ContextStoppedEvent event) { - autocompletionReloadTimer.cancel(); - } - - private synchronized void fillAutoCompletion() throws IOException { - if (cachedCompletions == null) { - updateAutocompletionCache(); - } - } - - private void updateAutocompletionCache() throws IOException { - Map<String, Map<String, Map<String, Integer>>> reloadedCachedCompletions = new HashMap<>(); - reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_KEYWORDS, new TreeMap<>()); - reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_CREATOR, new TreeMap<>()); - reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_CONTRIBUTOR, new TreeMap<>()); - reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES, new TreeMap<>()); - reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_FORMATS, new TreeMap<>()); - - SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); - - final int pageSize = 20; - int currentPage = 0; - boolean tryNextPage = true; - - while (tryNextPage) { - - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().size(pageSize).from(currentPage++ * pageSize); - - searchRequest.source(sourceBuilder); - - SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); - - ObjectMapper objectMapper = getSearchResultObjectMapper(); - - tryNextPage = searchResponse.getHits().getHits().length > 0; - - for (SearchHit searchHit : searchResponse.getHits().getHits()) { - final String sourceAsJSON = searchHit.getSourceAsString(); - SearchResultDTO entry = objectMapper.readValue(sourceAsJSON, SearchResultDTO.class); - if (entry.getMetadata().getKeyword() != null) - for (String keyWord : entry.getMetadata().getKeyword()) - addTo(reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_KEYWORDS), - split(keyWord), keyWord); - if (entry.getMetadata().getFormat() != null) - for (String format : entry.getMetadata().getFormat()) - addTo(reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_FORMATS), - split(format), format); - if (entry.getMetadata().getContributor() != null) - for (Person contributor : entry.getMetadata().getContributor()) - addTo(reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_CONTRIBUTOR), - split(contributor.getName()), contributor.getName()); - if (entry.getMetadata().getCreator() != null) - for (Person creator : entry.getMetadata().getCreator()) - addTo(reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_CREATOR), - split(creator.getName()), creator.getName()); - if (entry.getMetadata().getProgrammingLanguage() != null) - for (String language : entry.getMetadata().getProgrammingLanguage()) - addTo(reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES), - Collections.singletonList(language), language); - } - } - cachedCompletions = reloadedCachedCompletions; - } - - /** - * returns a preconfigured object mapper - * @return - */ - public static ObjectMapper getSearchResultObjectMapper() { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - return objectMapper; - } - - private static void addTo(Map<String, Map<String, Integer>> completionMap, List<String> tokenList, String target) { - tokenList.forEach(token -> { - String lowercaseToken = token.toLowerCase(); - Map<String, Integer> existingTargets = completionMap.get(lowercaseToken); - if (existingTargets == null) { // none found - existingTargets = new HashMap<>(); - existingTargets.put(target, 1); - completionMap.put(lowercaseToken, existingTargets); - } else { - final Integer count = existingTargets.get(target); - if (count == null) { - existingTargets.put(target, 1); - } else { - existingTargets.put(target, count + 1); - } - - } - }); - } - - private static List<String> split(String s) { - StringTokenizer st = new StringTokenizer(s, " \t\n\r\f"); - List<String> result = new ArrayList<>(); - while (st.hasMoreTokens()) { - result.add(st.nextToken()); - } - return result; - } - - - - - public SearchResultsDTO searchByEmail(String email, int pageSize, Optional<User> user) throws IOException { - - SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); - - BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); - - BoolQueryBuilder authorBuilder = QueryBuilders.boolQuery(); - if (email != null) - authorBuilder.should(QueryBuilders - .multiMatchQuery(email, - SearchRepositoryConstants.METADATA_CREATOR_EMAIL, SearchRepositoryConstants.METADATA_CONTRIBUTOR_EMAIL, - SearchRepositoryConstants.METADATA_PUBLISHER_EMAIL) - .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX)); - if(authorBuilder.hasClauses()) - queryBuilder.must(authorBuilder); - - - // Authorization restrictions - final BoolQueryBuilder publicQuery = createPublicQuery(); - - if(user.isEmpty()) { - queryBuilder - .must(publicQuery); - } else { - - final Collection<GrantedAuthority> authorities = user.get().getAuthorities(); - final BoolQueryBuilder authQuery = QueryBuilders.boolQuery().boost(0.0f); - final Stream<QueryBuilder> prefixAuthQueries = authorities.stream() - .filter(auth -> !auth.getAuthority().startsWith("ROLE")) - .filter(auth -> !auth.getAuthority().startsWith("SCOPE")) - .map(auth -> QueryBuilders.prefixQuery(SearchRepositoryConstants.PROJECT_NAMESPACE, auth.getAuthority())); - prefixAuthQueries.forEach(authQuery::should); - if(authQuery.hasClauses()) - queryBuilder.must(QueryBuilders.boolQuery().should(authQuery).should(publicQuery)); - else - queryBuilder.must(publicQuery); - } - - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - sourceBuilder.query(queryBuilder).size(pageSize) - .from(0); - - searchRequest.source(sourceBuilder); - - SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); - - return parseSearchResponse(searchResponse); - } - - /** - * returns the hits from the meta data search index for the input query - * parameters. - * - * @param searchInputDTO the query parameters. - * @param pageSize the size of the page (i.e. the maximum of returned - * hits). - * @param user the user that queries. - * @return the search hits. - * @throws IOException when search index is not available. - */ - public SearchResultsDTO pageDetails(org.codeability.sharing.plugins.api.search.SearchInputDTO searchInputDTO, Optional<User> user) - throws IOException { - fillAutoCompletion(); - - SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); - - BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); - - BoolQueryBuilder fullTextBuilder = QueryBuilders.boolQuery(); - forEachTerm(searchInputDTO.getFulltextQuery(), - term -> fullTextBuilder.should(QueryBuilders - .multiMatchQuery(term, SearchRepositoryConstants.METADATA_DESCRIPTION, - SearchRepositoryConstants.METADATA_KEYWORDS, SearchRepositoryConstants.METADATA_TITLE) - .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX))); - if (fullTextBuilder.hasClauses()) - queryBuilder.must(fullTextBuilder); - - BoolQueryBuilder plBuilder = QueryBuilders.boolQuery(); - forEachTerm(searchInputDTO.getMetadata().getProgrammingLanguage(), term -> plBuilder - .should(QueryBuilders.prefixQuery(SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES, term))); - if (plBuilder.hasClauses()) - queryBuilder.must(plBuilder); - - BoolQueryBuilder keywordBuilder = QueryBuilders.boolQuery(); - forEachTerm(searchInputDTO.getMetadata().getKeyword(), term -> keywordBuilder - .should(QueryBuilders.prefixQuery(SearchRepositoryConstants.METADATA_KEYWORDS, term))); - if (keywordBuilder.hasClauses()) - queryBuilder.must(keywordBuilder); - - BoolQueryBuilder formatBuilder = QueryBuilders.boolQuery(); - forEachTerm(searchInputDTO.getMetadata().getFormat(), term -> formatBuilder - .should(QueryBuilders.prefixQuery(SearchRepositoryConstants.METADATA_FORMATS, term))); - if (formatBuilder.hasClauses()) - queryBuilder.must(formatBuilder); - - if(!StringUtils.isEmpty(searchInputDTO.getMetadata().getParentId())) { - queryBuilder.must(QueryBuilders.termQuery(SearchRepositoryConstants.FILE_PARENTID, searchInputDTO.getMetadata().getParentId())); - } - - BoolQueryBuilder authorBuilder = QueryBuilders.boolQuery(); - if (searchInputDTO.getMetadata().getAuthor() != null) - authorBuilder.should(QueryBuilders - .multiMatchQuery(searchInputDTO.getMetadata().getAuthor(), - SearchRepositoryConstants.METADATA_CREATOR, SearchRepositoryConstants.METADATA_CONTRIBUTOR, - SearchRepositoryConstants.METADATA_PUBLISHER) - .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX)); - if (authorBuilder.hasClauses()) - queryBuilder.must(authorBuilder); - - if (searchInputDTO.getMetadata().getNaturalLanguage() != null - && !searchInputDTO.getMetadata().getNaturalLanguage().isEmpty()) { - BoolQueryBuilder nlBuilder = QueryBuilders.boolQuery(); - searchInputDTO.getMetadata().getNaturalLanguage().forEach(language -> nlBuilder - .should(QueryBuilders.matchQuery(SearchRepositoryConstants.METADATA_LANGUAGE, language))); - if (nlBuilder.hasClauses()) - queryBuilder.must(nlBuilder); - } - - forEachTerm(searchInputDTO.getMetadata().getLicense(), - term -> queryBuilder.must(QueryBuilders.prefixQuery(SearchRepositoryConstants.METADATA_LICENSE, term))); - - addAuthorizationQuery(user, queryBuilder); - - char[] boundaryChars = { '\n' }; - - HighlightBuilder highlightBuilder = new HighlightBuilder().highlighterType("plain") - .preTags(preTags).postTags(postTags) - .field(SearchRepositoryConstants.METADATA_DESCRIPTION).boundaryChars(boundaryChars) - .boundaryScannerType(HighlightBuilder.BoundaryScannerType.SENTENCE).fragmentSize(FRAGMENT_SIZE); - - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - sourceBuilder.query(queryBuilder).highlighter(highlightBuilder).size(searchInputDTO.getPageSize()) - .from((searchInputDTO.getPage()) * searchInputDTO.getPageSize()); - - searchRequest.source(sourceBuilder); - SearchResponse searchResponse; - try { - searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); - } catch (ElasticsearchException ese) { - LOGGER.warn("Exception in elastic search", ese); - throw ese; - } - - return parseSearchResponse(searchResponse); - } - - /** - * this adds extra authorization requirements. - * It currently supports directly the group membership in the hierarchy - * and the new access management by shared groups and explicit members. - * @param user - * @param queryBuilder - */ - private void addAuthorizationQuery(Optional<User> user, BoolQueryBuilder queryBuilder) { - // Authorization restrictions - final BoolQueryBuilder publicQuery = createPublicQuery(); - - - if (user.isEmpty()) { - queryBuilder.must(publicQuery); - } else { - - final Collection<GrantedAuthority> authorities = user.get().getAuthorities(); - final BoolQueryBuilder authQuery = QueryBuilders.boolQuery().boost(0.0f); - // old membership management (can be eliminated some day) - final Stream<QueryBuilder> prefixAuthQueries = authorities.stream() - .filter(auth -> !Authority.isStandardRole(auth.getAuthority())) - .filter(auth -> !auth.getAuthority().startsWith("SCOPE")).map( - auth -> QueryBuilders - .termQuery(SearchRepositoryConstants.PROJECT_NAMESPACE, auth.getAuthority())); - prefixAuthQueries.forEach(pq -> authQuery.should(pq)); - - // new membership management - final Stream<QueryBuilder> prefixAuthQueries2 = authorities.stream() - .filter(auth -> !Authority.isStandardRole(auth.getAuthority())) - .filter(auth -> !auth.getAuthority().startsWith("SCOPE")).map( - auth -> QueryBuilders - .termQuery(SearchRepositoryConstants.PROJECT_GROUPS, auth.getAuthority())); - prefixAuthQueries2.forEach(authQuery::should); - final String email = user.get().getUsername().toLowerCase(); - if(StringUtils.isNotEmpty(email)) { - authQuery.should(QueryBuilders - .termQuery(SearchRepositoryConstants.PROJECT_USERS, email)); - } - if (authQuery.hasClauses()) - queryBuilder.must(QueryBuilders.boolQuery().should(authQuery).should(publicQuery)); - else - queryBuilder.must(publicQuery); - } - } - - private BoolQueryBuilder createPublicQuery() { - final TermQueryBuilder simplePublicQuery = QueryBuilders - .termQuery(SearchRepositoryConstants.PROJECT_VISIBILITY, "public") - .boost(0.0f); - final ExistsQueryBuilder publicVisibilityQuery = QueryBuilders.existsQuery(SearchRepositoryConstants.METADATA_PUBLICVISIBILITY); - - final BoolQueryBuilder publicQuery = QueryBuilders.boolQuery().should(simplePublicQuery).should(publicVisibilityQuery); - return publicQuery; - } - - private static SearchResultsDTO parseSearchResponse(final SearchResponse searchResponse) - throws JsonProcessingException { - - float maxScore = searchResponse.getHits().getMaxScore(); - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - final List<SearchResultDTO> searchResults = new ArrayList<>(); - for (SearchHit searchHit : searchResponse.getHits().getHits()) { - float hitScore = searchHit.getScore(); - final SearchResultDTO parsedSearchHit = parseSearchHit(searchHit, objectMapper); - int ranking5 = 1; - if (maxScore > 0.0f) - ranking5 = (int) ((hitScore * 5.0) / maxScore + 0.5f); - parsedSearchHit.setRanking5(ranking5); - searchResults.add(parsedSearchHit); - } - - long hitCount = searchResponse.getHits().getTotalHits().value; - final SearchResultsDTO results = new SearchResultsDTO(); - results.setHitCount(hitCount); - results.setSearchResult(searchResults); - return results; - } - - private static SearchResultDTO parseSearchHit(SearchHit searchHit, ObjectMapper objectMapper) - throws JsonProcessingException { - final SearchResultDTO mappedValue = objectMapper.readValue(searchHit.getSourceAsString(), - SearchResultDTO.class); - mappedValue.setExerciseId(searchHit.getId()); - return mappedValue; - } - - /** Helper **/ - private static void forEachTerm(String searchTerm, Consumer<String> exec) { - if (searchTerm == null) - return; - StringTokenizer st = new StringTokenizer(searchTerm); - while (st.hasMoreTokens()) { - exec.accept(st.nextToken()); - } - } - - public SearchResultsDTO getExercisesById(Stream<String> exerciseIds, Optional<User> user, int page, int pageSize) { - return getExercisesById(exerciseIds, user, page, pageSize, null); - } - - - /** - * returns all exercises, referred by their ids, changed after since (if not null) - * @param exerciseIds a stream of exercise ids - * @param user the user: needed for authorization - * @param page the page - * @param pageSize the page size - * @param since an instant since when the exercise was last changed (or null, if not relevant) - * @return - */ - public SearchResultsDTO getExercisesById(Stream<String> exerciseIds, Optional<User> user, int page, int pageSize, Instant since) { - SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); - - BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); - - BoolQueryBuilder idQueryBuilder = QueryBuilders.boolQuery(); - exerciseIds.forEach(exerciseId -> idQueryBuilder - .should(QueryBuilders.matchQuery(SearchRepositoryConstants.EXERCISE_ID, exerciseId))); - // Böse Falle: Wenn exerciseIds empty, dann wird alles zurückgegeben! - if (!idQueryBuilder.hasClauses()) { - final SearchResultsDTO results = new SearchResultsDTO(); - results.setHitCount(0L); - results.setSearchResult(new ArrayList<>()); - return results; - - } - queryBuilder.must(idQueryBuilder); - if(since != null) { - queryBuilder.must(QueryBuilders.rangeQuery(SearchRepositoryConstants.PROJECT_LASTACTIVITYAT).gte(since) /*.lte(Instant.now()) */); - } - - addAuthorizationQuery(user, queryBuilder); - - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - sourceBuilder.query(queryBuilder).size(pageSize).from(page * pageSize); - - searchRequest.source(sourceBuilder); - - try { - SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); - - return parseSearchResponse(searchResponse); - - } catch (JsonProcessingException e) { - throw new NotFoundException(" Exercise with ids " + idQueryBuilder.toString() + " not found?", e); - } catch (IOException e) { - throw new NotFoundException("Query for exercise with id " + idQueryBuilder.toString() + " went wrong?", e); - } - } - - /** - * Searches for an exercise by id - * just a convenience method - * @param exerciseId the parsed exercise id - * @param user the user (if authenticated) - * @return search result - * @throws NotFoundException if not found - */ - @Cacheable(value = EXERCISE_BY_ID_CACHE, key="((#user.present)?#user.get().username:'') + #exerciseId.toString()") - public SearchResultDTO getExerciseById(ExerciseId exerciseId, Optional<User> user) throws NotFoundException { - return getExerciseById(exerciseId.toString(), user); - } - - - /** - * Searches for an exercise by id - * @param exerciseId exercise id as String - * @param user the user (if authenticated) - * @return search result - * @throws NotFoundException if not found - */ - @Cacheable(value = EXERCISE_BY_ID_CACHE, key="((#user.present)?#user.get().username:'') + #exerciseId.toString()") - public SearchResultDTO getExerciseById(String exerciseId, Optional<User> user) throws NotFoundException { - - SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); - - BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); - - queryBuilder.must(QueryBuilders.matchQuery(SearchRepositoryConstants.EXERCISE_ID, exerciseId)); - - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - sourceBuilder.query(queryBuilder).size(10); - addAuthorizationQuery(user, queryBuilder); - - searchRequest.source(sourceBuilder); - - try { - SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); - - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - if (searchResponse.getHits().getTotalHits().value > 1) { - LOGGER.warn("Found {} hits for exercise id {}, expected only one!", searchResponse.getHits().getTotalHits().value, - exerciseId); - } - if (searchResponse.getHits().getHits().length > 0) { - final SearchResultDTO parseSearchHit = parseSearchHit(searchResponse.getHits().getHits()[0], objectMapper); - parseSearchHit.setRanking5(5); - return parseSearchHit; - } - } catch (JsonProcessingException e) { - throw new NotFoundException(" Exercise with id " + exerciseId + " not found?", e); - } catch (IOException e) { - throw new NotFoundException("Query for exercise with id " + exerciseId + " went wrong?", e); - } - throw new NotFoundException(" Exercise with id " + exerciseId + " not found?"); - } + private String postTags; + + public MetaDataRepository(RestHighLevelClient elasticsearchClient) { + this.elasticsearchClient = elasticsearchClient; + } + + /** + * contains for each Field, a list of Strings mapped to a completion. Together + * with hit counts E.g. "metadata.creator" -> Kerstin -> {"Kerstin Limbeck" -> + * 3, "Kerstin Mair" -> 2)} + */ + private Map<String, Map<String, Map<String, Integer>>> cachedCompletions = null; + + /** + * returns all keyword autocompletes for keyWord + * + * @param keyWordPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getKeywordsAutoComplete(String keyWordPrefix, int max) throws IOException { + return getFieldAutoCompletion(keyWordPrefix, SearchRepositoryConstants.METADATA_KEYWORDS, max); + } + + /** + * returns all keyword autocompletes for keyWord + * + * @param formatPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getFormatsAutoComplete(String formatPrefix, int max) throws IOException { + return getFieldAutoCompletion(formatPrefix, SearchRepositoryConstants.METADATA_FORMATS, max); + } + + /** + * returns all programmingLanguage autocompletes for keyWord + * + * @param programmingLanguagePrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getProgrammingLanguageAutoComplete(String programmingLanguagePrefix, int max) throws IOException { + return getFieldAutoCompletion(programmingLanguagePrefix, SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES, max); + } + + /** + * returns all creator autocompletes + * + * @param creatorPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getCreatorAutoComplete(String creatorPrefix, int max) throws IOException { + return getFieldAutoCompletion(creatorPrefix, SearchRepositoryConstants.METADATA_CREATOR, max); + } + + /** + * returns all contributor autocompletes + * + * @param contributorPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getContributorAutoComplete(String contributorPrefix, int max) throws IOException { + return getFieldAutoCompletion(contributorPrefix, SearchRepositoryConstants.METADATA_CONTRIBUTOR, max); + } + + /** + * returns all contributor and creator autocompletes + * + * @param contributorPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getContributorCreatorAutoComplete(String contributorPrefix, int max) throws IOException { + final List<AutoCompleteEntry> contributors = getContributorAutoComplete(contributorPrefix, max); + final List<AutoCompleteEntry> creatorAutoComplete = getCreatorAutoComplete(contributorPrefix, max); + // merging + for (AutoCompleteEntry creator : creatorAutoComplete) { + contributors + .stream() + .filter(entry -> entry.getTarget().equals(creator.getTarget())) + .findAny() + .ifPresentOrElse( + entry -> { + contributors.remove(entry); + contributors.add(new AutoCompleteEntry(creator.getTarget(), creator.getHitCount() + entry.getHitCount())); + }, + () -> contributors.add(creator) + ); + } + return contributors; + } + + /** + * returns a list of hits together with the number of occurences + * + * @param prefix the prefix + * @param metaDataField the meta data field + * @param maxCount the maximum of hits, returned + * @return + * @throws IOException + * @throws JsonProcessingException + * @throws JsonMappingException + */ + private List<AutoCompleteEntry> getFieldAutoCompletion(String prefix, final String metaDataField, int maxCount) throws IOException { + fillAutoCompletion(); + + String lcKeyWordPrefix = prefix.toLowerCase(); + // höllisch kompliziert und höllisch unverständlich mit Streams :-) + // idea + // 1. Filtern nach Prefix + // 2. Zusammenzählen der möglichen Hits (Besser Max statt Sum?) + // 3. Auf MAX_AUTO_COMPLETION_RESULTS begrenzen und nur die Trefferstrings + // ausgeben. + final Stream<Entry<String, Map<String, Integer>>> filteredEntries = cachedCompletions + .get(metaDataField) + .entrySet() + .stream() // Map<String, Map<String, Integer>> -> Stream<Entry<String, Map<String, + // Integer>> + .filter(s -> s.getKey().startsWith(lcKeyWordPrefix)); + final Map<String, Integer> combinedHits = filteredEntries // s = String -> bool -> Stream<Entry<String, + // Map<String, Integer>> + .flatMap(e -> e.getValue().entrySet().stream()) // Stream< Map<String, Integer>> with duplicates + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::max)); + return combinedHits + .entrySet() + .stream() + .sorted((e1, e2) -> e2.getValue() - e1.getValue()) + .limit(maxCount) + .map(s -> new AutoCompleteEntry(s.getKey(), s.getValue())) + .collect(Collectors.toList()); // Map.Entry<String, + // Map<String, + // Integer>> + + } + + @PostConstruct + private void setUpAutocompletion() { + autocompletionReloadTimer.schedule( + new TimerTask() { + @Override + public void run() { + try { + updateAutocompletionCache(); + } catch (IOException e) { + LOGGER.warn("Cannot refresh Autocompletion Cache", e); + } + } + }, + 0L, + AUTOCOMPLETION_RECHECK_TIMEOUT + ); + } + + /** + * stops the cache reload timer, during shutdown or between tests. + * + * @param event ContextStoppedEvent + */ + @EventListener + protected void stopReloadTimer(ContextStoppedEvent event) { + autocompletionReloadTimer.cancel(); + } + + private synchronized void fillAutoCompletion() throws IOException { + if (cachedCompletions == null) { + updateAutocompletionCache(); + } + } + + private void updateAutocompletionCache() throws IOException { + Map<String, Map<String, Map<String, Integer>>> reloadedCachedCompletions = new HashMap<>(); + reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_KEYWORDS, new TreeMap<>()); + reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_CREATOR, new TreeMap<>()); + reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_CONTRIBUTOR, new TreeMap<>()); + reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES, new TreeMap<>()); + reloadedCachedCompletions.put(SearchRepositoryConstants.METADATA_FORMATS, new TreeMap<>()); + + SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); + + final int pageSize = 20; + int currentPage = 0; + boolean tryNextPage = true; + + while (tryNextPage) { + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder().size(pageSize).from(currentPage++ * pageSize); + + searchRequest.source(sourceBuilder); + + SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); + + ObjectMapper objectMapper = getSearchResultObjectMapper(); + + tryNextPage = searchResponse.getHits().getHits().length > 0; + + for (SearchHit searchHit : searchResponse.getHits().getHits()) { + final String sourceAsJSON = searchHit.getSourceAsString(); + SearchResultDTO entry = objectMapper.readValue(sourceAsJSON, SearchResultDTO.class); + if (entry.getMetadata().getKeyword() != null) for (String keyWord : entry.getMetadata().getKeyword()) addTo( + reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_KEYWORDS), + split(keyWord), + keyWord + ); + if (entry.getMetadata().getFormat() != null) for (String format : entry.getMetadata().getFormat()) addTo( + reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_FORMATS), + split(format), + format + ); + if (entry.getMetadata().getContributor() != null) for (Person contributor : entry.getMetadata().getContributor()) addTo( + reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_CONTRIBUTOR), + split(contributor.getName()), + contributor.getName() + ); + if (entry.getMetadata().getCreator() != null) for (Person creator : entry.getMetadata().getCreator()) addTo( + reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_CREATOR), + split(creator.getName()), + creator.getName() + ); + if (entry.getMetadata().getProgrammingLanguage() != null) for (String language : entry + .getMetadata() + .getProgrammingLanguage()) addTo( + reloadedCachedCompletions.get(SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES), + Collections.singletonList(language), + language + ); + } + } + cachedCompletions = reloadedCachedCompletions; + } + + /** + * returns a preconfigured object mapper + * @return + */ + public static ObjectMapper getSearchResultObjectMapper() { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + return objectMapper; + } + + private static void addTo(Map<String, Map<String, Integer>> completionMap, List<String> tokenList, String target) { + tokenList.forEach(token -> { + String lowercaseToken = token.toLowerCase(); + Map<String, Integer> existingTargets = completionMap.get(lowercaseToken); + if (existingTargets == null) { // none found + existingTargets = new HashMap<>(); + existingTargets.put(target, 1); + completionMap.put(lowercaseToken, existingTargets); + } else { + final Integer count = existingTargets.get(target); + if (count == null) { + existingTargets.put(target, 1); + } else { + existingTargets.put(target, count + 1); + } + } + }); + } + + private static List<String> split(String s) { + StringTokenizer st = new StringTokenizer(s, " \t\n\r\f"); + List<String> result = new ArrayList<>(); + while (st.hasMoreTokens()) { + result.add(st.nextToken()); + } + return result; + } + + public SearchResultsDTO searchByEmail(String email, int pageSize, Optional<User> user) throws IOException { + SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); + + BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); + + BoolQueryBuilder authorBuilder = QueryBuilders.boolQuery(); + if (email != null) authorBuilder.should( + QueryBuilders + .multiMatchQuery( + email, + SearchRepositoryConstants.METADATA_CREATOR_EMAIL, + SearchRepositoryConstants.METADATA_CONTRIBUTOR_EMAIL, + SearchRepositoryConstants.METADATA_PUBLISHER_EMAIL + ) + .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX) + ); + if (authorBuilder.hasClauses()) queryBuilder.must(authorBuilder); + + // Authorization restrictions + final BoolQueryBuilder publicQuery = createPublicQuery(); + + if (user.isEmpty()) { + queryBuilder.must(publicQuery); + } else { + final Collection<GrantedAuthority> authorities = user.get().getAuthorities(); + final BoolQueryBuilder authQuery = QueryBuilders.boolQuery().boost(0.0f); + final Stream<QueryBuilder> prefixAuthQueries = authorities + .stream() + .filter(auth -> !auth.getAuthority().startsWith("ROLE")) + .filter(auth -> !auth.getAuthority().startsWith("SCOPE")) + .map(auth -> QueryBuilders.prefixQuery(SearchRepositoryConstants.PROJECT_NAMESPACE, auth.getAuthority())); + prefixAuthQueries.forEach(authQuery::should); + if (authQuery.hasClauses()) queryBuilder.must( + QueryBuilders.boolQuery().should(authQuery).should(publicQuery) + ); else queryBuilder.must(publicQuery); + } + + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.query(queryBuilder).size(pageSize).from(0); + + searchRequest.source(sourceBuilder); + + SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); + + return parseSearchResponse(searchResponse); + } + + /** + * returns the hits from the meta data search index for the input query + * parameters. + * + * @param searchInputDTO the query parameters. + * @param pageSize the size of the page (i.e. the maximum of returned + * hits). + * @param user the user that queries. + * @return the search hits. + * @throws IOException when search index is not available. + */ + public SearchResultsDTO pageDetails(org.codeability.sharing.plugins.api.search.SearchInputDTO searchInputDTO, Optional<User> user) + throws IOException { + fillAutoCompletion(); + + SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); + + BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); + + BoolQueryBuilder fullTextBuilder = QueryBuilders.boolQuery(); + forEachTerm( + searchInputDTO.getFulltextQuery(), + term -> + fullTextBuilder.should( + QueryBuilders + .multiMatchQuery( + term, + SearchRepositoryConstants.METADATA_DESCRIPTION, + SearchRepositoryConstants.METADATA_KEYWORDS, + SearchRepositoryConstants.METADATA_TITLE + ) + .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX) + ) + ); + if (fullTextBuilder.hasClauses()) queryBuilder.must(fullTextBuilder); + + BoolQueryBuilder plBuilder = QueryBuilders.boolQuery(); + forEachTerm( + searchInputDTO.getMetadata().getProgrammingLanguage(), + term -> plBuilder.should(QueryBuilders.prefixQuery(SearchRepositoryConstants.METADATA_PROGRAMMING_LANGUAGES, term)) + ); + if (plBuilder.hasClauses()) queryBuilder.must(plBuilder); + + BoolQueryBuilder keywordBuilder = QueryBuilders.boolQuery(); + forEachTerm( + searchInputDTO.getMetadata().getKeyword(), + term -> keywordBuilder.should(QueryBuilders.prefixQuery(SearchRepositoryConstants.METADATA_KEYWORDS, term)) + ); + if (keywordBuilder.hasClauses()) queryBuilder.must(keywordBuilder); + + BoolQueryBuilder formatBuilder = QueryBuilders.boolQuery(); + forEachTerm( + searchInputDTO.getMetadata().getFormat(), + term -> formatBuilder.should(QueryBuilders.prefixQuery(SearchRepositoryConstants.METADATA_FORMATS, term)) + ); + if (formatBuilder.hasClauses()) queryBuilder.must(formatBuilder); + + if (!StringUtils.isEmpty(searchInputDTO.getMetadata().getParentId())) { + queryBuilder.must(QueryBuilders.termQuery(SearchRepositoryConstants.FILE_PARENTID, searchInputDTO.getMetadata().getParentId())); + } + + BoolQueryBuilder authorBuilder = QueryBuilders.boolQuery(); + if (searchInputDTO.getMetadata().getAuthor() != null) authorBuilder.should( + QueryBuilders + .multiMatchQuery( + searchInputDTO.getMetadata().getAuthor(), + SearchRepositoryConstants.METADATA_CREATOR, + SearchRepositoryConstants.METADATA_CONTRIBUTOR, + SearchRepositoryConstants.METADATA_PUBLISHER + ) + .type(MultiMatchQueryBuilder.Type.PHRASE_PREFIX) + ); + if (authorBuilder.hasClauses()) queryBuilder.must(authorBuilder); + + if (searchInputDTO.getMetadata().getNaturalLanguage() != null && !searchInputDTO.getMetadata().getNaturalLanguage().isEmpty()) { + BoolQueryBuilder nlBuilder = QueryBuilders.boolQuery(); + searchInputDTO + .getMetadata() + .getNaturalLanguage() + .forEach(language -> nlBuilder.should(QueryBuilders.matchQuery(SearchRepositoryConstants.METADATA_LANGUAGE, language))); + if (nlBuilder.hasClauses()) queryBuilder.must(nlBuilder); + } + + forEachTerm( + searchInputDTO.getMetadata().getLicense(), + term -> queryBuilder.must(QueryBuilders.prefixQuery(SearchRepositoryConstants.METADATA_LICENSE, term)) + ); + + addAuthorizationQuery(user, queryBuilder); + + char[] boundaryChars = { '\n' }; + + HighlightBuilder highlightBuilder = new HighlightBuilder() + .highlighterType("plain") + .preTags(preTags) + .postTags(postTags) + .field(SearchRepositoryConstants.METADATA_DESCRIPTION) + .boundaryChars(boundaryChars) + .boundaryScannerType(HighlightBuilder.BoundaryScannerType.SENTENCE) + .fragmentSize(FRAGMENT_SIZE); + + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder + .query(queryBuilder) + .highlighter(highlightBuilder) + .size(searchInputDTO.getPageSize()) + .from((searchInputDTO.getPage()) * searchInputDTO.getPageSize()); + + searchRequest.source(sourceBuilder); + SearchResponse searchResponse; + try { + searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); + } catch (ElasticsearchException ese) { + LOGGER.warn("Exception in elastic search", ese); + throw ese; + } + + return parseSearchResponse(searchResponse); + } + + /** + * this adds extra authorization requirements. + * It currently supports directly the group membership in the hierarchy + * and the new access management by shared groups and explicit members. + * @param user + * @param queryBuilder + */ + private void addAuthorizationQuery(Optional<User> user, BoolQueryBuilder queryBuilder) { + // Authorization restrictions + final BoolQueryBuilder publicQuery = createPublicQuery(); + + if (user.isEmpty()) { + queryBuilder.must(publicQuery); + } else { + final Collection<GrantedAuthority> authorities = user.get().getAuthorities(); + final BoolQueryBuilder authQuery = QueryBuilders.boolQuery().boost(0.0f); + // old membership management (can be eliminated some day) + final Stream<QueryBuilder> prefixAuthQueries = authorities + .stream() + .filter(auth -> !Authority.isStandardRole(auth.getAuthority())) + .filter(auth -> !auth.getAuthority().startsWith("SCOPE")) + .map(auth -> QueryBuilders.termQuery(SearchRepositoryConstants.PROJECT_NAMESPACE, auth.getAuthority())); + prefixAuthQueries.forEach(pq -> authQuery.should(pq)); + + // new membership management + final Stream<QueryBuilder> prefixAuthQueries2 = authorities + .stream() + .filter(auth -> !Authority.isStandardRole(auth.getAuthority())) + .filter(auth -> !auth.getAuthority().startsWith("SCOPE")) + .map(auth -> QueryBuilders.termQuery(SearchRepositoryConstants.PROJECT_GROUPS, auth.getAuthority())); + prefixAuthQueries2.forEach(authQuery::should); + final String email = user.get().getUsername().toLowerCase(); + if (StringUtils.isNotEmpty(email)) { + authQuery.should(QueryBuilders.termQuery(SearchRepositoryConstants.PROJECT_USERS, email)); + } + if (authQuery.hasClauses()) queryBuilder.must( + QueryBuilders.boolQuery().should(authQuery).should(publicQuery) + ); else queryBuilder.must(publicQuery); + } + } + + private BoolQueryBuilder createPublicQuery() { + final TermQueryBuilder simplePublicQuery = QueryBuilders + .termQuery(SearchRepositoryConstants.PROJECT_VISIBILITY, "public") + .boost(0.0f); + final ExistsQueryBuilder publicVisibilityQuery = QueryBuilders.existsQuery(SearchRepositoryConstants.METADATA_PUBLICVISIBILITY); + + final BoolQueryBuilder publicQuery = QueryBuilders.boolQuery().should(simplePublicQuery).should(publicVisibilityQuery); + return publicQuery; + } + + private static SearchResultsDTO parseSearchResponse(final SearchResponse searchResponse) throws JsonProcessingException { + float maxScore = searchResponse.getHits().getMaxScore(); + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + final List<SearchResultDTO> searchResults = new ArrayList<>(); + for (SearchHit searchHit : searchResponse.getHits().getHits()) { + float hitScore = searchHit.getScore(); + final SearchResultDTO parsedSearchHit = parseSearchHit(searchHit, objectMapper); + int ranking5 = 1; + if (maxScore > 0.0f) ranking5 = (int) ((hitScore * 5.0) / maxScore + 0.5f); + parsedSearchHit.setRanking5(ranking5); + searchResults.add(parsedSearchHit); + } + + long hitCount = searchResponse.getHits().getTotalHits().value; + final SearchResultsDTO results = new SearchResultsDTO(); + results.setHitCount(hitCount); + results.setSearchResult(searchResults); + return results; + } + + private static SearchResultDTO parseSearchHit(SearchHit searchHit, ObjectMapper objectMapper) throws JsonProcessingException { + final SearchResultDTO mappedValue = objectMapper.readValue(searchHit.getSourceAsString(), SearchResultDTO.class); + mappedValue.setExerciseId(searchHit.getId()); + return mappedValue; + } + + /** Helper **/ + private static void forEachTerm(String searchTerm, Consumer<String> exec) { + if (searchTerm == null) return; + StringTokenizer st = new StringTokenizer(searchTerm); + while (st.hasMoreTokens()) { + exec.accept(st.nextToken()); + } + } + + public SearchResultsDTO getExercisesById(Stream<String> exerciseIds, Optional<User> user, int page, int pageSize) { + return getExercisesById(exerciseIds, user, page, pageSize, null); + } + + /** + * returns all exercises, referred by their ids, changed after since (if not null) + * @param exerciseIds a stream of exercise ids + * @param user the user: needed for authorization + * @param page the page + * @param pageSize the page size + * @param since an instant since when the exercise was last changed (or null, if not relevant) + * @return + */ + public SearchResultsDTO getExercisesById(Stream<String> exerciseIds, Optional<User> user, int page, int pageSize, Instant since) { + SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); + + BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); + + BoolQueryBuilder idQueryBuilder = QueryBuilders.boolQuery(); + exerciseIds.forEach(exerciseId -> idQueryBuilder.should(QueryBuilders.matchQuery(SearchRepositoryConstants.EXERCISE_ID, exerciseId)) + ); + // Böse Falle: Wenn exerciseIds empty, dann wird alles zurückgegeben! + if (!idQueryBuilder.hasClauses()) { + final SearchResultsDTO results = new SearchResultsDTO(); + results.setHitCount(0L); + results.setSearchResult(new ArrayList<>()); + return results; + } + queryBuilder.must(idQueryBuilder); + if (since != null) { + queryBuilder.must( + QueryBuilders.rangeQuery(SearchRepositoryConstants.PROJECT_LASTACTIVITYAT).gte(since) + /*.lte(Instant.now()) */ + ); + } + + addAuthorizationQuery(user, queryBuilder); + + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.query(queryBuilder).size(pageSize).from(page * pageSize); + + searchRequest.source(sourceBuilder); + + try { + SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); + + return parseSearchResponse(searchResponse); + } catch (JsonProcessingException e) { + throw new NotFoundException(" Exercise with ids " + idQueryBuilder.toString() + " not found?", e); + } catch (IOException e) { + throw new NotFoundException("Query for exercise with id " + idQueryBuilder.toString() + " went wrong?", e); + } + } + + /** + * Searches for an exercise by id + * just a convenience method + * @param exerciseId the parsed exercise id + * @param user the user (if authenticated) + * @return search result + * @throws NotFoundException if not found + */ + @Cacheable(value = EXERCISE_BY_ID_CACHE, key = "((#user.present)?#user.get().username:'') + #exerciseId.toString()") + public SearchResultDTO getExerciseById(ExerciseId exerciseId, Optional<User> user) throws NotFoundException { + return getExerciseById(exerciseId.toString(), user); + } + + /** + * Searches for an exercise by id + * @param exerciseId exercise id as String + * @param user the user (if authenticated) + * @return search result + * @throws NotFoundException if not found + */ + @Cacheable(value = EXERCISE_BY_ID_CACHE, key = "((#user.present)?#user.get().username:'') + #exerciseId.toString()") + public SearchResultDTO getExerciseById(String exerciseId, Optional<User> user) throws NotFoundException { + SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); + + BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); + + queryBuilder.must(QueryBuilders.matchQuery(SearchRepositoryConstants.EXERCISE_ID, exerciseId)); + + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.query(queryBuilder).size(10); + addAuthorizationQuery(user, queryBuilder); + + searchRequest.source(sourceBuilder); + + try { + SearchResponse searchResponse = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + if (searchResponse.getHits().getTotalHits().value > 1) { + LOGGER.warn( + "Found {} hits for exercise id {}, expected only one!", + searchResponse.getHits().getTotalHits().value, + exerciseId + ); + } + if (searchResponse.getHits().getHits().length > 0) { + final SearchResultDTO parseSearchHit = parseSearchHit(searchResponse.getHits().getHits()[0], objectMapper); + parseSearchHit.setRanking5(5); + return parseSearchHit; + } + } catch (JsonProcessingException e) { + throw new NotFoundException(" Exercise with id " + exerciseId + " not found?", e); + } catch (IOException e) { + throw new NotFoundException("Query for exercise with id " + exerciseId + " went wrong?", e); + } + throw new NotFoundException(" Exercise with id " + exerciseId + " not found?"); + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/SavedSearchesSearchRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/SavedSearchesSearchRepository.java index 6f2a6e3fa8a03368f3f5f3331b86229eac13aaa4..d4448dbda7feb269a9c90aff5cc0be784f4bfa98 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/SavedSearchesSearchRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/SavedSearchesSearchRepository.java @@ -2,9 +2,9 @@ package at.ac.uibk.gitsearch.repository.search; import static org.elasticsearch.index.query.QueryBuilders.queryStringQuery; +import at.ac.uibk.gitsearch.domain.SavedSearches; import java.util.List; import java.util.stream.Collectors; - import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.Pageable; @@ -13,8 +13,6 @@ import org.springframework.data.elasticsearch.core.SearchHit; import org.springframework.data.elasticsearch.core.query.NativeSearchQuery; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; -import at.ac.uibk.gitsearch.domain.SavedSearches; - /** * Spring Data Elasticsearch repository for the {@link SavedSearches} entity. */ diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/SearchRepositoryConstants.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/SearchRepositoryConstants.java index 523f5f2a6c89d2453732379fc9c00a3ac3f42339..e4e1bee2bded4359cd605976782e6798534daeb4 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/SearchRepositoryConstants.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/SearchRepositoryConstants.java @@ -42,6 +42,6 @@ public final class SearchRepositoryConstants { public static final String PROJECT_LASTACTIVITYAT = "project.last_activity_at"; private SearchRepositoryConstants() { - // just a list of constants + // just a list of constants } } diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/StatisticsSearchRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/StatisticsSearchRepository.java index 6f5af0d21edcc5c599a81dad64c53f9a001725e7..c0ad63a0a9f62ff03476d09c1126cba4fbc315fa 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/StatisticsSearchRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/StatisticsSearchRepository.java @@ -3,9 +3,7 @@ package at.ac.uibk.gitsearch.repository.search; import at.ac.uibk.gitsearch.domain.Statistics; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; - /** * Spring Data Elasticsearch repository for the {@link Statistics} entity. */ -public interface StatisticsSearchRepository extends ElasticsearchRepository<Statistics, Long> { -} +public interface StatisticsSearchRepository extends ElasticsearchRepository<Statistics, Long> {} diff --git a/src/main/java/at/ac/uibk/gitsearch/repository/search/WatchListEntrySearchRepository.java b/src/main/java/at/ac/uibk/gitsearch/repository/search/WatchListEntrySearchRepository.java index 3d1f8be303a69a2f619aface7278a67f28fc3940..f162ecbd8de0174408299fb144fcdd49bc5e9f00 100644 --- a/src/main/java/at/ac/uibk/gitsearch/repository/search/WatchListEntrySearchRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/repository/search/WatchListEntrySearchRepository.java @@ -3,9 +3,7 @@ package at.ac.uibk.gitsearch.repository.search; import at.ac.uibk.gitsearch.domain.WatchListEntry; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; - /** * Spring Data Elasticsearch repository for the {@link WatchListEntry} entity. */ -public interface WatchListEntrySearchRepository extends ElasticsearchRepository<WatchListEntry, Long> { -} +public interface WatchListEntrySearchRepository extends ElasticsearchRepository<WatchListEntry, Long> {} diff --git a/src/main/java/at/ac/uibk/gitsearch/security/AuthoritiesConstants.java b/src/main/java/at/ac/uibk/gitsearch/security/AuthoritiesConstants.java index 01793fce50664e8b1661f41d806fef226199f137..414b3b408c2b26dfd89e4fe4e95633a7b21280c8 100644 --- a/src/main/java/at/ac/uibk/gitsearch/security/AuthoritiesConstants.java +++ b/src/main/java/at/ac/uibk/gitsearch/security/AuthoritiesConstants.java @@ -16,33 +16,34 @@ public final class AuthoritiesConstants { /** just a convenience enum to access authorities in all their variants */ public enum AuthoritiesConstantEnum { - ADMIN(AuthoritiesConstants.ADMIN), USER(AuthoritiesConstants.USER), ANONYMOUS(AuthoritiesConstants.ANONYMOUS); - - private String name; - private GrantedAuthority grantedAuthority; - AuthoritiesConstantEnum(String name) { - this.name = name; - grantedAuthority = new SimpleGrantedAuthority(name); - } - - /** - * @return the name - */ - public String getName() { - return name; - } - - /** - * @return the grantedAuthority - */ - public GrantedAuthority getGrantedAuthority() { - return grantedAuthority; - } - + ADMIN(AuthoritiesConstants.ADMIN), + USER(AuthoritiesConstants.USER), + ANONYMOUS(AuthoritiesConstants.ANONYMOUS); + + private String name; + private GrantedAuthority grantedAuthority; + + AuthoritiesConstantEnum(String name) { + this.name = name; + grantedAuthority = new SimpleGrantedAuthority(name); + } + + /** + * @return the name + */ + public String getName() { + return name; + } + + /** + * @return the grantedAuthority + */ + public GrantedAuthority getGrantedAuthority() { + return grantedAuthority; + } } - + public static final GrantedAuthority ADMIN_AUTHORITY = new SimpleGrantedAuthority(ADMIN); - private AuthoritiesConstants() { - } + private AuthoritiesConstants() {} } diff --git a/src/main/java/at/ac/uibk/gitsearch/security/SecurityUtils.java b/src/main/java/at/ac/uibk/gitsearch/security/SecurityUtils.java index af7726eaa9fd5b991bf0983e810554adca16cb5e..70511e5fa7346b820e7f72a6a1180ea8d449ca98 100644 --- a/src/main/java/at/ac/uibk/gitsearch/security/SecurityUtils.java +++ b/src/main/java/at/ac/uibk/gitsearch/security/SecurityUtils.java @@ -42,12 +42,12 @@ public final class SecurityUtils { UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal(); return springSecurityUser.getUsername(); } else if (authentication instanceof JwtAuthenticationToken) { - return (String) ((JwtAuthenticationToken)authentication).getToken().getClaims().get("preferred_username"); + return (String) ((JwtAuthenticationToken) authentication).getToken().getClaims().get("preferred_username"); } else if (authentication instanceof OAuth2AuthenticationToken) { - // we use email for username! - return ((OidcUser) ((OAuth2AuthenticationToken) authentication).getPrincipal()).getEmail(); + // we use email for username! + return ((OidcUser) ((OAuth2AuthenticationToken) authentication).getPrincipal()).getEmail(); } else if (authentication.getPrincipal() instanceof OidcUser) { - return ((OidcUser) authentication.getPrincipal()).getName(); + return ((OidcUser) authentication.getPrincipal()).getName(); } else if (authentication.getPrincipal() instanceof String) { return (String) authentication.getPrincipal(); } @@ -113,22 +113,17 @@ public final class SecurityUtils { private static Stream<String> getAuthorities(Authentication authentication) { return authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority); } - + public static List<GrantedAuthority> extractAuthorityFromClaims(Map<String, Object> claims) { return mapRolesToGrantedAuthorities(getRolesFromClaims(claims)); } @SuppressWarnings("unchecked") private static Collection<String> getRolesFromClaims(Map<String, Object> claims) { - return (Collection<String>) claims.getOrDefault("groups", - claims.getOrDefault("roles", new ArrayList<>())); + return (Collection<String>) claims.getOrDefault("groups", claims.getOrDefault("roles", new ArrayList<>())); } private static List<GrantedAuthority> mapRolesToGrantedAuthorities(Collection<String> roles) { - return roles.stream() - .filter(role -> role.startsWith("ROLE_")) - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()); + return roles.stream().filter(role -> role.startsWith("ROLE_")).map(SimpleGrantedAuthority::new).collect(Collectors.toList()); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/security/jwt/TokenProvider.java b/src/main/java/at/ac/uibk/gitsearch/security/jwt/TokenProvider.java index 7bed6038284b8db85385af26100e447720ccc188..5ae0760236eb4e466ad39581cd46d77eb7867bec 100644 --- a/src/main/java/at/ac/uibk/gitsearch/security/jwt/TokenProvider.java +++ b/src/main/java/at/ac/uibk/gitsearch/security/jwt/TokenProvider.java @@ -1,5 +1,17 @@ package at.ac.uibk.gitsearch.security.jwt; +import at.ac.uibk.gitsearch.management.SecurityMetersService; +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtBuilder; +import io.jsonwebtoken.JwtParser; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.UnsupportedJwtException; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import io.jsonwebtoken.security.SignatureException; import java.nio.charset.StandardCharsets; import java.security.Key; import java.util.Arrays; @@ -9,7 +21,6 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; - import org.apache.commons.lang3.ObjectUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,70 +34,60 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.stereotype.Component; - -import at.ac.uibk.gitsearch.management.SecurityMetersService; -import io.jsonwebtoken.Claims; -import io.jsonwebtoken.ExpiredJwtException; -import io.jsonwebtoken.JwtBuilder; -import io.jsonwebtoken.JwtParser; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.MalformedJwtException; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.UnsupportedJwtException; -import io.jsonwebtoken.io.Decoders; -import io.jsonwebtoken.security.Keys; -import io.jsonwebtoken.security.SignatureException; import tech.jhipster.config.JHipsterProperties; @Component public class TokenProvider { - /** - * encapsulate gitlab access token and access issuer - * @author Michael Breu - * - */ + /** + * encapsulate gitlab access token and access issuer + * @author Michael Breu + * + */ public static class GitLabAccessInfo { - String accessToken; - String gitLabAccessIssuer; - Optional<User> user; - - public GitLabAccessInfo(String accessToken, String gitLabAccessIssuer, Optional<User> user) { - super(); - this.accessToken = accessToken; - this.gitLabAccessIssuer = gitLabAccessIssuer; - this.user = user; - } - /** - * @return the accessToken - */ - public String getAccessToken() { - return accessToken; - } - /** - * @return the gitLabAccessIssuer - */ - public String getGitLabAccessIssuer() { - return gitLabAccessIssuer; - } - /** - * @return the user - */ - public Optional<User> getUser() { - return user; - } - } - - public static final String GITLAB_ACCESS_TOKEN = "gitLabAccessToken"; + + String accessToken; + String gitLabAccessIssuer; + Optional<User> user; + + public GitLabAccessInfo(String accessToken, String gitLabAccessIssuer, Optional<User> user) { + super(); + this.accessToken = accessToken; + this.gitLabAccessIssuer = gitLabAccessIssuer; + this.user = user; + } + + /** + * @return the accessToken + */ + public String getAccessToken() { + return accessToken; + } + + /** + * @return the gitLabAccessIssuer + */ + public String getGitLabAccessIssuer() { + return gitLabAccessIssuer; + } + + /** + * @return the user + */ + public Optional<User> getUser() { + return user; + } + } + + public static final String GITLAB_ACCESS_TOKEN = "gitLabAccessToken"; public static final String GITLAB_ACCESS_ISSUER = "gitLabAccessIssuer"; - + @Value("${application.gitlab.url}") private String gitLabUrl; - - public static final String PRE_TOKEN_CLAIM = "preToken"; + public static final String PRE_TOKEN_CLAIM = "preToken"; - private final Logger log = LoggerFactory.getLogger(TokenProvider.class); + private final Logger log = LoggerFactory.getLogger(TokenProvider.class); private static final String AUTHORITIES_KEY = "auth"; @@ -101,7 +102,7 @@ public class TokenProvider { private final long tokenValidityInMillisecondsForRememberMe; private final SecurityMetersService securityMetersService; - + public TokenProvider(JHipsterProperties jHipsterProperties, SecurityMetersService securityMetersService) { byte[] keyBytes; String secret = jHipsterProperties.getSecurity().getAuthentication().getJwt().getBase64Secret(); @@ -132,9 +133,7 @@ public class TokenProvider { * @return */ public String createToken(Authentication authentication, boolean rememberMe) { - long validity = rememberMe - ?tokenValidityInMillisecondsForRememberMe - :tokenValidityInMilliseconds; + long validity = rememberMe ? tokenValidityInMillisecondsForRememberMe : tokenValidityInMilliseconds; return createToken(authentication, validity, false); } @@ -146,74 +145,61 @@ public class TokenProvider { * @param isPreToken include hint that this token entitles for a long term token * @return */ - public String createToken(Authentication authentication, long validity, boolean isPreToken) { + public String createToken(Authentication authentication, long validity, boolean isPreToken) { Date endTime = new Date(System.currentTimeMillis() + validity); - String authorities = authentication.getAuthorities().stream() - .map(GrantedAuthority::getAuthority) - .collect(Collectors.joining(",")); - JwtBuilder jwtBuilder = Jwts.builder() - .setSubject(authentication.getName()) - .claim(AUTHORITIES_KEY, authorities); - // copy from preToken - String authenticationToken = null; - String authenticationIssuer = null; - if (authentication.getDetails() instanceof Map) { - @SuppressWarnings("unchecked") - Map<String, String> details = (Map<String, String>) authentication.getDetails(); - authenticationToken = details.get(GITLAB_ACCESS_TOKEN); - authenticationIssuer = details.get(GITLAB_ACCESS_ISSUER); - } - if (authentication.getPrincipal() instanceof DefaultOidcUser) { - DefaultOidcUser oidcInfo = (DefaultOidcUser) authentication.getPrincipal(); - authenticationToken = oidcInfo.getClaimAsString(GITLAB_ACCESS_TOKEN); - authenticationIssuer = oidcInfo.getClaimAsString(GITLAB_ACCESS_ISSUER); - } - - if (authenticationToken!=null) { - jwtBuilder.claim(GITLAB_ACCESS_TOKEN, authenticationToken); - jwtBuilder.claim(GITLAB_ACCESS_ISSUER, authenticationIssuer); - } - - if(isPreToken) { - jwtBuilder = jwtBuilder.claim(PRE_TOKEN_CLAIM, PRE_TOKEN_CLAIM); + String authorities = authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.joining(",")); + JwtBuilder jwtBuilder = Jwts.builder().setSubject(authentication.getName()).claim(AUTHORITIES_KEY, authorities); + // copy from preToken + String authenticationToken = null; + String authenticationIssuer = null; + if (authentication.getDetails() instanceof Map) { + @SuppressWarnings("unchecked") + Map<String, String> details = (Map<String, String>) authentication.getDetails(); + authenticationToken = details.get(GITLAB_ACCESS_TOKEN); + authenticationIssuer = details.get(GITLAB_ACCESS_ISSUER); + } + if (authentication.getPrincipal() instanceof DefaultOidcUser) { + DefaultOidcUser oidcInfo = (DefaultOidcUser) authentication.getPrincipal(); + authenticationToken = oidcInfo.getClaimAsString(GITLAB_ACCESS_TOKEN); + authenticationIssuer = oidcInfo.getClaimAsString(GITLAB_ACCESS_ISSUER); } - return jwtBuilder - .signWith(key, SignatureAlgorithm.HS512) - .setExpiration(endTime) - .compact(); - } + + if (authenticationToken != null) { + jwtBuilder.claim(GITLAB_ACCESS_TOKEN, authenticationToken); + jwtBuilder.claim(GITLAB_ACCESS_ISSUER, authenticationIssuer); + } + + if (isPreToken) { + jwtBuilder = jwtBuilder.claim(PRE_TOKEN_CLAIM, PRE_TOKEN_CLAIM); + } + return jwtBuilder.signWith(key, SignatureAlgorithm.HS512).setExpiration(endTime).compact(); + } public Authentication getAuthentication(String token) { - Claims claims = Jwts.parserBuilder() - .setSigningKey(key) - .build() - .parseClaimsJws(token) - .getBody(); - - Collection<? extends GrantedAuthority> authorities = - Arrays.stream(claims.get(AUTHORITIES_KEY).toString().split(",")) - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()); + Claims claims = Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(token).getBody(); + + Collection<? extends GrantedAuthority> authorities = Arrays + .stream(claims.get(AUTHORITIES_KEY).toString().split(",")) + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); String preTokenFlag = (String) claims.get(PRE_TOKEN_CLAIM); - - User principal = new User(claims.getSubject(),"", authorities); + User principal = new User(claims.getSubject(), "", authorities); - final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(principal, token, authorities); - Map<String, String> detailsMap = new HashMap<>(); - if(preTokenFlag !=null) { - detailsMap.put(TokenProvider.PRE_TOKEN_CLAIM, preTokenFlag); + Map<String, String> detailsMap = new HashMap<>(); + if (preTokenFlag != null) { + detailsMap.put(TokenProvider.PRE_TOKEN_CLAIM, preTokenFlag); } String authenticationToken = (String) claims.get(GITLAB_ACCESS_TOKEN); String authenticationIssuer = (String) claims.get(GITLAB_ACCESS_ISSUER); - if(authenticationToken !=null) { - detailsMap.put(GITLAB_ACCESS_TOKEN, authenticationToken); - detailsMap.put(GITLAB_ACCESS_ISSUER, authenticationIssuer); - } - authentication.setDetails(detailsMap); - return authentication; + if (authenticationToken != null) { + detailsMap.put(GITLAB_ACCESS_TOKEN, authenticationToken); + detailsMap.put(GITLAB_ACCESS_ISSUER, authenticationIssuer); + } + authentication.setDetails(detailsMap); + return authentication; } public boolean validateToken(String authToken) { @@ -244,28 +230,28 @@ public class TokenProvider { return false; } - public Optional<User> getCurrentPrincipal() { + public Optional<User> getCurrentPrincipal() { SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication a = securityContext.getAuthentication(); - + final Object principal = a.getPrincipal(); - + if (principal instanceof User) { - return Optional.ofNullable((User)principal); - } + return Optional.ofNullable((User) principal); + } return Optional.empty(); } - - public Optional<String> getGitLabAccessToken() { + + public Optional<String> getGitLabAccessToken() { SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication authentication = securityContext.getAuthentication(); - if(authentication==null) return Optional.empty(); - final Object userDetails = authentication.getDetails(); - if (userDetails instanceof Map<?,?>) { - @SuppressWarnings("unchecked") - Map<String, String> userDetailsMap = (Map<String, String>) userDetails; - return Optional.ofNullable(userDetailsMap.get(GITLAB_ACCESS_TOKEN)); - } + if (authentication == null) return Optional.empty(); + final Object userDetails = authentication.getDetails(); + if (userDetails instanceof Map<?, ?>) { + @SuppressWarnings("unchecked") + Map<String, String> userDetailsMap = (Map<String, String>) userDetails; + return Optional.ofNullable(userDetailsMap.get(GITLAB_ACCESS_TOKEN)); + } return Optional.empty(); } @@ -273,27 +259,26 @@ public class TokenProvider { * returns the issuer URL for Gitlab API. * @return */ - public Optional<String> getGitLabAccessIssuer() { + public Optional<String> getGitLabAccessIssuer() { SecurityContext securityContext = SecurityContextHolder.getContext(); Authentication authentication = securityContext.getAuthentication(); - final Object userDetails = authentication.getDetails(); - if (userDetails instanceof Map<?,?>) { - @SuppressWarnings("unchecked") - Map<String, String> userDetailsMap = (Map<String, String>) userDetails; - return Optional.ofNullable(userDetailsMap.get(GITLAB_ACCESS_ISSUER)); - } + final Object userDetails = authentication.getDetails(); + if (userDetails instanceof Map<?, ?>) { + @SuppressWarnings("unchecked") + Map<String, String> userDetailsMap = (Map<String, String>) userDetails; + return Optional.ofNullable(userDetailsMap.get(GITLAB_ACCESS_ISSUER)); + } return Optional.empty(); } - + public Optional<GitLabAccessInfo> getGitLabAccessInfo() { - final Optional<String> accessToken = getGitLabAccessToken(); - if(accessToken.isPresent()) { - final Optional<String> accessIssuer = getGitLabAccessIssuer(); - if(accessIssuer.isPresent()) { - return Optional.of(new GitLabAccessInfo(accessToken.get(), gitLabUrl, getCurrentPrincipal()) ); - } - } - return Optional.empty(); + final Optional<String> accessToken = getGitLabAccessToken(); + if (accessToken.isPresent()) { + final Optional<String> accessIssuer = getGitLabAccessIssuer(); + if (accessIssuer.isPresent()) { + return Optional.of(new GitLabAccessInfo(accessToken.get(), gitLabUrl, getCurrentPrincipal())); + } + } + return Optional.empty(); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/GitSearchOAuth2AuthorizationRequestRepository.java b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/GitSearchOAuth2AuthorizationRequestRepository.java index 9f9a18c72f039a3a35a9d82d16d5ee5b30759596..aec89c1614d6ea369edbb505695c837c7f0dd3e3 100644 --- a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/GitSearchOAuth2AuthorizationRequestRepository.java +++ b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/GitSearchOAuth2AuthorizationRequestRepository.java @@ -2,10 +2,8 @@ package at.ac.uibk.gitsearch.security.oauth2; import java.util.HashMap; import java.util.Map; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.springframework.security.oauth2.client.web.AuthorizationRequestRepository; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; @@ -16,85 +14,87 @@ import org.springframework.util.Assert; * @author Michael Breu * */ -public class GitSearchOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository<OAuth2AuthorizationRequest>{ - - /** - * TODO this should be persisted in the database! - */ - private Map<String, OAuth2AuthorizationRequest> authorizationRequests = new HashMap<>(); +public class GitSearchOAuth2AuthorizationRequestRepository implements AuthorizationRequestRepository<OAuth2AuthorizationRequest> { - @Override - public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) { - Assert.notNull(request, "request cannot be null"); - String stateParameter = this.getStateParameter(request); - if (stateParameter == null) { - return null; - } -// Map<String, OAuth2AuthorizationRequest> authorizationRequests = this.getAuthorizationRequests(request); - return authorizationRequests.get(stateParameter); - } + /** + * TODO this should be persisted in the database! + */ + private Map<String, OAuth2AuthorizationRequest> authorizationRequests = new HashMap<>(); - @Override - public void saveAuthorizationRequest(OAuth2AuthorizationRequest authorizationRequest, HttpServletRequest request, - HttpServletResponse response) { - Assert.notNull(request, "request cannot be null"); - Assert.notNull(response, "response cannot be null"); - if (authorizationRequest == null) { - this.removeAuthorizationRequest(request, response); - return; - } - String state = authorizationRequest.getState(); - Assert.hasText(state, "authorizationRequest.state cannot be empty"); -// Map<String, OAuth2AuthorizationRequest> authorizationRequests = this.getAuthorizationRequests(request); - authorizationRequests.put(state, authorizationRequest); -// request.getSession().setAttribute(this.sessionAttributeName, authorizationRequests); - } + @Override + public OAuth2AuthorizationRequest loadAuthorizationRequest(HttpServletRequest request) { + Assert.notNull(request, "request cannot be null"); + String stateParameter = this.getStateParameter(request); + if (stateParameter == null) { + return null; + } + // Map<String, OAuth2AuthorizationRequest> authorizationRequests = this.getAuthorizationRequests(request); + return authorizationRequests.get(stateParameter); + } - @Override - public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) { - Assert.notNull(request, "request cannot be null"); - String stateParameter = this.getStateParameter(request); - if (stateParameter == null) { - return null; - } -// Map<String, OAuth2AuthorizationRequest> authorizationRequests = this.getAuthorizationRequests(request); - OAuth2AuthorizationRequest originalRequest = authorizationRequests.remove(stateParameter); -// if (!authorizationRequests.isEmpty()) { -// request.getSession().setAttribute(this.sessionAttributeName, authorizationRequests); -// } else { -// request.getSession().removeAttribute(this.sessionAttributeName); -// } - return originalRequest; - } + @Override + public void saveAuthorizationRequest( + OAuth2AuthorizationRequest authorizationRequest, + HttpServletRequest request, + HttpServletResponse response + ) { + Assert.notNull(request, "request cannot be null"); + Assert.notNull(response, "response cannot be null"); + if (authorizationRequest == null) { + this.removeAuthorizationRequest(request, response); + return; + } + String state = authorizationRequest.getState(); + Assert.hasText(state, "authorizationRequest.state cannot be empty"); + // Map<String, OAuth2AuthorizationRequest> authorizationRequests = this.getAuthorizationRequests(request); + authorizationRequests.put(state, authorizationRequest); + // request.getSession().setAttribute(this.sessionAttributeName, authorizationRequests); + } - @Override - public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { - Assert.notNull(response, "response cannot be null"); - return this.removeAuthorizationRequest(request); - } + @Override + public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request) { + Assert.notNull(request, "request cannot be null"); + String stateParameter = this.getStateParameter(request); + if (stateParameter == null) { + return null; + } + // Map<String, OAuth2AuthorizationRequest> authorizationRequests = this.getAuthorizationRequests(request); + OAuth2AuthorizationRequest originalRequest = authorizationRequests.remove(stateParameter); + // if (!authorizationRequests.isEmpty()) { + // request.getSession().setAttribute(this.sessionAttributeName, authorizationRequests); + // } else { + // request.getSession().removeAttribute(this.sessionAttributeName); + // } + return originalRequest; + } - /** - * Gets the state parameter from the {@link HttpServletRequest} - * @param request the request to use - * @return the state parameter or null if not found - */ - private String getStateParameter(HttpServletRequest request) { - return request.getParameter(OAuth2ParameterNames.STATE); - } + @Override + public OAuth2AuthorizationRequest removeAuthorizationRequest(HttpServletRequest request, HttpServletResponse response) { + Assert.notNull(response, "response cannot be null"); + return this.removeAuthorizationRequest(request); + } -// /** -// * Gets a non-null and mutable map of {@link OAuth2AuthorizationRequest#getState()} to an {@link OAuth2AuthorizationRequest} -// * @param request -// * @return a non-null and mutable map of {@link OAuth2AuthorizationRequest#getState()} to an {@link OAuth2AuthorizationRequest}. -// */ -// private Map<String, OAuth2AuthorizationRequest> getAuthorizationRequests(HttpServletRequest request) { -// HttpSession session = request.getSession(false); -// Map<String, OAuth2AuthorizationRequest> authorizationRequests = session == null ? null : -// (Map<String, OAuth2AuthorizationRequest>) session.getAttribute(this.sessionAttributeName); -// if (authorizationRequests == null) { -// return new HashMap<>(); -// } -// return authorizationRequests; -// } + /** + * Gets the state parameter from the {@link HttpServletRequest} + * @param request the request to use + * @return the state parameter or null if not found + */ + private String getStateParameter(HttpServletRequest request) { + return request.getParameter(OAuth2ParameterNames.STATE); + } + // /** + // * Gets a non-null and mutable map of {@link OAuth2AuthorizationRequest#getState()} to an {@link OAuth2AuthorizationRequest} + // * @param request + // * @return a non-null and mutable map of {@link OAuth2AuthorizationRequest#getState()} to an {@link OAuth2AuthorizationRequest}. + // */ + // private Map<String, OAuth2AuthorizationRequest> getAuthorizationRequests(HttpServletRequest request) { + // HttpSession session = request.getSession(false); + // Map<String, OAuth2AuthorizationRequest> authorizationRequests = session == null ? null : + // (Map<String, OAuth2AuthorizationRequest>) session.getAttribute(this.sessionAttributeName); + // if (authorizationRequests == null) { + // return new HashMap<>(); + // } + // return authorizationRequests; + // } } diff --git a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/JwtGrantedAuthorityConverter.java b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/JwtGrantedAuthorityConverter.java index 185457fef0fe525a9535009d5db38cf2f37a83f9..b87fc2969e876642c5514d91b6d2dff399d93ba9 100644 --- a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/JwtGrantedAuthorityConverter.java +++ b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/JwtGrantedAuthorityConverter.java @@ -1,9 +1,7 @@ package at.ac.uibk.gitsearch.security.oauth2; import at.ac.uibk.gitsearch.security.SecurityUtils; - import java.util.Collection; - import org.springframework.core.convert.converter.Converter; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.oauth2.jwt.Jwt; diff --git a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport.java b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport.java index 1c7521ab1d896df4b486fb1807f5f2c0d0f479bc..bf59aa1cd6fc5198b5300b0ef8cb8ef2c9ed811e 100644 --- a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport.java +++ b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport.java @@ -1,16 +1,15 @@ package at.ac.uibk.gitsearch.security.oauth2; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; import java.io.IOException; import java.security.Principal; import java.util.ArrayList; import java.util.Collection; import java.util.List; - import javax.servlet.ServletException; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; - import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -19,8 +18,6 @@ import org.springframework.security.oauth2.core.oidc.user.DefaultOidcUser; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; - /** * allows for a redirect and adds a short-lived cookie that encodes a short lived JWT-Token * @author Michael Breu @@ -28,132 +25,126 @@ import at.ac.uibk.gitsearch.security.jwt.TokenProvider; */ public class SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport extends SavedRequestAwareAuthenticationSuccessHandler { - protected TokenProvider tokenProvider; - - - public SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport(TokenProvider tokenProvider) { - super(); - this.tokenProvider = tokenProvider; - } - - - private static final int REQUEST_TOKEN_LIVETIME = 10; // seconds - @Override - public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) throws ServletException, IOException { - Authentication authenticationForToken = authentication; - if (authentication instanceof OAuth2AuthenticationToken) { - OAuth2AuthenticationToken oAuthA = (OAuth2AuthenticationToken) authentication; - @SuppressWarnings("unchecked") - List<String> gitLabGroups = (List<String>) ((OidcUser) ((OAuth2AuthenticationToken) authentication).getPrincipal()).getClaims().get("groups"); - final DefaultOidcUser principal = (DefaultOidcUser) oAuthA.getPrincipal(); - List<GrantedAuthority> roles = new ArrayList<>(); - roles.addAll(authentication.getAuthorities()); - for(String gitLabGroup: gitLabGroups) { - roles.add(new SimpleGrantedAuthority(gitLabGroup)); - } - - DefaultOidcUser emailUser = new DefaultOidcUser(roles, principal.getIdToken(), principal.getUserInfo(),"email"); - - OAuth2AuthenticationToken oauth2Authentication = new OAuth2AuthenticationToken( - emailUser, - roles, - oAuthA.getAuthorizedClientRegistrationId()); - - authenticationForToken = oauth2Authentication; - authenticationForToken.setAuthenticated(authentication.isAuthenticated()); - } - String token = tokenProvider.createToken(authenticationForToken, REQUEST_TOKEN_LIVETIME *1000L, true /* preToken */); // 200 secs (for Debugging) - - Cookie tempTokenCookie = new Cookie("tempRequestToken", token); - tempTokenCookie.setMaxAge(REQUEST_TOKEN_LIVETIME); - tempTokenCookie.setPath("/"); - tempTokenCookie.setSecure(true); - - response.addCookie(tempTokenCookie); - - super.onAuthenticationSuccess(request, response, authentication); - } - - - - @Override - protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, - Authentication authentication) { - return super.determineTargetUrl(request, response, authentication); - } - - + protected TokenProvider tokenProvider; + + public SavedRequestAwareAuthenticationSuccessHandlerWithJWTSupport(TokenProvider tokenProvider) { + super(); + this.tokenProvider = tokenProvider; + } + + private static final int REQUEST_TOKEN_LIVETIME = 10; // seconds + + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) + throws ServletException, IOException { + Authentication authenticationForToken = authentication; + if (authentication instanceof OAuth2AuthenticationToken) { + OAuth2AuthenticationToken oAuthA = (OAuth2AuthenticationToken) authentication; + @SuppressWarnings("unchecked") + List<String> gitLabGroups = (List<String>) ((OidcUser) ((OAuth2AuthenticationToken) authentication).getPrincipal()).getClaims() + .get("groups"); + final DefaultOidcUser principal = (DefaultOidcUser) oAuthA.getPrincipal(); + List<GrantedAuthority> roles = new ArrayList<>(); + roles.addAll(authentication.getAuthorities()); + for (String gitLabGroup : gitLabGroups) { + roles.add(new SimpleGrantedAuthority(gitLabGroup)); + } + + DefaultOidcUser emailUser = new DefaultOidcUser(roles, principal.getIdToken(), principal.getUserInfo(), "email"); + + OAuth2AuthenticationToken oauth2Authentication = new OAuth2AuthenticationToken( + emailUser, + roles, + oAuthA.getAuthorizedClientRegistrationId() + ); + + authenticationForToken = oauth2Authentication; + authenticationForToken.setAuthenticated(authentication.isAuthenticated()); + } + String token = tokenProvider.createToken(authenticationForToken, REQUEST_TOKEN_LIVETIME * 1000L, true/* preToken */); // 200 secs (for Debugging) + + Cookie tempTokenCookie = new Cookie("tempRequestToken", token); + tempTokenCookie.setMaxAge(REQUEST_TOKEN_LIVETIME); + tempTokenCookie.setPath("/"); + tempTokenCookie.setSecure(true); + + response.addCookie(tempTokenCookie); + + super.onAuthenticationSuccess(request, response, authentication); + } + + @Override + protected String determineTargetUrl(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { + return super.determineTargetUrl(request, response, authentication); + } + public static class SimplePrincipal implements Principal { - protected String name; - - - public SimplePrincipal(String name) { - super(); - this.name = name; - } - - @Override - public String getName() { - return name; - } - + protected String name; + + public SimplePrincipal(String name) { + super(); + this.name = name; + } + + @Override + public String getName() { + return name; + } } - + public static class SimpleAuthentication implements Authentication { - /** - * - */ - private static final long serialVersionUID = -791646857551363545L; - - private Principal principal; - - Collection<? extends GrantedAuthority> authorities; - - public SimpleAuthentication(Principal principal, Collection<? extends GrantedAuthority> authorities) { - super(); - this.principal = principal; - this.authorities = authorities; - } - - @Override - public String getName() { - return principal.getName(); - } - - @Override - public Collection<? extends GrantedAuthority> getAuthorities() { - return authorities; - } - - @Override - public Object getCredentials() { - return null; - } - - @Override - public Object getDetails() { - return null; - } - - @Override - public Object getPrincipal() { - return principal; - } - - private boolean authenticated = false; - @Override - public boolean isAuthenticated() { - return authenticated; - } - - @Override - public void setAuthenticated(boolean isAuthenticated) { - authenticated = isAuthenticated; - } - + /** + * + */ + private static final long serialVersionUID = -791646857551363545L; + + private Principal principal; + + Collection<? extends GrantedAuthority> authorities; + + public SimpleAuthentication(Principal principal, Collection<? extends GrantedAuthority> authorities) { + super(); + this.principal = principal; + this.authorities = authorities; + } + + @Override + public String getName() { + return principal.getName(); + } + + @Override + public Collection<? extends GrantedAuthority> getAuthorities() { + return authorities; + } + + @Override + public Object getCredentials() { + return null; + } + + @Override + public Object getDetails() { + return null; + } + + @Override + public Object getPrincipal() { + return principal; + } + + private boolean authenticated = false; + + @Override + public boolean isAuthenticated() { + return authenticated; + } + + @Override + public void setAuthenticated(boolean isAuthenticated) { + authenticated = isAuthenticated; + } } - -} \ No newline at end of file +} diff --git a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcher.java b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcher.java index fc49c5511aa61703c0dd2a175dadfc895023054a..112d6715df54ca26ada4562acbdb01f3e85fb440 100644 --- a/src/main/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcher.java +++ b/src/main/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcher.java @@ -1,5 +1,7 @@ package at.ac.uibk.gitsearch.security.oauth2; +import at.ac.uibk.gitsearch.domain.Authority; +import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; import java.time.Instant; import java.util.ArrayList; import java.util.HashSet; @@ -7,7 +9,6 @@ import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.function.Consumer; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.gitlab4j.api.Constants.TokenType; @@ -20,103 +21,101 @@ import org.springframework.security.oauth2.core.OAuth2AccessToken; import org.springframework.security.oauth2.core.oidc.user.OidcUser; import org.springframework.stereotype.Component; -import at.ac.uibk.gitsearch.domain.Authority; -import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; - @Component public class UserDetailsFetcher { - - private static final Logger logger = LogManager.getLogger(UserDetailsFetcher.class); - - /** fills in data from OIDC repository. - * returns true, if user data really changed **/ - public boolean updateUserDetails(AdminUserDTO u, OidcUser oidcUser, OAuth2LoginAuthenticationToken oAuth2LoginAuthenticationToken) { - final OAuth2AccessToken accessToken = oAuth2LoginAuthenticationToken.getAccessToken(); - final ClientRegistration clientRegistration = oAuth2LoginAuthenticationToken.getClientRegistration(); - return updateUserDetails(u, oidcUser, accessToken, clientRegistration); - } - /** - * fills in date from OIDC repository - * @param u - * @param oidcUser - * @param accessToken - * @param clientRegistration - * @return - */ - public boolean updateUserDetails(AdminUserDTO u, OidcUser oidcUser, final OAuth2AccessToken accessToken, - final ClientRegistration clientRegistration) { - String idToken = accessToken.getTokenValue(); - String issuerURI = (String) clientRegistration.getProviderDetails().getConfigurationMetadata().get("issuer"); - try( GitLabApi gitLabApi = new GitLabApi(issuerURI, TokenType.OAUTH2_ACCESS, idToken)) { - boolean modified = false; - gitLabApi.enableRequestResponseLogging(); - // List<Project> memberProjects = gitLabApi.getProjectApi().getMemberProjects(); - final Set<String> authorities = new HashSet<>(); - // remove all old gitlab roles - u.getAuthorities().stream().filter(Authority::isStandardRole).forEach(authorities::add); - - @SuppressWarnings("unchecked") - final List<String> gitLabGroups = (List<String>)oidcUser.getAttribute("groups"); - // add gitlab groups - authorities.addAll(reduceGroups(gitLabGroups)); // only add main groups - - User gitUser = gitLabApi.getUserApi().getCurrentUser(); - - modified |= updateAttribute(gitUser.getAvatarUrl(),u.getImageUrl(), u::setImageUrl); - modified |= updateAttribute(gitUser.getEmail(), u.getEmail(), u::setEmail); - modified |= updateAttribute(gitUser.getName(),u.getLastName(), u::setLastName); - if(!u.getAuthorities().equals(authorities)) { - u.setAuthorities(authorities); - modified = true; - } - // modified |= updateAttribute(gitUser.getUsername(),u.getLogin(), u::setLogin); - - - if (modified) u.setLastModifiedDate(Instant.now()); - // testMetaDataGenerator.generateTestData(gitLabApi, issuerURI, idToken); - return modified; - } catch (GitLabApiException e) { - logger.warn("Cannot fetch details for user {}", oidcUser.getName(), e); - -} - return false; - } - - /** - * unfortunatelly gitlab returns not only the main groups but also all groups in the project hierarchy. That makes the list - * very large. We need only the main groups! - * @param groups - * @return - */ - protected List<String> reduceGroups(List<String> groups) { - List<String> unNormalizedGroups = new ArrayList<>(groups.size()); - unNormalizedGroups.addAll(groups); - final Iterator<String> unNormalizedGroupsIterator = unNormalizedGroups.iterator(); - while (unNormalizedGroupsIterator.hasNext()) { - String groupToCheck = unNormalizedGroupsIterator.next(); - for(String otherGroup: unNormalizedGroups) { - if(groupToCheck.startsWith(otherGroup) - && groupToCheck.length() != otherGroup.length() // same group, just continue - && groupToCheck.charAt(otherGroup.length()) == '/') { // it is a real subgroup - unNormalizedGroupsIterator.remove(); - break; - - } - } - } - return unNormalizedGroups; // now normalized :-) - - } - - private static boolean updateAttribute (String newString, String oldString, Consumer<String> setter) { - if(oldString==null) { - if(newString == null) return false; - } else if(oldString.equals(newString)) { - return false; - } - setter.accept(newString); - return true; - } - + private static final Logger logger = LogManager.getLogger(UserDetailsFetcher.class); + + /** fills in data from OIDC repository. + * returns true, if user data really changed **/ + public boolean updateUserDetails(AdminUserDTO u, OidcUser oidcUser, OAuth2LoginAuthenticationToken oAuth2LoginAuthenticationToken) { + final OAuth2AccessToken accessToken = oAuth2LoginAuthenticationToken.getAccessToken(); + final ClientRegistration clientRegistration = oAuth2LoginAuthenticationToken.getClientRegistration(); + return updateUserDetails(u, oidcUser, accessToken, clientRegistration); + } + + /** + * fills in date from OIDC repository + * @param u + * @param oidcUser + * @param accessToken + * @param clientRegistration + * @return + */ + public boolean updateUserDetails( + AdminUserDTO u, + OidcUser oidcUser, + final OAuth2AccessToken accessToken, + final ClientRegistration clientRegistration + ) { + String idToken = accessToken.getTokenValue(); + String issuerURI = (String) clientRegistration.getProviderDetails().getConfigurationMetadata().get("issuer"); + try (GitLabApi gitLabApi = new GitLabApi(issuerURI, TokenType.OAUTH2_ACCESS, idToken)) { + boolean modified = false; + gitLabApi.enableRequestResponseLogging(); + // List<Project> memberProjects = gitLabApi.getProjectApi().getMemberProjects(); + final Set<String> authorities = new HashSet<>(); + // remove all old gitlab roles + u.getAuthorities().stream().filter(Authority::isStandardRole).forEach(authorities::add); + + @SuppressWarnings("unchecked") + final List<String> gitLabGroups = (List<String>) oidcUser.getAttribute("groups"); + // add gitlab groups + authorities.addAll(reduceGroups(gitLabGroups)); // only add main groups + + User gitUser = gitLabApi.getUserApi().getCurrentUser(); + + modified |= updateAttribute(gitUser.getAvatarUrl(), u.getImageUrl(), u::setImageUrl); + modified |= updateAttribute(gitUser.getEmail(), u.getEmail(), u::setEmail); + modified |= updateAttribute(gitUser.getName(), u.getLastName(), u::setLastName); + if (!u.getAuthorities().equals(authorities)) { + u.setAuthorities(authorities); + modified = true; + } + // modified |= updateAttribute(gitUser.getUsername(),u.getLogin(), u::setLogin); + + if (modified) u.setLastModifiedDate(Instant.now()); + // testMetaDataGenerator.generateTestData(gitLabApi, issuerURI, idToken); + return modified; + } catch (GitLabApiException e) { + logger.warn("Cannot fetch details for user {}", oidcUser.getName(), e); + } + return false; + } + + /** + * unfortunatelly gitlab returns not only the main groups but also all groups in the project hierarchy. That makes the list + * very large. We need only the main groups! + * @param groups + * @return + */ + protected List<String> reduceGroups(List<String> groups) { + List<String> unNormalizedGroups = new ArrayList<>(groups.size()); + unNormalizedGroups.addAll(groups); + final Iterator<String> unNormalizedGroupsIterator = unNormalizedGroups.iterator(); + while (unNormalizedGroupsIterator.hasNext()) { + String groupToCheck = unNormalizedGroupsIterator.next(); + for (String otherGroup : unNormalizedGroups) { + if ( + groupToCheck.startsWith(otherGroup) && + groupToCheck.length() != otherGroup.length() && // same group, just continue + groupToCheck.charAt(otherGroup.length()) == '/' + ) { // it is a real subgroup + unNormalizedGroupsIterator.remove(); + break; + } + } + } + return unNormalizedGroups; // now normalized :-) + } + + private static boolean updateAttribute(String newString, String oldString, Consumer<String> setter) { + if (oldString == null) { + if (newString == null) return false; + } else if (oldString.equals(newString)) { + return false; + } + setter.accept(newString); + return true; + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/AchievementService.java b/src/main/java/at/ac/uibk/gitsearch/service/AchievementService.java index ef3924e6e1b5a44017fa876170f68111e6eb9a4b..e6a3cc4b83f5fe1b3267497bb67ffdeaafc9554f 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/AchievementService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/AchievementService.java @@ -1,9 +1,10 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.repository.StatisticsRepository; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; import java.io.IOException; import java.util.ArrayList; import java.util.List; - import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.codeability.sharing.plugins.api.search.SearchResultsDTO; import org.slf4j.Logger; @@ -11,13 +12,10 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.repository.StatisticsRepository; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; - @Service @Transactional public class AchievementService { - + private final Logger log = LoggerFactory.getLogger(AchievementService.class); private final SearchService searchService; @@ -29,50 +27,38 @@ public class AchievementService { this.statisticsRepository = statisticsRepository; } - public StatisticsDTO searchUserStatistics(String email) throws IOException { - SearchResultsDTO results = searchService.searchResultForAuthorEmail(email, 1000); - List<SearchResultDTO> result = results.getSearchResult(); List<String> query = new ArrayList<>(); - for (int i = 0; i < result.size() ; i++) { - query.add(result.get(i).getExerciseId()); + for (int i = 0; i < result.size(); i++) { + query.add(result.get(i).getExerciseId()); } StatisticsDTO toReturn = new StatisticsDTO(); List<Integer[]> data = statisticsRepository.findNumberOfDownloadsAndViewsByExerciseIDs(query); - - if(data.get(0)[0] != null){ + if (data.get(0)[0] != null) { toReturn.setDownloads(data.get(0)[0]); - }else { + } else { toReturn.setDownloads(0); - } - if(data.get(0)[1] != null){ + if (data.get(0)[1] != null) { toReturn.setViews(data.get(0)[1]); - }else { + } else { toReturn.setViews(0); - } log.info("Returning " + data.get(0)[1] + " views and " + data.get(0)[0] + " downloads"); return toReturn; - - } - } - - - // Maybe to use later // Optional<StatisticsDTO> statisticsDTO = statisticsService.findOneByExerciseID((result.getExerciseId())); // if (statisticsDTO.isPresent()) { // StatisticsDTO newStats = statisticsDTO.get(); // totalAmountOfViews += newStats.getViews(); // totalAmountOfDownloads += newStats.getDownloads(); -// } \ No newline at end of file +// } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/AuditEventService.java b/src/main/java/at/ac/uibk/gitsearch/service/AuditEventService.java index bb94487c2d6d622299516bba4daf2de06ca492ed..70d5e53744d563e450f87281663c7f1a9c2eb73c 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/AuditEventService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/AuditEventService.java @@ -1,8 +1,10 @@ package at.ac.uibk.gitsearch.service; -import tech.jhipster.config.JHipsterProperties; import at.ac.uibk.gitsearch.repository.AuditEventConverter; import at.ac.uibk.gitsearch.repository.PersistenceAuditEventRepository; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Optional; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.actuate.audit.AuditEvent; @@ -11,10 +13,7 @@ import org.springframework.data.domain.Pageable; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.Optional; +import tech.jhipster.config.JHipsterProperties; /** * Service for managing audit events. @@ -35,8 +34,9 @@ public class AuditEventService { public AuditEventService( PersistenceAuditEventRepository persistenceAuditEventRepository, - AuditEventConverter auditEventConverter, JHipsterProperties jhipsterProperties) { - + AuditEventConverter auditEventConverter, + JHipsterProperties jhipsterProperties + ) { this.persistenceAuditEventRepository = persistenceAuditEventRepository; this.auditEventConverter = auditEventConverter; this.jHipsterProperties = jhipsterProperties; @@ -59,19 +59,18 @@ public class AuditEventService { @Transactional(readOnly = true) public Page<AuditEvent> findAll(Pageable pageable) { - return persistenceAuditEventRepository.findAll(pageable) - .map(auditEventConverter::convertToAuditEvent); + return persistenceAuditEventRepository.findAll(pageable).map(auditEventConverter::convertToAuditEvent); } @Transactional(readOnly = true) public Page<AuditEvent> findByDates(Instant fromDate, Instant toDate, Pageable pageable) { - return persistenceAuditEventRepository.findAllByAuditEventDateBetween(fromDate, toDate, pageable) + return persistenceAuditEventRepository + .findAllByAuditEventDateBetween(fromDate, toDate, pageable) .map(auditEventConverter::convertToAuditEvent); } @Transactional(readOnly = true) public Optional<AuditEvent> find(Long id) { - return persistenceAuditEventRepository.findById(id) - .map(auditEventConverter::convertToAuditEvent); + return persistenceAuditEventRepository.findById(id).map(auditEventConverter::convertToAuditEvent); } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/EditorialPagesService.java b/src/main/java/at/ac/uibk/gitsearch/service/EditorialPagesService.java index 0bcac7090235d01e29ba81bb49f52ac18ab46f7c..7c3d35ed046201574bfa9307d0dab34df15f6124 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/EditorialPagesService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/EditorialPagesService.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; +import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; - import org.gitlab4j.api.GitLabApiException; import org.gitlab4j.api.models.WikiPage; import org.springframework.beans.factory.annotation.Autowired; @@ -12,9 +13,6 @@ import org.springframework.cache.annotation.Cacheable; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; -import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; -import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; - /** * this service enables the provisioning of editorial pages. * The basic idea is, to use the wiki of a dedicated git project to edit pages. @@ -23,36 +21,35 @@ import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; * */ @Service -@CacheConfig(cacheNames={EditorialPagesService.PAGES_CACHE}) +@CacheConfig(cacheNames = { EditorialPagesService.PAGES_CACHE }) public class EditorialPagesService { - - public static final String PAGES_CACHE = "pages"; - - private static final String editorialProject = "infrastructure/GitSearchEditorialPages"; - @Autowired - private GitLabRepository gitLabRepository; - - @Cacheable(PAGES_CACHE) - public EditorialPageDTO getContent(String path) throws GitLabApiException { - String encodedPath; - encodedPath = URLEncoder.encode(path, StandardCharsets.UTF_8); - final WikiPage page = gitLabRepository.getGitLabApi().getWikisApi().getPage(editorialProject, encodedPath); - return new EditorialPageDTO(path, page.getContent()); - } - - @CacheEvict(value = PAGES_CACHE, allEntries = true) - public boolean resetCache() { - return true; // nothing to do - } - - @Scheduled(fixedRate = 30*60*1000L) // every 30 Minutes - public void evictPagesCacheAtIntervals() { - resetCache(); - } - - public String getAttachmentURL(String path) throws GitLabApiException { - return gitLabRepository.getRepositoryURL() + "infrastructure/gitsearcheditorialpages/-/wikis/" + path; - } - + public static final String PAGES_CACHE = "pages"; + + private static final String editorialProject = "infrastructure/GitSearchEditorialPages"; + + @Autowired + private GitLabRepository gitLabRepository; + + @Cacheable(PAGES_CACHE) + public EditorialPageDTO getContent(String path) throws GitLabApiException { + String encodedPath; + encodedPath = URLEncoder.encode(path, StandardCharsets.UTF_8); + final WikiPage page = gitLabRepository.getGitLabApi().getWikisApi().getPage(editorialProject, encodedPath); + return new EditorialPageDTO(path, page.getContent()); + } + + @CacheEvict(value = PAGES_CACHE, allEntries = true) + public boolean resetCache() { + return true; // nothing to do + } + + @Scheduled(fixedRate = 30 * 60 * 1000L) // every 30 Minutes + public void evictPagesCacheAtIntervals() { + resetCache(); + } + + public String getAttachmentURL(String path) throws GitLabApiException { + return gitLabRepository.getRepositoryURL() + "infrastructure/gitsearcheditorialpages/-/wikis/" + path; + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/ExerciseService.java b/src/main/java/at/ac/uibk/gitsearch/service/ExerciseService.java index 69d527952e9048e6a1052f0957a04de364097242..2298ed0095098524f1a3563adc55c332535edf92 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/ExerciseService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/ExerciseService.java @@ -1,5 +1,13 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.es.model.ArtemisExerciseInfo; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; @@ -15,11 +23,11 @@ import java.nio.file.Paths; import java.util.Objects; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; - import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; - +import net.minidev.json.JSONObject; +import net.minidev.json.JSONStyle; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.eclipse.jgit.api.errors.GitAPIException; @@ -30,18 +38,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.core.JsonFactory; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.MapperFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; - -import at.ac.uibk.gitsearch.es.model.ArtemisExerciseInfo; -import at.ac.uibk.gitsearch.properties.ApplicationProperties; -import net.minidev.json.JSONObject; -import net.minidev.json.JSONStyle; - @Service public class ExerciseService { @@ -53,7 +49,11 @@ public class ExerciseService { private final GitlabService gitlabService; - public ExerciseService(at.ac.uibk.gitsearch.properties.ApplicationProperties applicationProperties, FileService fileService, GitlabService gitlabService) { + public ExerciseService( + at.ac.uibk.gitsearch.properties.ApplicationProperties applicationProperties, + FileService fileService, + GitlabService gitlabService + ) { this.applicationProperties = applicationProperties; this.fileService = fileService; this.gitlabService = gitlabService; @@ -71,15 +71,20 @@ public class ExerciseService { WebTarget target = client.target(exerciseUrl); try { - InputStream inputStream = target.request().header("Authorization", getApiKeyOfRegisteredConnectorByUrl(new URI(exerciseUrl).getAuthority())).accept(javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM).get(InputStream.class); + InputStream inputStream = target + .request() + .header("Authorization", getApiKeyOfRegisteredConnectorByUrl(new URI(exerciseUrl).getAuthority())) + .accept(javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM) + .get(InputStream.class); ZipInputStream zipInput = new ZipInputStream(inputStream); storeZipInTmp(zipInput, exerciseToken); - } catch (URISyntaxException e) { log.error("Unable to add apiKey to the import request for [{}]. Try to request resource without apiKey.", exerciseUrl); } catch (Exception e) { - throw new ArtemisImportError("ZipFile couldn't be retrieved from [" + URLDecoder.decode(exerciseUrl, StandardCharsets.UTF_8) + "]" + e.getMessage()); + throw new ArtemisImportError( + "ZipFile couldn't be retrieved from [" + URLDecoder.decode(exerciseUrl, StandardCharsets.UTF_8) + "]" + e.getMessage() + ); } } @@ -94,7 +99,8 @@ public class ExerciseService { * @param exerciseInfo of the exercise to import * @param exerciseToken of the stored exercise (in '/tmp-import' directory) to import */ - public void importExercise(ArtemisExerciseInfo exerciseInfo, String exerciseToken, Integer gitlabGroupId) throws GitLabApiException, GitAPIException, IOException, ArtemisImportError { + public void importExercise(ArtemisExerciseInfo exerciseInfo, String exerciseToken, Integer gitlabGroupId) + throws GitLabApiException, GitAPIException, IOException, ArtemisImportError { applyExerciseInfoChanges(exerciseInfo, exerciseToken); renameFiles(exerciseToken); @@ -120,17 +126,19 @@ public class ExerciseService { */ public ArtemisExerciseInfo getArtemisExerciseInfo(String exerciseToken) throws IOException { ObjectMapper mapper = new ObjectMapper(new JsonFactory()); - mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING) + mapper + .enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING) .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY) - .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);; - File exerciseDetailsFile = Objects.requireNonNull(new File("tmp-import", exerciseToken).listFiles((file, name) -> name.startsWith("Exercise-Details-") && name.endsWith(".json")))[0]; - + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + File exerciseDetailsFile = Objects.requireNonNull( + new File("tmp-import", exerciseToken).listFiles((file, name) -> name.startsWith("Exercise-Details-") && name.endsWith(".json")) + )[0]; mapArtemisExerciseInfoValues(exerciseDetailsFile); ArtemisExerciseInfo artemisExerciseInfo = mapper.readValue(exerciseDetailsFile, ArtemisExerciseInfo.class); - writeArtemisMetadataFile(exerciseDetailsFile, artemisExerciseInfo); + writeArtemisMetadataFile(exerciseDetailsFile, artemisExerciseInfo); return artemisExerciseInfo; } @@ -181,7 +189,7 @@ public class ExerciseService { } try (FileWriter fileWriter = new FileWriter(jsonFile, StandardCharsets.UTF_8)) { - fileWriter.write(jsonObject.toString(JSONStyle.NO_COMPRESS)); + fileWriter.write(jsonObject.toString(JSONStyle.NO_COMPRESS)); } } @@ -192,15 +200,15 @@ public class ExerciseService { * @throws IOException if an error occurs */ private void writeArtemisMetadataFile(File jsonMetadataFile, ArtemisExerciseInfo artemisExerciseInfo) throws IOException { - ObjectMapper mapper = new ObjectMapper(new YAMLFactory() - .enable(YAMLGenerator.Feature.INDENT_ARRAYS) - .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)); + ObjectMapper mapper = new ObjectMapper( + new YAMLFactory().enable(YAMLGenerator.Feature.INDENT_ARRAYS).disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER) + ); File artemisMetadataFile = new File(jsonMetadataFile.getParent(), "artemis.yaml"); if (!artemisMetadataFile.exists()) { boolean success = artemisMetadataFile.createNewFile(); - if(!success) { - log.warn("Cannot create file"); + if (!success) { + log.warn("Cannot create file"); } } mapper.writeValue(artemisMetadataFile, artemisExerciseInfo.getArtemisInfoOnly()); @@ -227,19 +235,25 @@ public class ExerciseService { // https://www.baeldung.com/java-compress-and-uncompress while ((zipEntry = zipInputStream.getNextEntry()) != null) { - if (zipEntry.getName().contains(".git")) { // important as Artemis exercises come in submodules + if (zipEntry.getName().contains(".git")) { // important as Artemis exercises come in submodules continue; } File entryFile = new File(tmpDir, zipEntry.getName()); if (zipEntry.getName().endsWith(".zip")) { writeFile(entryFile, zipInputStream); String newSubDir; - if (StringUtils.endsWithAny(zipEntry.getName(), new String[]{"-exercise.zip", "-solution.zip", "-tests.zip"})) { + if (StringUtils.endsWithAny(zipEntry.getName(), new String[] { "-exercise.zip", "-solution.zip", "-tests.zip" })) { // extract repo directory name only - newSubDir = Paths.get(entryFile.getParentFile().getParent(), zipEntry.getName().substring(zipEntry.getName().lastIndexOf("-") + 1, zipEntry.getName().lastIndexOf("."))).toString(); + newSubDir = + Paths + .get( + entryFile.getParentFile().getParent(), + zipEntry.getName().substring(zipEntry.getName().lastIndexOf("-") + 1, zipEntry.getName().lastIndexOf(".")) + ) + .toString(); } else { newSubDir = Paths.get(subDir, entryFile.getName()).toString(); - newSubDir = newSubDir.substring(0, newSubDir.lastIndexOf(".")); // remove '.zip' from path + newSubDir = newSubDir.substring(0, newSubDir.lastIndexOf(".")); // remove '.zip' from path } if (newSubDir.startsWith("tmp-import")) { newSubDir = newSubDir.replaceFirst("tmp-import/", ""); @@ -248,12 +262,11 @@ public class ExerciseService { if (Files.deleteIfExists(entryFile.toPath())) { log.warn("Unable to delete temporary Zip file [{}] after extraction. Skipping..", entryFile.getPath()); } - } - else if (zipEntry.isDirectory()) { + } else if (zipEntry.isDirectory()) { if (!entryFile.mkdir()) { throw new IOException("Failed to create directory " + entryFile); } - } else if (!zipEntry.getName().endsWith(".zip")){ + } else if (!zipEntry.getName().endsWith(".zip")) { // fix for Windows-created archives File parent = entryFile.getParentFile(); if (!parent.isDirectory() && !parent.mkdirs()) { @@ -263,7 +276,7 @@ public class ExerciseService { writeFile(entryFile, zipInputStream); } } - if (tmpDir.isDirectory() && fileService.isEmpty(tmpDir.toPath())){ + if (tmpDir.isDirectory() && fileService.isEmpty(tmpDir.toPath())) { Files.delete(tmpDir.toPath()); } zipInputStream.close(); @@ -279,12 +292,12 @@ public class ExerciseService { private void writeFile(File entryFile, ZipInputStream zipInputStream) throws IOException { byte[] buffer = new byte[1024]; - try (FileOutputStream fos = new FileOutputStream(entryFile)) { - int len; - while ((len = zipInputStream.read(buffer)) > 0) { - fos.write(buffer, 0, len); - } - } + try (FileOutputStream fos = new FileOutputStream(entryFile)) { + int len; + while ((len = zipInputStream.read(buffer)) > 0) { + fos.write(buffer, 0, len); + } + } } /** @@ -294,9 +307,9 @@ public class ExerciseService { * @throws IOException */ public void applyExerciseInfoChanges(ArtemisExerciseInfo exerciseInfo, String exerciseToken) throws IOException { - ObjectMapper mapper = new ObjectMapper(new YAMLFactory() - .enable(YAMLGenerator.Feature.INDENT_ARRAYS) - .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER)); + ObjectMapper mapper = new ObjectMapper( + new YAMLFactory().enable(YAMLGenerator.Feature.INDENT_ARRAYS).disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER) + ); mapper.writeValue(new File("tmp-import/" + exerciseToken, "metadata.yaml"), exerciseInfo.getExerciseInfoOnly()); } @@ -343,17 +356,22 @@ public class ExerciseService { */ private void renameFiles(String exerciseToken) { try { - File problemStatementFile = Objects.requireNonNull(new File("tmp-import", exerciseToken).listFiles((file, name) -> name.startsWith("Problem-Statement-") && name.endsWith(".md")))[0]; + File problemStatementFile = Objects.requireNonNull( + new File("tmp-import", exerciseToken) + .listFiles((file, name) -> name.startsWith("Problem-Statement-") && name.endsWith(".md")) + )[0]; if (!problemStatementFile.renameTo(new File("tmp-import" + File.separator + exerciseToken, "exercise.md"))) { log.error("Unable to rename file [{}]. Skipping..", problemStatementFile.getName()); } - File exerciseDetailsFile = Objects.requireNonNull(new File("tmp-import", exerciseToken).listFiles((file, name) -> name.startsWith("Exercise-Details-") && name.endsWith(".json")))[0]; + File exerciseDetailsFile = Objects.requireNonNull( + new File("tmp-import", exerciseToken) + .listFiles((file, name) -> name.startsWith("Exercise-Details-") && name.endsWith(".json")) + )[0]; Files.move(exerciseDetailsFile.toPath(), exerciseDetailsFile.toPath().resolveSibling("Exercise-Details.json")); } catch (ArrayIndexOutOfBoundsException e) { log.error("File to rename could not be found in [{}].", "tmp-import" + File.separator + exerciseToken); } catch (IOException ioe) { log.error("Error while renaming file: {}", ioe.getMessage()); } - } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/FileService.java b/src/main/java/at/ac/uibk/gitsearch/service/FileService.java index a10ad3e00ecd87a36c128f7f940792023c9e641c..49640ad62d73f43e65d1e40494dff2d9dd1ab8a3 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/FileService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/FileService.java @@ -1,20 +1,19 @@ package at.ac.uibk.gitsearch.service; -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.stereotype.Service; - import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.util.Map; import java.util.concurrent.*; import java.util.stream.Stream; +import org.apache.commons.io.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.stereotype.Service; @Service -public class FileService implements DisposableBean { +public class FileService implements DisposableBean { private final Logger log = LoggerFactory.getLogger(FileService.class); @@ -36,23 +35,26 @@ public class FileService implements DisposableBean { */ public void scheduleForDeletion(Path path, long delayInMinutes) { log.debug("Removing [{}] scheduled for deletion", path.toString()); - ScheduledFuture<?> future = executor.schedule(() -> { - try { - if (Files.exists(path)) { - if (Files.isDirectory(path)) { - log.info("Delete directory {}", path); - FileUtils.deleteDirectory(path.toFile()); - } else { - log.info("Delete file {}", path); - Files.delete(path); + ScheduledFuture<?> future = executor.schedule( + () -> { + try { + if (Files.exists(path)) { + if (Files.isDirectory(path)) { + log.info("Delete directory {}", path); + FileUtils.deleteDirectory(path.toFile()); + } else { + log.info("Delete file {}", path); + Files.delete(path); + } } + futures.remove(path); + } catch (IOException e) { + log.error("Deleting the file " + path + " did not work: {}", e.getMessage()); } - futures.remove(path); - } - catch (IOException e) { - log.error("Deleting the file " + path + " did not work: {}", e.getMessage()); - } - }, delayInMinutes, TimeUnit.MINUTES); + }, + delayInMinutes, + TimeUnit.MINUTES + ); futures.put(path, future); } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/GitlabService.java b/src/main/java/at/ac/uibk/gitsearch/service/GitlabService.java index 992f9428bfb4f1d76b61681efab8aba9e7a5800c..38bb1d4bbb4064e1b96791f4144ac9c8683a4142 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/GitlabService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/GitlabService.java @@ -1,5 +1,8 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; +import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; @@ -17,7 +20,6 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; - import org.apache.commons.io.FileUtils; import org.apache.http.auth.AuthenticationException; import org.codeability.sharing.plugins.api.search.SearchResultDTO; @@ -48,169 +50,167 @@ import org.springframework.stereotype.Service; import org.springframework.util.StreamUtils; import org.springframework.util.StringUtils; -import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; -import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; - /** * Service for accessing git lab backbone * <p> */ @Service public class GitlabService { - - @Autowired - private GitLabRepository gitLabRepository; - @Autowired - private MetaDataRepository metaDataRepository; - @Autowired - protected TokenProvider tokenProvider; - @Autowired - private FileService fileService; - private static final Logger log = LoggerFactory.getLogger(ShoppingBasketService.class); + @Autowired + private GitLabRepository gitLabRepository; + + @Autowired + private MetaDataRepository metaDataRepository; + + @Autowired + protected TokenProvider tokenProvider; + + @Autowired + private FileService fileService; + private static final Logger log = LoggerFactory.getLogger(ShoppingBasketService.class); public Boolean repositoryExists(String projectID) { - try{ - final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()); - final ProjectApi gitLabProjectApi = gitLabApi.getProjectApi(); - return gitLabProjectApi.getProject(projectID) != null;} - catch(GitLabApiException e){ - log.error(e.getMessage(), e); - return false; - } + try { + final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()); + final ProjectApi gitLabProjectApi = gitLabApi.getProjectApi(); + return gitLabProjectApi.getProject(projectID) != null; + } catch (GitLabApiException e) { + log.error(e.getMessage(), e); + return false; + } } /** * returns an authentication of the current user against gitlab, together with groups and access token */ public Authentication getGitLabAuthentication(String name, String oAuth2Token) { - final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(oAuth2Token); - List<Group> groups = Collections.emptyList(); - if (!org.apache.commons.lang3.StringUtils.isEmpty(oAuth2Token)) - try { - groups = gitLabApi.getGroupApi().getGroups(); - } catch (GitLabApiException e) { - log.warn("Cannot read groups for {}", name); - groups = Collections.emptyList(); - } - - Collection<? extends GrantedAuthority> authorities = - groups.stream().map(g -> g.getFullPath()) - .map(SimpleGrantedAuthority::new) - .collect(Collectors.toList()); - - User principal = new User(name,"", authorities); + final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(oAuth2Token); + List<Group> groups = Collections.emptyList(); + if (!org.apache.commons.lang3.StringUtils.isEmpty(oAuth2Token)) try { + groups = gitLabApi.getGroupApi().getGroups(); + } catch (GitLabApiException e) { + log.warn("Cannot read groups for {}", name); + groups = Collections.emptyList(); + } + + Collection<? extends GrantedAuthority> authorities = groups + .stream() + .map(g -> g.getFullPath()) + .map(SimpleGrantedAuthority::new) + .collect(Collectors.toList()); + + User principal = new User(name, "", authorities); final UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(principal, "", authorities); - Map<String, String> detailsMap = new HashMap<>(); - detailsMap.put(TokenProvider.GITLAB_ACCESS_TOKEN, oAuth2Token); - detailsMap.put(TokenProvider.GITLAB_ACCESS_ISSUER, "who cares?"); - authentication.setDetails(detailsMap); - return authentication; - + Map<String, String> detailsMap = new HashMap<>(); + detailsMap.put(TokenProvider.GITLAB_ACCESS_TOKEN, oAuth2Token); + detailsMap.put(TokenProvider.GITLAB_ACCESS_ISSUER, "who cares?"); + authentication.setDetails(detailsMap); + return authentication; + } + + public InputStream getRepositoryZip(String exerciseID) throws GitLabApiException, IOException { + final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()); + return rePackageGitLabProjectZip( + new ZipInputStream(gitLabApi.getRepositoryApi().getRepositoryArchive(exerciseID, "HEAD", "zip")), + "from project " + exerciseID + ); + } + + /** + * chops of the main folder, and brings every file one level up. Also deleting + * all plain files in main folder. + * + * @param zipIn the zip to be repackaged + * @param originalLocation the original location. For debug purposes only. + * @return + * @throws IOException + */ + protected InputStream rePackageGitLabProjectZip(ZipInputStream zipIn, String originalLocation) throws IOException { + final PipedInputStream pis = new PipedInputStream(1024 * 256); + final PipedOutputStream pos = new PipedOutputStream(pis); + + Runnable rePackage = () -> { + try (ZipOutputStream zipOut = new ZipOutputStream(pos)) { + ZipEntry zipInEntry = zipIn.getNextEntry(); + String prefix = ""; + if (zipInEntry.isDirectory()) { // main directory is prefix to all entries + prefix = zipInEntry.getName(); + } + + while (zipInEntry != null) { + if (zipInEntry.getName().startsWith(prefix)) { + String newName = zipInEntry.getName().substring(prefix.length()); + if (StringUtils.hasLength(newName)) { + ZipEntry zipOutEntry = new ZipEntry(newName); + if (zipInEntry.isDirectory()) { + log.debug("ignoring directory {}", zipInEntry.getName()); + zipOut.putNextEntry(zipOutEntry); + } else { + zipOut.putNextEntry(zipOutEntry); + StreamUtils.copy(zipIn, zipOut); + zipOut.closeEntry(); + } + } + } + zipInEntry = zipIn.getNextEntry(); + } + zipIn.close(); + } catch (IOException e) { + log.error("Cannot rezip file from {}", originalLocation); + } + }; + + new Thread(rePackage).start(); + + return pis; } - - - public InputStream getRepositoryZip(String exerciseID) throws GitLabApiException, IOException { - + + /** + * returns the requested file from the project in gitlab. If the user is not enabled for access, but the project is public visible, the file is returned with admin token. + * @param exerciseId + * @param filePath + * @return + * @throws GitLabApiException + * @throws IOException + */ + public InputStream getRepositoryFile(ExerciseId exerciseId, String filePath) throws GitLabApiException, IOException { + final SearchResultDTO exercise = metaDataRepository.getExerciseById(exerciseId, tokenProvider.getCurrentPrincipal()); + if (exercise == null) throw new IOException("Exercise with id " + exerciseId + " not found!"); + final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()); - return rePackageGitLabProjectZip(new ZipInputStream(gitLabApi.getRepositoryApi().getRepositoryArchive(exerciseID, "HEAD", "zip")), "from project " + exerciseID); - } - - /** - * chops of the main folder, and brings every file one level up. Also deleting - * all plain files in main folder. - * - * @param zipIn the zip to be repackaged - * @param originalLocation the original location. For debug purposes only. - * @return - * @throws IOException - */ - protected InputStream rePackageGitLabProjectZip(ZipInputStream zipIn, String originalLocation) throws IOException { - final PipedInputStream pis = new PipedInputStream(1024*256); - final PipedOutputStream pos = new PipedOutputStream(pis); - - Runnable rePackage = () -> { - try (ZipOutputStream zipOut = new ZipOutputStream(pos)) { - - ZipEntry zipInEntry = zipIn.getNextEntry(); - String prefix = ""; - if (zipInEntry.isDirectory()) { // main directory is prefix to all entries - prefix = zipInEntry.getName(); - } - - while (zipInEntry != null) { - if (zipInEntry.getName().startsWith(prefix)) { - String newName = zipInEntry.getName().substring(prefix.length()); - if (StringUtils.hasLength(newName)) { - ZipEntry zipOutEntry = new ZipEntry(newName); - if (zipInEntry.isDirectory()) { - log.debug("ignoring directory {}", zipInEntry.getName()); - zipOut.putNextEntry(zipOutEntry); - } else { - zipOut.putNextEntry(zipOutEntry); - StreamUtils.copy(zipIn, zipOut); - zipOut.closeEntry(); - } - }} - zipInEntry = zipIn.getNextEntry(); - } - zipIn.close(); - } catch (IOException e) { - log.error("Cannot rezip file from {}", originalLocation); - } - }; - - new Thread(rePackage).start(); - - return pis; - - } - - /** - * returns the requested file from the project in gitlab. If the user is not enabled for access, but the project is public visible, the file is returned with admin token. - * @param exerciseId - * @param filePath - * @return - * @throws GitLabApiException - * @throws IOException - */ - public InputStream getRepositoryFile(ExerciseId exerciseId, String filePath) - throws GitLabApiException, IOException { - - final SearchResultDTO exercise = metaDataRepository.getExerciseById(exerciseId, - tokenProvider.getCurrentPrincipal()); - if (exercise == null) - throw new IOException("Exercise with id " + exerciseId + " not found!"); - - final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()); - RepositoryFile file; - try { - file = gitLabApi.getRepositoryFileApi().getFile(exercise.getProject().getProjectId(), - exerciseId.extendPath(filePath), "master"); - } catch (GitLabApiException e) { - log.warn("Cannot read file ", e.getMessage()); - if (exercise.getMetadata().getPublicVisibility() != null - && (!isDisabledPrefix(filePath, exercise.getMetadata().getPublicVisibility().getExcept()))) { - file = gitLabRepository.getAdminGitLabApi().getRepositoryFileApi() - .getFile(exercise.getProject().getProjectId(), exerciseId.extendPath(filePath), "master"); - - } else { - throw new IOException("Access to " + filePath + " not allowed"); - } - } - return new ByteArrayInputStream(file.getDecodedContentAsBytes()); - } - - private boolean isDisabledPrefix(String filePath, String[] exceptions) { - for(String exception: exceptions) { - if(filePath.startsWith(exception) && (filePath.equals(exception) || filePath.charAt(exception.length()+1) == '/')) - return true; - } - return false; - } + RepositoryFile file; + try { + file = + gitLabApi.getRepositoryFileApi().getFile(exercise.getProject().getProjectId(), exerciseId.extendPath(filePath), "master"); + } catch (GitLabApiException e) { + log.warn("Cannot read file ", e.getMessage()); + if ( + exercise.getMetadata().getPublicVisibility() != null && + (!isDisabledPrefix(filePath, exercise.getMetadata().getPublicVisibility().getExcept())) + ) { + file = + gitLabRepository + .getAdminGitLabApi() + .getRepositoryFileApi() + .getFile(exercise.getProject().getProjectId(), exerciseId.extendPath(filePath), "master"); + } else { + throw new IOException("Access to " + filePath + " not allowed"); + } + } + return new ByteArrayInputStream(file.getDecodedContentAsBytes()); + } + + private boolean isDisabledPrefix(String filePath, String[] exceptions) { + for (String exception : exceptions) { + if ( + filePath.startsWith(exception) && (filePath.equals(exception) || filePath.charAt(exception.length() + 1) == '/') + ) return true; + } + return false; + } /** * Creates a new repository in Gitlab and returns the url to it @@ -219,20 +219,17 @@ public class GitlabService { * @return Url (as String) to the repository * @throws GitLabApiException */ - public String createRepository(Group group, String repoName) throws GitLabApiException, ArtemisImportError { + public String createRepository(Group group, String repoName) throws GitLabApiException, ArtemisImportError { final ProjectApi projectApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()).getProjectApi(); try { // If repository already exist, return it return projectApi.getProject(group.getFullPath() + "/" + repoName.replace(" ", "-")).getWebUrl(); } catch (GitLabApiException ignored) { - log.debug("not relevant here" + ignored.getMessage()); + log.debug("not relevant here" + ignored.getMessage()); } - Project project = new Project() - .withNamespaceId(group.getId()) - .withName(repoName) - .withVisibility(Visibility.PUBLIC); + Project project = new Project().withNamespaceId(group.getId()).withName(repoName).withVisibility(Visibility.PUBLIC); try { project = projectApi.createProject(project); @@ -247,7 +244,7 @@ public class GitlabService { public void commitAndPushToRepo(Repository repository, File srcDir) throws IOException, ArtemisImportError { Git git = new Git(repository); - try { + try { final UserApi userApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()).getUserApi(); org.gitlab4j.api.models.User currentUser = userApi.getCurrentUser(); @@ -256,15 +253,15 @@ public class GitlabService { git.commit().setAll(true).setMessage("Importing files").setCommitter(currentUser.getUsername(), currentUser.getEmail()).call(); git.push().setCredentialsProvider(CredentialsProvider.getDefault()).call(); } catch (GitLabApiException | GitAPIException e) { - if (git.getRepository().getDirectory().getParentFile().exists()) { - try { + if (git.getRepository().getDirectory().getParentFile().exists()) { + try { FileUtils.deleteDirectory(git.getRepository().getDirectory().getParentFile()); } catch (IOException ioe) { log.error("Could not remove directory: {} \n", ioe.getMessage()); } } - log.error("An error occurred during the commit and push of files: {}", e.getMessage()); - git.getRepository().close(); + log.error("An error occurred during the commit and push of files: {}", e.getMessage()); + git.getRepository().close(); git.close(); throw new ArtemisImportError("exercise.import.error.pushFailed"); } @@ -298,7 +295,6 @@ public class GitlabService { fileService.scheduleForDeletion(repo.getDirectory().toPath(), 60); return repo; - } catch (GitAPIException e) { log.error("Unable to clone Git repository to temporary directory : {}", e.getMessage()); throw new ArtemisImportError("exercise.import.error.checkoutFailed"); @@ -323,14 +319,18 @@ public class GitlabService { * @return List of all groups * @throws GitLabApiException if an error occurs */ - public List<Group> getGroups() throws GitLabApiException, AuthenticationException { - if (tokenProvider.getGitLabAccessInfo().isEmpty()) { - throw new AuthenticationException(); + public List<Group> getGroups() throws GitLabApiException, AuthenticationException { + if (tokenProvider.getGitLabAccessInfo().isEmpty()) { + throw new AuthenticationException(); } GroupApi groupApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()).getGroupApi(); - User principal = tokenProvider.getCurrentPrincipal().orElseThrow(AuthenticationException::new); - Collection<String> authorities = principal.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList()); + User principal = tokenProvider.getCurrentPrincipal().orElseThrow(AuthenticationException::new); + Collection<String> authorities = principal + .getAuthorities() + .stream() + .map(GrantedAuthority::getAuthority) + .collect(Collectors.toList()); return groupApi.getGroups().stream().filter(group -> authorities.contains(group.getFullPath())).collect(Collectors.toList()); } @@ -348,18 +348,21 @@ public class GitlabService { GroupApi groupApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()).getGroupApi(); Integer userId = userApi.getCurrentUser().getId(); - List<Group> groups = getGroups(); - groups = groups.stream().filter(group -> { - try { - return groupApi.getMember(group.getId(), userId, true).getAccessLevel().value >= 40; - } catch (GitLabApiException e) { - log.warn("Could not retrieve membership of user [{}] for group [{}]. Skipping..", userId, group.getId()); - } - return false; - }).collect(Collectors.toList()); - - return groups; + groups = + groups + .stream() + .filter(group -> { + try { + return groupApi.getMember(group.getId(), userId, true).getAccessLevel().value >= 40; + } catch (GitLabApiException e) { + log.warn("Could not retrieve membership of user [{}] for group [{}]. Skipping..", userId, group.getId()); + } + return false; + }) + .collect(Collectors.toList()); + + return groups; } /** @@ -368,7 +371,7 @@ public class GitlabService { * @return List of subgroups of given group * @throws GitLabApiException if an error occurs */ - public List<Group> getSubGroups(int groupId) throws GitLabApiException { + public List<Group> getSubGroups(int groupId) throws GitLabApiException { GroupApi groupApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()).getGroupApi(); return groupApi.getSubGroups(groupId); @@ -379,12 +382,11 @@ public class GitlabService { * to use the provided OAuth2 token */ public void setJGitDefaultAuth() { - final Optional<String> gitLabAccessToken = tokenProvider.getGitLabAccessToken(); - if (gitLabAccessToken.isPresent()) { - CredentialsProvider.setDefault(new UsernamePasswordCredentialsProvider("oauth2", gitLabAccessToken.get())); - } else { - log.error("Cannot find gitlab token!"); - } + final Optional<String> gitLabAccessToken = tokenProvider.getGitLabAccessToken(); + if (gitLabAccessToken.isPresent()) { + CredentialsProvider.setDefault(new UsernamePasswordCredentialsProvider("oauth2", gitLabAccessToken.get())); + } else { + log.error("Cannot find gitlab token!"); + } } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/LikesQueryService.java b/src/main/java/at/ac/uibk/gitsearch/service/LikesQueryService.java index 0bb270c59b49887e963c671d74ade62b91fd82f0..1d6404d1bcabf49a5bf95a093ec63e5437f7307b 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/LikesQueryService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/LikesQueryService.java @@ -1,7 +1,11 @@ package at.ac.uibk.gitsearch.service; +// for static metamodels +import at.ac.uibk.gitsearch.domain.Likes; +import at.ac.uibk.gitsearch.domain.Likes_; +import at.ac.uibk.gitsearch.repository.LikesRepository; +import at.ac.uibk.gitsearch.service.dto.LikesCriteria; import java.util.List; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -9,12 +13,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -// for static metamodels -import at.ac.uibk.gitsearch.domain.Likes; -import at.ac.uibk.gitsearch.domain.Likes_; -import at.ac.uibk.gitsearch.repository.LikesRepository; -import at.ac.uibk.gitsearch.service.dto.LikesCriteria; import tech.jhipster.service.QueryService; /** diff --git a/src/main/java/at/ac/uibk/gitsearch/service/MailService.java b/src/main/java/at/ac/uibk/gitsearch/service/MailService.java index 122aab1b781af092f7381161f9710f6fa6055a99..29c033acaca251fff2a255a2378d5bbcac47b5d3 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/MailService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/MailService.java @@ -4,8 +4,6 @@ import at.ac.uibk.gitsearch.domain.User; import at.ac.uibk.gitsearch.domain.UserWatchList; import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; import at.ac.uibk.gitsearch.repository.UserRepository; -import tech.jhipster.config.JHipsterProperties; - import java.nio.charset.StandardCharsets; import java.time.Instant; import java.util.List; @@ -13,10 +11,8 @@ import java.util.Locale; import java.util.Map; import java.util.Map.Entry; import java.util.stream.Collectors; - import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; - import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +25,7 @@ import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; import org.thymeleaf.context.Context; import org.thymeleaf.spring5.SpringTemplateEngine; +import tech.jhipster.config.JHipsterProperties; /** * Service for sending emails. @@ -53,13 +50,17 @@ public class MailService { private final SpringTemplateEngine templateEngine; private final UserRepository userRepository; - - private final UserWatchListService userWatchListService; - public MailService(JHipsterProperties jHipsterProperties, JavaMailSender javaMailSender, - MessageSource messageSource, SpringTemplateEngine templateEngine, - UserRepository userRepository, UserWatchListService userWatchListService) { + private final UserWatchListService userWatchListService; + public MailService( + JHipsterProperties jHipsterProperties, + JavaMailSender javaMailSender, + MessageSource messageSource, + SpringTemplateEngine templateEngine, + UserRepository userRepository, + UserWatchListService userWatchListService + ) { this.jHipsterProperties = jHipsterProperties; this.javaMailSender = javaMailSender; this.messageSource = messageSource; @@ -79,8 +80,14 @@ public class MailService { */ @Async public boolean sendEmail(String to, String subject, String content, boolean isMultipart, boolean isHtml) { - log.debug("Send email[multipart '{}' and html '{}'] to '{}' with subject '{}' and content={}", - isMultipart, isHtml, to, subject, content); + log.debug( + "Send email[multipart '{}' and html '{}'] to '{}' with subject '{}' and content={}", + isMultipart, + isHtml, + to, + subject, + content + ); // Prepare message using a Spring helper MimeMessage mimeMessage = javaMailSender.createMimeMessage(); @@ -93,7 +100,7 @@ public class MailService { javaMailSender.send(mimeMessage); log.debug("Sent email to User '{}'", to); return true; - } catch (MailException | MessagingException e) { + } catch (MailException | MessagingException e) { log.warn("Email could not be sent to user '{}'", to, e); return false; } @@ -120,10 +127,9 @@ public class MailService { */ @Scheduled(cron = "0 0 5 * * ?") public void sendInfoMails() { - - for(User user: userRepository.findAll()) { - sendInfoMail(user, false /* only if content */); - } + for (User user : userRepository.findAll()) { + sendInfoMail(user, false/* only if content */); + } } /** @@ -133,54 +139,62 @@ public class MailService { * @param force force mail sending, even if mail is empty. * @return true if mail was sent. */ - public boolean sendInfoMail(User user, boolean force) { - boolean hasContent = force; - Locale locale = Locale.forLanguageTag(user.getLangKey()); - Context context = new Context(locale); - context.setVariable(USER, user); - context.setVariable(BASE_URL, jHipsterProperties.getMail().getBaseUrl()); - Instant lastMailSending = user.getLastMailSent(); - if (lastMailSending == null) { - lastMailSending = user.getLastLogin(); - if (lastMailSending == null) { - lastMailSending = Instant.ofEpochMilli(0); // should only happen during testing - } - user.setLastMailSent(lastMailSending); - user = userRepository.save(user); - } - Map<SearchResultDTO, UserWatchList> findChangesSince = null; - - findChangesSince = userWatchListService.findChangesSince(lastMailSending, user); - - - boolean dailyRelevant = findChangesSince.entrySet().stream().anyMatch(entry -> entry.getValue().getCheckFrequency() == CheckFrequency.DAILY); - boolean weeklyRelevant = findChangesSince.entrySet().stream().anyMatch(entry -> entry.getValue().getCheckFrequency() == CheckFrequency.WEEKLY); - boolean monthlyRelevant = findChangesSince.entrySet().stream().anyMatch(entry -> entry.getValue().getCheckFrequency() == CheckFrequency.MONTHLY); - - boolean shouldSend = - (dailyRelevant && lastMailSending.isBefore(CheckFrequency.DAILY.getChangedBefore())) || - (weeklyRelevant && lastMailSending.isBefore(CheckFrequency.WEEKLY.getChangedBefore())) || - (monthlyRelevant && lastMailSending.isBefore(CheckFrequency.MONTHLY.getChangedBefore())); - - - - hasContent = hasContent || shouldSend; - - if(hasContent) { - final List<Entry<SearchResultDTO, UserWatchList>> changedExercises = findChangesSince.entrySet().stream().collect(Collectors.toList()); - context.setVariable("watchListUpdates", changedExercises); - String content = templateEngine.process("mail/info/infoEmail", context); - String subject = messageSource.getMessage("email.info.title", null, locale); - boolean success = sendEmail(user.getEmail(), subject, content, false, true); - if(success) { - user.setLastMailSent(Instant.now()); - userRepository.save(user); - return true; - } - } - return false; - } - + public boolean sendInfoMail(User user, boolean force) { + boolean hasContent = force; + Locale locale = Locale.forLanguageTag(user.getLangKey()); + Context context = new Context(locale); + context.setVariable(USER, user); + context.setVariable(BASE_URL, jHipsterProperties.getMail().getBaseUrl()); + Instant lastMailSending = user.getLastMailSent(); + if (lastMailSending == null) { + lastMailSending = user.getLastLogin(); + if (lastMailSending == null) { + lastMailSending = Instant.ofEpochMilli(0); // should only happen during testing + } + user.setLastMailSent(lastMailSending); + user = userRepository.save(user); + } + Map<SearchResultDTO, UserWatchList> findChangesSince = null; + + findChangesSince = userWatchListService.findChangesSince(lastMailSending, user); + + boolean dailyRelevant = findChangesSince + .entrySet() + .stream() + .anyMatch(entry -> entry.getValue().getCheckFrequency() == CheckFrequency.DAILY); + boolean weeklyRelevant = findChangesSince + .entrySet() + .stream() + .anyMatch(entry -> entry.getValue().getCheckFrequency() == CheckFrequency.WEEKLY); + boolean monthlyRelevant = findChangesSince + .entrySet() + .stream() + .anyMatch(entry -> entry.getValue().getCheckFrequency() == CheckFrequency.MONTHLY); + + boolean shouldSend = + (dailyRelevant && lastMailSending.isBefore(CheckFrequency.DAILY.getChangedBefore())) || + (weeklyRelevant && lastMailSending.isBefore(CheckFrequency.WEEKLY.getChangedBefore())) || + (monthlyRelevant && lastMailSending.isBefore(CheckFrequency.MONTHLY.getChangedBefore())); + + hasContent = hasContent || shouldSend; + + if (hasContent) { + final List<Entry<SearchResultDTO, UserWatchList>> changedExercises = findChangesSince + .entrySet() + .stream() + .collect(Collectors.toList()); + context.setVariable("watchListUpdates", changedExercises); + String content = templateEngine.process("mail/info/infoEmail", context); + String subject = messageSource.getMessage("email.info.title", null, locale); + boolean success = sendEmail(user.getEmail(), subject, content, false, true); + if (success) { + user.setLastMailSent(Instant.now()); + userRepository.save(user); + return true; + } + } + return false; + } @Async public void sendActivationEmail(User user) { diff --git a/src/main/java/at/ac/uibk/gitsearch/service/MessageService.java b/src/main/java/at/ac/uibk/gitsearch/service/MessageService.java index 6d334b60cc6e17438330d4cf4501ee15d8a8ae77..8201f4a57ccbfaeb26f5f7c4e7425f9ede4ddf67 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/MessageService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/MessageService.java @@ -1,77 +1,71 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; +import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import java.util.Timer; import java.util.TimerTask; - import javax.annotation.PostConstruct; import javax.ws.rs.client.Client; import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; - import org.glassfish.jersey.client.ClientConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; - -import at.ac.uibk.gitsearch.properties.ApplicationProperties; -import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; - /** * this service provides messages. To make things simple, we use gitlab to * manage the (broadcast) messages. - * + * * @author Michael Breu * */ @Service public class MessageService { - private static final Logger log = LoggerFactory.getLogger(MessageService.class); + private static final Logger log = LoggerFactory.getLogger(MessageService.class); + @Autowired + protected ApplicationProperties applicationProperties; - @Autowired - protected ApplicationProperties applicationProperties; + BroadCastMessageDTO[] messages = null; - BroadCastMessageDTO[] messages = null; + public BroadCastMessageDTO[] getMessages() { + return messages; + } - public BroadCastMessageDTO[] getMessages() { - return messages; - } + private static final long PLUGIN_RECHECK_TIMEOUT = 10 * 60 * 1000L; // every 10 Minutes - private static final long PLUGIN_RECHECK_TIMEOUT = 10 * 60 * 1000L; // every 10 Minutes + @PostConstruct + public void startReloadTimer() { + Timer check = new Timer("MessageReloadTimer"); + check.schedule(new MessageLoaderTask(), 0, PLUGIN_RECHECK_TIMEOUT); + } - @PostConstruct - public void startReloadTimer() { - Timer check = new Timer("MessageReloadTimer"); - check.schedule(new MessageLoaderTask(), 0, PLUGIN_RECHECK_TIMEOUT); - } + public class MessageLoaderTask extends TimerTask { - public class MessageLoaderTask extends TimerTask { - public void run() { - - // Unfortunatelly the gitlab API does not yet support fetching of broadcast messages :-( - ClientConfig restClientConfig = new ClientConfig(); - restClientConfig.register(JacksonJsonProvider.class); - Client client = ClientBuilder.newClient(restClientConfig); + public void run() { + // Unfortunatelly the gitlab API does not yet support fetching of broadcast messages :-( + ClientConfig restClientConfig = new ClientConfig(); + restClientConfig.register(JacksonJsonProvider.class); + Client client = ClientBuilder.newClient(restClientConfig); - WebTarget target = client.target(applicationProperties.getGitLab().getUrl() + "/api/v4/broadcast_messages"); - try { - messages = target.request().accept(MediaType.APPLICATION_JSON).get(BroadCastMessageDTO[].class); - } catch (Exception e) { - log.warn("Cannot load broadcast messages from {}", e.getMessage()); - } - } - } - - /** - * this is for testing mainly. - */ - public void triggerReload() { - new MessageLoaderTask().run(); - } + WebTarget target = client.target(applicationProperties.getGitLab().getUrl() + "/api/v4/broadcast_messages"); + try { + messages = target.request().accept(MediaType.APPLICATION_JSON).get(BroadCastMessageDTO[].class); + } catch (Exception e) { + log.warn("Cannot load broadcast messages from {}", e.getMessage()); + } + } + } + /** + * this is for testing mainly. + */ + public void triggerReload() { + new MessageLoaderTask().run(); + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/PluginManagementService.java b/src/main/java/at/ac/uibk/gitsearch/service/PluginManagementService.java index 868ed54793dd6eb723824de4c7061413e00e4f5f..b624921e03f6b2882f7f86beb75502b8219e6f11 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/PluginManagementService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/PluginManagementService.java @@ -1,5 +1,9 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; +import at.ac.uibk.gitsearch.properties.ApplicationProperties.RegisteredConnector; +import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper.ActionWrapper; +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; import java.net.URI; import java.net.URISyntaxException; import java.util.Collection; @@ -11,7 +15,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Timer; import java.util.TimerTask; - import javax.annotation.PostConstruct; import javax.el.ELContext; import javax.el.ExpressionFactory; @@ -23,7 +26,6 @@ import javax.ws.rs.client.ClientBuilder; import javax.ws.rs.client.Invocation.Builder; import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; - import org.apache.commons.lang3.StringUtils; import org.codeability.sharing.plugins.api.SharingPluginConfig; import org.codeability.sharing.plugins.api.SharingPluginConfig.Action; @@ -35,248 +37,240 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; - -import at.ac.uibk.gitsearch.properties.ApplicationProperties; -import at.ac.uibk.gitsearch.properties.ApplicationProperties.RegisteredConnector; -import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper.ActionWrapper; - /** * management services for plugins. - * + * * @author Michael Breu * */ @Service public class PluginManagementService { - private static final String API_BASE_URL_PARAM = "apiBaseUrl"; - private static final String INSTALLATION_NAME_PARAM = "installationName"; - - private final Map<RegisteredConnector, Exception> configFailures = new HashMap<>(); - - private final class PluginCheckTimer extends TimerTask { - private final RegisteredConnector registeredConnector; - - private PluginCheckTimer(RegisteredConnector registeredConnector) { - this.registeredConnector = registeredConnector; - } - - @Override - public void run() { - synchronized (configFailures) { - ClientConfig restClientConfig = new ClientConfig(); - restClientConfig.register(JacksonJsonProvider.class); - Client client = ClientBuilder.newClient(restClientConfig); - - WebTarget target = client.target(registeredConnector.getUrl()) -// .queryParam(ACCESS_TOKEN_PARAM, registeredPlugin.getAccessToken()) - .queryParam(API_BASE_URL_PARAM, applicationProperties.getRegisteredConnectorsCallBackURL()) - .queryParam(INSTALLATION_NAME_PARAM, applicationProperties.getInstallationName()); - SharingPluginConfig config = null; - try { - Builder request = target.request().accept(MediaType.APPLICATION_JSON); - - if(!StringUtils.isEmpty(registeredConnector.getAccessToken())) - request = request.header("Authorization", "Bearer " + registeredConnector.getAccessToken()); - config = request - .get(SharingPluginConfig.class); - registeredPluginConfigs.put(config.pluginName, - new ConnectorConfigWrapper(config, registeredConnector.getUrl())); - configFailures.remove(registeredConnector); - } catch (ProcessingException ce) { - log.warn("Cannot connect to connector at {}: {}", registeredConnector.getUrl(), ce.getMessage()); - configFailures.put(registeredConnector, ce); - } catch (Exception e) { - log.warn("Cannot (re-)load connector at {}", registeredConnector, e.getMessage()); - configFailures.put(registeredConnector, e); - final Iterator<Entry<String, ConnectorConfigWrapper>> pluginIterator = registeredPluginConfigs - .entrySet().iterator(); - while (pluginIterator.hasNext()) { - final Entry<String, ConnectorConfigWrapper> nextEntry = pluginIterator.next(); - if (nextEntry.getValue().getConfigURL().equals(registeredConnector.getUrl())) { - pluginIterator.remove(); - break; - } - } - } - - } - - } - } - - - /** - * this is just a wrapper, to provide a more efficient access to the original - * config. - * - * @author Michael Breu - * - */ - public static class ConnectorConfigWrapper { - - - public static class ActionWrapper { - protected SharingPluginConfig.Action originalAction; - protected ValueExpression filterExpression; - protected PluginActionInfo pluginActionInfo; - - String absoluteActionTransferURL; - - - public ActionWrapper(Action action, ConnectorConfigWrapper plugin) { - super(); - this.originalAction = action; - pluginActionInfo = new PluginActionInfo(plugin.getPluginName(), action.actionId, action.actionName); - - try { - factory.createValueExpression(factory, Boolean.class); - ELContext context = new StandardELContext(factory); - filterExpression = factory.createValueExpression(context, - "${" + originalAction.filterELExpression + "}", Boolean.class); - } catch (Exception e) { - log.error("Cannot parse elExpression {} for pluginAction {}:{} ", originalAction.filterELExpression, - plugin.getPluginName(), action.actionId); - filterExpression = null; - } - - try { - URI actionURI = new URI(action.actionTransferURL); - if (!actionURI.isAbsolute()) { - this.absoluteActionTransferURL = new URI(plugin.getConfigURL()).resolve(actionURI).toASCIIString(); - } - } catch (URISyntaxException e) { - log.error("Cannot asolutize url {} from action {} via {}", action.actionTransferURL, plugin.getConfigURL(), plugin.getPluginName(), e); - } - - - } - - - /** - * @return the absoluteImportServiceURL - */ - public String getAbsoluteActionTransferURL() { - return absoluteActionTransferURL; - } - - - /** - * @return the originalAction - */ - public SharingPluginConfig.Action getOriginalAction() { - return originalAction; - } - - public String getActionId() { - return originalAction.actionId; - } - - public String getActionName() { - return originalAction.actionName; - } - - public PluginActionInfo getPluginActionInfo() { - return pluginActionInfo; - } - - protected static ExpressionFactory factory = ExpressionFactory.newInstance(); - - public boolean isApplicable(final SearchResultDTO hit) { - if (filterExpression == null) - return false; - try { - StandardELContext context = new StandardELContext(factory); - context.getELResolver().setValue(context, null, "metadata", hit.getMetadata()); - return (boolean) filterExpression.getValue(context); - } catch (Exception e) { - log.error("Cannot evaluate elExpression {} for pluginAction {}:{} ", - originalAction.filterELExpression, originalAction.actionId, e); - return false; - } - - } - } - - protected SharingPluginConfig originalConfig; - protected Map<String, ActionWrapper> actions = new HashMap<>(); - protected String configURL; - - public ConnectorConfigWrapper(SharingPluginConfig originalConfig, String configURL) { - super(); - this.originalConfig = originalConfig; - this.configURL = configURL; - actions = new HashMap<>(); - for (Action action : originalConfig.actions) { - actions.put(action.actionId, new ActionWrapper(action, this)); - } - } - - /** - * @return the baseURL - */ - public String getConfigURL() { - return configURL; - } - - public String getPluginName() { - return originalConfig.pluginName; - } - - public Map<String, ActionWrapper> getActions() { - return actions; - } - - } - - @Autowired - private ApplicationProperties applicationProperties; - - private static Map<String, ConnectorConfigWrapper> registeredPluginConfigs = new HashMap<>(); - - private static final Logger log = LoggerFactory.getLogger(PluginManagementService.class); - - private static final long PLUGIN_RECHECK_TIMEOUT = 5 * 60 * 1000L; // every 5 Minutes - - /** - * triggers registration of all plugins after startup. - */ - @PostConstruct - public void registerPlugins() { - List<RegisteredConnector> registeredPlugins = applicationProperties.getRegisteredConnectors(); - - if (registeredPlugins==null) { - log.warn("No Plugins registered?"); - return; - } - - for (RegisteredConnector registeredPlugin : registeredPlugins) { - Timer check = new Timer(registeredPlugin+"-CheckTimer"); - check.schedule(new PluginCheckTimer(registeredPlugin),0L, PLUGIN_RECHECK_TIMEOUT); - } - } - - - public String getRedirectURL(String pluginName, String actionId) { - final ConnectorConfigWrapper sharingPluginConfig = registeredPluginConfigs.get(pluginName); - if (sharingPluginConfig == null) - return null; - final ActionWrapper actionWrapper = sharingPluginConfig.actions.get(actionId); - if (actionWrapper == null) - return null; - return actionWrapper.getAbsoluteActionTransferURL(); - } - - public Collection<ConnectorConfigWrapper> getRegisteredPluginConfigs() { - return registeredPluginConfigs.values(); - } - - /** - * @return the configFailures - */ - public Map<RegisteredConnector, Exception> getConfigFailures() { - return Collections.unmodifiableMap(configFailures); - } - + private static final String API_BASE_URL_PARAM = "apiBaseUrl"; + private static final String INSTALLATION_NAME_PARAM = "installationName"; + + private final Map<RegisteredConnector, Exception> configFailures = new HashMap<>(); + + private final class PluginCheckTimer extends TimerTask { + + private final RegisteredConnector registeredConnector; + + private PluginCheckTimer(RegisteredConnector registeredConnector) { + this.registeredConnector = registeredConnector; + } + + @Override + public void run() { + synchronized (configFailures) { + ClientConfig restClientConfig = new ClientConfig(); + restClientConfig.register(JacksonJsonProvider.class); + Client client = ClientBuilder.newClient(restClientConfig); + + WebTarget target = client + .target(registeredConnector.getUrl()) + // .queryParam(ACCESS_TOKEN_PARAM, registeredPlugin.getAccessToken()) + .queryParam(API_BASE_URL_PARAM, applicationProperties.getRegisteredConnectorsCallBackURL()) + .queryParam(INSTALLATION_NAME_PARAM, applicationProperties.getInstallationName()); + SharingPluginConfig config = null; + try { + Builder request = target.request().accept(MediaType.APPLICATION_JSON); + + if (!StringUtils.isEmpty(registeredConnector.getAccessToken())) request = + request.header("Authorization", "Bearer " + registeredConnector.getAccessToken()); + config = request.get(SharingPluginConfig.class); + registeredPluginConfigs.put(config.pluginName, new ConnectorConfigWrapper(config, registeredConnector.getUrl())); + configFailures.remove(registeredConnector); + } catch (ProcessingException ce) { + log.warn("Cannot connect to connector at {}: {}", registeredConnector.getUrl(), ce.getMessage()); + configFailures.put(registeredConnector, ce); + } catch (Exception e) { + log.warn("Cannot (re-)load connector at {}", registeredConnector, e.getMessage()); + configFailures.put(registeredConnector, e); + final Iterator<Entry<String, ConnectorConfigWrapper>> pluginIterator = registeredPluginConfigs.entrySet().iterator(); + while (pluginIterator.hasNext()) { + final Entry<String, ConnectorConfigWrapper> nextEntry = pluginIterator.next(); + if (nextEntry.getValue().getConfigURL().equals(registeredConnector.getUrl())) { + pluginIterator.remove(); + break; + } + } + } + } + } + } + + /** + * this is just a wrapper, to provide a more efficient access to the original + * config. + * + * @author Michael Breu + * + */ + public static class ConnectorConfigWrapper { + + public static class ActionWrapper { + + protected SharingPluginConfig.Action originalAction; + protected ValueExpression filterExpression; + protected PluginActionInfo pluginActionInfo; + + String absoluteActionTransferURL; + + public ActionWrapper(Action action, ConnectorConfigWrapper plugin) { + super(); + this.originalAction = action; + pluginActionInfo = new PluginActionInfo(plugin.getPluginName(), action.actionId, action.actionName); + + try { + factory.createValueExpression(factory, Boolean.class); + ELContext context = new StandardELContext(factory); + filterExpression = + factory.createValueExpression(context, "${" + originalAction.filterELExpression + "}", Boolean.class); + } catch (Exception e) { + log.error( + "Cannot parse elExpression {} for pluginAction {}:{} ", + originalAction.filterELExpression, + plugin.getPluginName(), + action.actionId + ); + filterExpression = null; + } + + try { + URI actionURI = new URI(action.actionTransferURL); + if (!actionURI.isAbsolute()) { + this.absoluteActionTransferURL = new URI(plugin.getConfigURL()).resolve(actionURI).toASCIIString(); + } + } catch (URISyntaxException e) { + log.error( + "Cannot asolutize url {} from action {} via {}", + action.actionTransferURL, + plugin.getConfigURL(), + plugin.getPluginName(), + e + ); + } + } + + /** + * @return the absoluteImportServiceURL + */ + public String getAbsoluteActionTransferURL() { + return absoluteActionTransferURL; + } + + /** + * @return the originalAction + */ + public SharingPluginConfig.Action getOriginalAction() { + return originalAction; + } + + public String getActionId() { + return originalAction.actionId; + } + + public String getActionName() { + return originalAction.actionName; + } + + public PluginActionInfo getPluginActionInfo() { + return pluginActionInfo; + } + + protected static ExpressionFactory factory = ExpressionFactory.newInstance(); + + public boolean isApplicable(final SearchResultDTO hit) { + if (filterExpression == null) return false; + try { + StandardELContext context = new StandardELContext(factory); + context.getELResolver().setValue(context, null, "metadata", hit.getMetadata()); + return (boolean) filterExpression.getValue(context); + } catch (Exception e) { + log.error( + "Cannot evaluate elExpression {} for pluginAction {}:{} ", + originalAction.filterELExpression, + originalAction.actionId, + e + ); + return false; + } + } + } + + protected SharingPluginConfig originalConfig; + protected Map<String, ActionWrapper> actions = new HashMap<>(); + protected String configURL; + + public ConnectorConfigWrapper(SharingPluginConfig originalConfig, String configURL) { + super(); + this.originalConfig = originalConfig; + this.configURL = configURL; + actions = new HashMap<>(); + for (Action action : originalConfig.actions) { + actions.put(action.actionId, new ActionWrapper(action, this)); + } + } + + /** + * @return the baseURL + */ + public String getConfigURL() { + return configURL; + } + + public String getPluginName() { + return originalConfig.pluginName; + } + + public Map<String, ActionWrapper> getActions() { + return actions; + } + } + + @Autowired + private ApplicationProperties applicationProperties; + + private static Map<String, ConnectorConfigWrapper> registeredPluginConfigs = new HashMap<>(); + + private static final Logger log = LoggerFactory.getLogger(PluginManagementService.class); + + private static final long PLUGIN_RECHECK_TIMEOUT = 5 * 60 * 1000L; // every 5 Minutes + + /** + * triggers registration of all plugins after startup. + */ + @PostConstruct + public void registerPlugins() { + List<RegisteredConnector> registeredPlugins = applicationProperties.getRegisteredConnectors(); + + if (registeredPlugins == null) { + log.warn("No Plugins registered?"); + return; + } + + for (RegisteredConnector registeredPlugin : registeredPlugins) { + Timer check = new Timer(registeredPlugin + "-CheckTimer"); + check.schedule(new PluginCheckTimer(registeredPlugin), 0L, PLUGIN_RECHECK_TIMEOUT); + } + } + + public String getRedirectURL(String pluginName, String actionId) { + final ConnectorConfigWrapper sharingPluginConfig = registeredPluginConfigs.get(pluginName); + if (sharingPluginConfig == null) return null; + final ActionWrapper actionWrapper = sharingPluginConfig.actions.get(actionId); + if (actionWrapper == null) return null; + return actionWrapper.getAbsoluteActionTransferURL(); + } + + public Collection<ConnectorConfigWrapper> getRegisteredPluginConfigs() { + return registeredPluginConfigs.values(); + } + + /** + * @return the configFailures + */ + public Map<RegisteredConnector, Exception> getConfigFailures() { + return Collections.unmodifiableMap(configFailures); + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/SearchService.java b/src/main/java/at/ac/uibk/gitsearch/service/SearchService.java index b4d3dcf9dd10a10a86b904940511916395b34dd4..a0649cde259917df3b1fea913aebd54d64706fda 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/SearchService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/SearchService.java @@ -1,5 +1,11 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; +import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants.AuthoritiesConstantEnum; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider.GitLabAccessInfo; +import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; @@ -13,7 +19,6 @@ import java.util.Optional; import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.zip.ZipInputStream; - import org.codeability.sharing.plugins.api.search.SearchInputDTO; import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.codeability.sharing.plugins.api.search.SearchResultsDTO; @@ -26,13 +31,6 @@ import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Service; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; -import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants.AuthoritiesConstantEnum; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider.GitLabAccessInfo; -import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; - /** * Service for exercise/course search results * <p> @@ -40,16 +38,23 @@ import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; @Service public class SearchService { - private final Logger log = LoggerFactory.getLogger(SearchService.class); + private final Logger log = LoggerFactory.getLogger(SearchService.class); - protected final MetaDataRepository metaDataRepository; - protected final TokenProvider tokenProvider; - protected final GitLabRepository gitLabRepository; + protected final MetaDataRepository metaDataRepository; + protected final TokenProvider tokenProvider; + protected final GitLabRepository gitLabRepository; protected final GitlabService gitlabService; - protected final PluginManagementService pluginManagementService; - protected final ShoppingBasketService shoppingBasketService; - - public SearchService(MetaDataRepository metaDataRepository, TokenProvider tokenProvider, GitLabRepository gitLabRepository, GitlabService gitlabService, PluginManagementService pluginManagementService, ShoppingBasketService shoppingBasketService) { + protected final PluginManagementService pluginManagementService; + protected final ShoppingBasketService shoppingBasketService; + + public SearchService( + MetaDataRepository metaDataRepository, + TokenProvider tokenProvider, + GitLabRepository gitLabRepository, + GitlabService gitlabService, + PluginManagementService pluginManagementService, + ShoppingBasketService shoppingBasketService + ) { this.metaDataRepository = metaDataRepository; this.tokenProvider = tokenProvider; this.gitLabRepository = gitLabRepository; @@ -58,268 +63,298 @@ public class SearchService { this.shoppingBasketService = shoppingBasketService; } - /** - * returns all keyword autocompletes for keyWord - * - * @param keyWordPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getKeywordsAutoComplete(String keyWordPrefix, int max) throws IOException { - return metaDataRepository.getKeywordsAutoComplete(keyWordPrefix, max); - } - - /** - * returns all keyword autocompletes for keyWord - * - * @param formatPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getFormatsAutoComplete(String formatPrefix, int max) throws IOException { - return metaDataRepository.getFormatsAutoComplete(formatPrefix, max); - } - - /** - * returns all creator autocompletes - * - * @param creatorPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getCreatorAutoComplete(String creatorPrefix, int max) throws IOException { - return metaDataRepository.getCreatorAutoComplete(creatorPrefix, max); - } - - /** - * returns all contributor autocompletes - * - * @param contributorPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getContributorAutoComplete(String contributorPrefix, int max) throws IOException { - return metaDataRepository.getContributorAutoComplete(contributorPrefix, max); - } - - /** - * returns all contributor and author autocompletes - * - * @param contributorPrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getContributorCreatorAutoComplete(String contributorPrefix, int max) - throws IOException { - return metaDataRepository.getContributorCreatorAutoComplete(contributorPrefix, max); - } - - /** - * returns all programmingLanguage autocompletes for keyWord - * - * @param programmingLanguagePrefix - * @return - * @throws IOException - */ - public List<AutoCompleteEntry> getProgrammingLanguageAutoComplete(String programmingLanguagePrefix, int max) - throws IOException { - return metaDataRepository.getProgrammingLanguageAutoComplete(programmingLanguagePrefix, max); - } - - /** - * returns the result page - * - * @param searchInput the query definition - */ - public SearchResultsDTO searchResultPage(SearchInputDTO searchInput) throws IOException { - final Optional<User> principal = tokenProvider.getCurrentPrincipal(); - log.debug("Searchrequest for {} ", searchInput); - - final SearchResultsDTO pageDetails = metaDataRepository.pageDetails(searchInput, principal); - - pageDetails.getSearchResult().stream() - .forEach(hit -> pluginManagementService.getRegisteredPluginConfigs().stream() - .forEach(config -> config.getActions().values().stream() - .filter(action -> action.isApplicable(hit)) - .forEach(action -> hit.getSupportedActions().add(action.getPluginActionInfo())))); - pageDetails.getSearchResult().stream().forEach(this::fixImageURL); - pageDetails.getSearchResult() - .forEach(this::filterArtemisActionForUnauthorized); - - return pageDetails; - } - - public SearchResultsDTO searchResultForAuthorEmail(String searchInput, int length) throws IOException { - log.debug("Searchrequest for {} ", searchInput); - - final SearchResultsDTO pageDetails = metaDataRepository.searchByEmail(searchInput, length, - tokenProvider.getCurrentPrincipal()); - - pageDetails.getSearchResult().stream() - .forEach(hit -> pluginManagementService.getRegisteredPluginConfigs().stream() - .forEach(config -> config.getActions().values().stream() - .filter(action -> action.isApplicable(hit)) - .forEach(action -> hit.getSupportedActions().add(action.getPluginActionInfo())))); - pageDetails.getSearchResult().stream().forEach(this::fixImageURL); - - return pageDetails; - } - /** - * returns the result page - * - * @param page the index of the first record to be returned - * @param length the number of records on page - */ - public SearchResultsDTO watchListResultPage(Stream<String> exerciseIds, int page, int length) throws IOException { - - final SearchResultsDTO pageDetails = metaDataRepository.getExercisesById(exerciseIds, - tokenProvider.getCurrentPrincipal(), page, length); - - pageDetails.getSearchResult().stream() - .forEach(hit -> pluginManagementService.getRegisteredPluginConfigs().stream() - .forEach(config -> config.getActions().values().stream() - .filter(action -> action.isApplicable(hit)) - .forEach(action -> hit.getSupportedActions().add(action.getPluginActionInfo())))); - pageDetails.getSearchResult().stream().forEach(this::fixImageURL); - - return pageDetails; - // return readTestResults(searchInput.getFulltextQuery(), first, length); - } - - private void fixImageURL(SearchResultDTO metaData) { - - String image = metaData.getMetadata().getImage(); - - try { - if (image != null) { - URI url = new URI(image); - if (url.isAbsolute()) - return; - String httpUrlToRepo = metaData.getProject().getUrl(); - String baseRepoURL = httpUrlToRepo + "/-/raw/master/"; - final URI resolvedImageUrl = new URI(baseRepoURL).resolve(url); - metaData.getMetadata().setImage(resolvedImageUrl.toASCIIString()); - return; - } - - final String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); - final boolean isJava = metaData.getMetadata().getProgrammingLanguage() != null && Arrays - .stream(metaData.getMetadata().getProgrammingLanguage()).anyMatch(s -> s.startsWith("JAVA")) - && metaData.hashCode() % 2 == 0; // nur um ein wenig Abwechslung zu bekommen :-) - @SuppressWarnings("unused") - final boolean isLatexFormat = metaData.getMetadata().getFormat() != null - && Arrays.stream(metaData.getMetadata().getFormat()).anyMatch(s -> s.startsWith("latex")); - final boolean isPython = metaData.getMetadata().getProgrammingLanguage() != null && Arrays - .stream(metaData.getMetadata().getProgrammingLanguage()).anyMatch(s -> s.startsWith("python")); - if (isJava) { - metaData.getMetadata().setImage(baseUrl + "/content/img/java.png"); - return; - } - // depends on code commented out above -// if (isLatexFormat) { -// metaData.getMetadata().setImage(baseUrl + "/content/img/latex.png"); -// return; -// } - if (isPython) { - metaData.getMetadata().setImage(baseUrl + "/content/img/python.png"); - return; - } - metaData.getMetadata().setImage(baseUrl + "/content/img/gitLab.png"); - return; - - } catch (URISyntaxException e) { - log.warn("Cannot parse image url {} for {}", metaData.getMetadata().getImage(), - metaData.getProject().getUrl()); - } - } - - public File exportExercise(String exerciseId) throws IOException, ParseException { - return exportExercise( ExerciseId.fromString(exerciseId)); - } - public File exportExercise(ExerciseId exerciseId) throws IOException { - try { - final Optional<User> currentPrincipal = tokenProvider.getCurrentPrincipal(); - final SearchResultDTO exercise = metaDataRepository.getExerciseById(exerciseId, - currentPrincipal); - final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()); - // first we try with user credentials! - InputStream repositoryArchive = null; - String[] filter = null; - try { - repositoryArchive = gitLabApi.getRepositoryApi() - .getRepositoryArchive(exercise.getProject().getProject_id(), "HEAD", "zip"); - // if the previous gitlab requests succeeds, the user has full access to the repository. - // no filtering is required - filter = new String[] {}; - } catch (GitLabApiException e) { - // if the previous gitlab throws an exception, we expect, that this is because of permission problems. - // we check for public visibility, and construct the filter from the except array. - log.warn("no access?", e.getMessage()); - if (exercise.getMetadata().getPublicVisibility()!=null) { - repositoryArchive = gitLabRepository.getAdminGitLabApi().getRepositoryApi() - .getRepositoryArchive(exercise.getProject().getProject_id(), "HEAD", "zip"); - filter = exercise.getMetadata().getPublicVisibility().getExcept(); - } else { // throw it further - throw e; - } - - } - InputStream inputFile = shoppingBasketService.rePackageGitLabProjectZip( - new ZipInputStream(repositoryArchive), - "from project " + exerciseId.getProjectId(), - filter, - exerciseId.getPath()); - File file = new File("exercise" + exerciseId.getProjectId() + ".zip"); - - return copyInputStreamToFile(inputFile, file); - } catch (GitLabApiException exception) { - log.error(exception.getMessage()); - return null; - } - } - - private File copyInputStreamToFile(InputStream inputStream, File file) throws IOException { - - // append = false - try (FileOutputStream outputStream = new FileOutputStream(file, false)) { - int read; - byte[] bytes = new byte[8192]; - while ((read = inputStream.read(bytes)) != -1) { - outputStream.write(bytes, 0, read); - } - return file; - } - } - - public Boolean hasAccessToExerciseId(String exerciseId) { - - if (tokenProvider.getCurrentPrincipal().isEmpty()) { - log.warn("Cannot find a principal for for exercise {}", exerciseId); - return false; - } - if (tokenProvider.getCurrentPrincipal().get().getAuthorities() - .contains(AuthoritiesConstantEnum.ADMIN.getGrantedAuthority())) { - log.info("Admin can access everything : {}", exerciseId); - return true; // ADMIN is always allowed - } - SearchResultDTO result = metaDataRepository.getExerciseById(exerciseId, tokenProvider.getCurrentPrincipal()); - if (result == null) { - log.warn("Cannot find exercise for : {}", exerciseId); - return false; - } - return true; - } - - public Optional<SearchResultDTO> findExerciseById(ExerciseId exerciseId) { - try { - SearchResultDTO result = metaDataRepository.getExerciseById(exerciseId.toString(), - tokenProvider.getCurrentPrincipal()); - return Optional.ofNullable(result); - } catch (javax.ws.rs.NotFoundException e) { - log.error("exercise with id {} not found?", exerciseId, e); - return Optional.empty(); - } - } + /** + * returns all keyword autocompletes for keyWord + * + * @param keyWordPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getKeywordsAutoComplete(String keyWordPrefix, int max) throws IOException { + return metaDataRepository.getKeywordsAutoComplete(keyWordPrefix, max); + } + + /** + * returns all keyword autocompletes for keyWord + * + * @param formatPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getFormatsAutoComplete(String formatPrefix, int max) throws IOException { + return metaDataRepository.getFormatsAutoComplete(formatPrefix, max); + } + + /** + * returns all creator autocompletes + * + * @param creatorPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getCreatorAutoComplete(String creatorPrefix, int max) throws IOException { + return metaDataRepository.getCreatorAutoComplete(creatorPrefix, max); + } + + /** + * returns all contributor autocompletes + * + * @param contributorPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getContributorAutoComplete(String contributorPrefix, int max) throws IOException { + return metaDataRepository.getContributorAutoComplete(contributorPrefix, max); + } + + /** + * returns all contributor and author autocompletes + * + * @param contributorPrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getContributorCreatorAutoComplete(String contributorPrefix, int max) throws IOException { + return metaDataRepository.getContributorCreatorAutoComplete(contributorPrefix, max); + } + + /** + * returns all programmingLanguage autocompletes for keyWord + * + * @param programmingLanguagePrefix + * @return + * @throws IOException + */ + public List<AutoCompleteEntry> getProgrammingLanguageAutoComplete(String programmingLanguagePrefix, int max) throws IOException { + return metaDataRepository.getProgrammingLanguageAutoComplete(programmingLanguagePrefix, max); + } + + /** + * returns the result page + * + * @param searchInput the query definition + */ + public SearchResultsDTO searchResultPage(SearchInputDTO searchInput) throws IOException { + final Optional<User> principal = tokenProvider.getCurrentPrincipal(); + log.debug("Searchrequest for {} ", searchInput); + + final SearchResultsDTO pageDetails = metaDataRepository.pageDetails(searchInput, principal); + + pageDetails + .getSearchResult() + .stream() + .forEach(hit -> + pluginManagementService + .getRegisteredPluginConfigs() + .stream() + .forEach(config -> + config + .getActions() + .values() + .stream() + .filter(action -> action.isApplicable(hit)) + .forEach(action -> hit.getSupportedActions().add(action.getPluginActionInfo())) + ) + ); + pageDetails.getSearchResult().stream().forEach(this::fixImageURL); + pageDetails.getSearchResult().forEach(this::filterArtemisActionForUnauthorized); + + return pageDetails; + } + + public SearchResultsDTO searchResultForAuthorEmail(String searchInput, int length) throws IOException { + log.debug("Searchrequest for {} ", searchInput); + + final SearchResultsDTO pageDetails = metaDataRepository.searchByEmail(searchInput, length, tokenProvider.getCurrentPrincipal()); + + pageDetails + .getSearchResult() + .stream() + .forEach(hit -> + pluginManagementService + .getRegisteredPluginConfigs() + .stream() + .forEach(config -> + config + .getActions() + .values() + .stream() + .filter(action -> action.isApplicable(hit)) + .forEach(action -> hit.getSupportedActions().add(action.getPluginActionInfo())) + ) + ); + pageDetails.getSearchResult().stream().forEach(this::fixImageURL); + + return pageDetails; + } + + /** + * returns the result page + * + * @param page the index of the first record to be returned + * @param length the number of records on page + */ + public SearchResultsDTO watchListResultPage(Stream<String> exerciseIds, int page, int length) throws IOException { + final SearchResultsDTO pageDetails = metaDataRepository.getExercisesById( + exerciseIds, + tokenProvider.getCurrentPrincipal(), + page, + length + ); + + pageDetails + .getSearchResult() + .stream() + .forEach(hit -> + pluginManagementService + .getRegisteredPluginConfigs() + .stream() + .forEach(config -> + config + .getActions() + .values() + .stream() + .filter(action -> action.isApplicable(hit)) + .forEach(action -> hit.getSupportedActions().add(action.getPluginActionInfo())) + ) + ); + pageDetails.getSearchResult().stream().forEach(this::fixImageURL); + + return pageDetails; + // return readTestResults(searchInput.getFulltextQuery(), first, length); + } + + private void fixImageURL(SearchResultDTO metaData) { + String image = metaData.getMetadata().getImage(); + + try { + if (image != null) { + URI url = new URI(image); + if (url.isAbsolute()) return; + String httpUrlToRepo = metaData.getProject().getUrl(); + String baseRepoURL = httpUrlToRepo + "/-/raw/master/"; + final URI resolvedImageUrl = new URI(baseRepoURL).resolve(url); + metaData.getMetadata().setImage(resolvedImageUrl.toASCIIString()); + return; + } + + final String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); + final boolean isJava = + metaData.getMetadata().getProgrammingLanguage() != null && + Arrays.stream(metaData.getMetadata().getProgrammingLanguage()).anyMatch(s -> s.startsWith("JAVA")) && + metaData.hashCode() % 2 == 0; // nur um ein wenig Abwechslung zu bekommen :-) + @SuppressWarnings("unused") + final boolean isLatexFormat = + metaData.getMetadata().getFormat() != null && + Arrays.stream(metaData.getMetadata().getFormat()).anyMatch(s -> s.startsWith("latex")); + final boolean isPython = + metaData.getMetadata().getProgrammingLanguage() != null && + Arrays.stream(metaData.getMetadata().getProgrammingLanguage()).anyMatch(s -> s.startsWith("python")); + if (isJava) { + metaData.getMetadata().setImage(baseUrl + "/content/img/java.png"); + return; + } + // depends on code commented out above + // if (isLatexFormat) { + // metaData.getMetadata().setImage(baseUrl + "/content/img/latex.png"); + // return; + // } + if (isPython) { + metaData.getMetadata().setImage(baseUrl + "/content/img/python.png"); + return; + } + metaData.getMetadata().setImage(baseUrl + "/content/img/gitLab.png"); + return; + } catch (URISyntaxException e) { + log.warn("Cannot parse image url {} for {}", metaData.getMetadata().getImage(), metaData.getProject().getUrl()); + } + } + + public File exportExercise(String exerciseId) throws IOException, ParseException { + return exportExercise(ExerciseId.fromString(exerciseId)); + } + + public File exportExercise(ExerciseId exerciseId) throws IOException { + try { + final Optional<User> currentPrincipal = tokenProvider.getCurrentPrincipal(); + final SearchResultDTO exercise = metaDataRepository.getExerciseById(exerciseId, currentPrincipal); + final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo()); + // first we try with user credentials! + InputStream repositoryArchive = null; + String[] filter = null; + try { + repositoryArchive = gitLabApi.getRepositoryApi().getRepositoryArchive(exercise.getProject().getProject_id(), "HEAD", "zip"); + // if the previous gitlab requests succeeds, the user has full access to the repository. + // no filtering is required + filter = new String[] {}; + } catch (GitLabApiException e) { + // if the previous gitlab throws an exception, we expect, that this is because of permission problems. + // we check for public visibility, and construct the filter from the except array. + log.warn("no access?", e.getMessage()); + if (exercise.getMetadata().getPublicVisibility() != null) { + repositoryArchive = + gitLabRepository + .getAdminGitLabApi() + .getRepositoryApi() + .getRepositoryArchive(exercise.getProject().getProject_id(), "HEAD", "zip"); + filter = exercise.getMetadata().getPublicVisibility().getExcept(); + } else { // throw it further + throw e; + } + } + InputStream inputFile = shoppingBasketService.rePackageGitLabProjectZip( + new ZipInputStream(repositoryArchive), + "from project " + exerciseId.getProjectId(), + filter, + exerciseId.getPath() + ); + File file = new File("exercise" + exerciseId.getProjectId() + ".zip"); + + return copyInputStreamToFile(inputFile, file); + } catch (GitLabApiException exception) { + log.error(exception.getMessage()); + return null; + } + } + + private File copyInputStreamToFile(InputStream inputStream, File file) throws IOException { + // append = false + try (FileOutputStream outputStream = new FileOutputStream(file, false)) { + int read; + byte[] bytes = new byte[8192]; + while ((read = inputStream.read(bytes)) != -1) { + outputStream.write(bytes, 0, read); + } + return file; + } + } + + public Boolean hasAccessToExerciseId(String exerciseId) { + if (tokenProvider.getCurrentPrincipal().isEmpty()) { + log.warn("Cannot find a principal for for exercise {}", exerciseId); + return false; + } + if (tokenProvider.getCurrentPrincipal().get().getAuthorities().contains(AuthoritiesConstantEnum.ADMIN.getGrantedAuthority())) { + log.info("Admin can access everything : {}", exerciseId); + return true; // ADMIN is always allowed + } + SearchResultDTO result = metaDataRepository.getExerciseById(exerciseId, tokenProvider.getCurrentPrincipal()); + if (result == null) { + log.warn("Cannot find exercise for : {}", exerciseId); + return false; + } + return true; + } + + public Optional<SearchResultDTO> findExerciseById(ExerciseId exerciseId) { + try { + SearchResultDTO result = metaDataRepository.getExerciseById(exerciseId.toString(), tokenProvider.getCurrentPrincipal()); + return Optional.ofNullable(result); + } catch (javax.ws.rs.NotFoundException e) { + log.error("exercise with id {} not found?", exerciseId, e); + return Optional.empty(); + } + } /** * Method used to filter out the Artemis export action for @@ -336,13 +371,18 @@ public class SearchService { } try { final Optional<GitLabAccessInfo> gitLabAccessInfo = tokenProvider.getGitLabAccessInfo(); - GitLabApi gitLabApi = gitLabRepository.getGitLabApi(gitLabAccessInfo); + GitLabApi gitLabApi = gitLabRepository.getGitLabApi(gitLabAccessInfo); gitLabApi.getRepositoryApi().getRepositoryArchive(result.getProject().getProject_id(), "HEAD", "zip"); } catch (GitLabApiException | NullPointerException e) { // TODO NullPointerException thrown if gitLabAccessInfo.isEmpty(): make it more elegant // We expect permissions missing - result.setSupportedActions(result.getSupportedActions().stream().filter(action -> !action.getPlugin().equals("Artemis Sharing Connector")).collect(Collectors.toList())); + result.setSupportedActions( + result + .getSupportedActions() + .stream() + .filter(action -> !action.getPlugin().equals("Artemis Sharing Connector")) + .collect(Collectors.toList()) + ); } return result; } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/ShoppingBasketService.java b/src/main/java/at/ac/uibk/gitsearch/service/ShoppingBasketService.java index 38fb573d26f4384dabfdccb15aae75d43d8de4ad..548310318a338d52cffe4cfa29e96ba2674ff40e 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/ShoppingBasketService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/ShoppingBasketService.java @@ -1,5 +1,15 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider.GitLabAccessInfo; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import java.io.IOException; import java.io.InputStream; import java.io.PipedInputStream; @@ -12,7 +22,6 @@ import java.util.UUID; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import java.util.zip.ZipOutputStream; - import org.apache.commons.lang3.StringUtils; import org.checkerframework.checker.nullness.qual.Nullable; import org.codeability.sharing.plugins.api.ShoppingBasket; @@ -26,18 +35,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StreamUtils; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; - -import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider.GitLabAccessInfo; - /** * Service for exercise/course search results * <p> @@ -45,368 +42,398 @@ import at.ac.uibk.gitsearch.security.jwt.TokenProvider.GitLabAccessInfo; @Service public class ShoppingBasketService { - @Autowired - private PluginManagementService pluginManagementService; - @Autowired - private GitLabRepository gitLabRepository; - - public static class ShoppingBasketRedirectInfoDTO { - private String redirectURL; - /** - * @return the redirectURL - */ - public String getRedirectURL() { - return redirectURL; - } - /** - * @param redirectURL the redirectURL to set - */ - public void setRedirectURL(String redirectURL) { - this.redirectURL = redirectURL; - } - } - - public static class ShoppingBasketInfoDTO { - private SearchResultDTO[] itemInfos; - private String plugin; - private String action; - - public ShoppingBasketInfoDTO(SearchResultDTO[] itemInfos) { - super(); - this.itemInfos = itemInfos; - } - - public ShoppingBasketInfoDTO() { - // JSON - } - - - - /** - * @return the itemInfos - */ - public SearchResultDTO[] getItemInfos() { - return itemInfos; - } - - /** - * @param itemInfos the itemInfos to set - */ - public void setItemInfos(SearchResultDTO[] itemInfos) { - this.itemInfos = itemInfos; - } - - - - /** - * @return the plugin - */ - public String getPlugin() { - return plugin; - } - - /** - * @param plugin the plugin to set - */ - public void setPlugin(String plugin) { - this.plugin = plugin; - } - - /** - * @return the action - */ - public String getAction() { - return action; - } - - /** - * @param action the action to set - */ - public void setAction(String action) { - this.action = action; - } - - - - public static class ItemInfoDTO { - String exerciseID; - String gitLabURL; - - public ItemInfoDTO(String exerciseID, String gitLabURl) { - super(); - this.exerciseID = exerciseID; - this.gitLabURL = gitLabURl; - } - - public ItemInfoDTO() { - // JSON - } - /** - * @return the exerciseIDs - */ - public String getExerciseID() { - return exerciseID; - } - /** - * @param exerciseIDs the exerciseIDs to set - */ - public void setExerciseID(String exerciseID) { - this.exerciseID = exerciseID; - } - /** - * @return the gitLabURls - */ - public String getGitLabURL() { - return gitLabURL; - } - /** - * @param gitLabURL the gitLabURls to set - */ - public void setGitLabURL(String gitLabURL) { - this.gitLabURL = gitLabURL; - } - } - } - - /** - * holds further info for shopping basket. - * @author Michael Breu - * - */ - public static class ExtendedShoppingBasket { - public ExtendedShoppingBasket(ShoppingBasketInfoDTO shoppingBasket, Optional<GitLabAccessInfo> gitLabAccessInfo, long tokenValidUntil) { - super(); - this.shoppingBasket = shoppingBasket; - this.gitLabAccessInfo = gitLabAccessInfo; - this.tokenValidUntil = tokenValidUntil; - } - public ExtendedShoppingBasket() { - } - - private ShoppingBasketInfoDTO shoppingBasket; - private Optional<GitLabAccessInfo> gitLabAccessInfo; - - - /** - * token valid until (msecs since 1.1.1970) - */ - private long tokenValidUntil; - - /** - * @return the shoppingBasket - */ - public ShoppingBasketInfoDTO getShoppingBasket() { - return shoppingBasket; - } - /** - * @param shoppingBasket the shoppingBasket to set - */ - public void setShoppingBasket(ShoppingBasketInfoDTO shoppingBasket) { - this.shoppingBasket = shoppingBasket; - } - /** - * @return the gitLabAccessInfo - */ - public Optional<GitLabAccessInfo> getGitLabAccessInfo() { - return gitLabAccessInfo; - } - /** - * @param gitLabAccessInfo the gitLabAccessInfo to set - */ - public void setGitLabAccessInfo(Optional<GitLabAccessInfo> gitLabAccessInfo) { - this.gitLabAccessInfo = gitLabAccessInfo; - } - /** - * @return the tokenValidUntil - */ - public long getTokenValidUntil() { - return tokenValidUntil; - } - } - - - private final Logger log = LoggerFactory.getLogger(ShoppingBasketService.class); - - - public ShoppingBasketService() { - // JSON - } - - public ShoppingBasket getBasket(String basketToken) { - if(basketToken==null) { - log.warn("Basket for null not found" ); - return null; - } - final @Nullable ExtendedShoppingBasket basketInfo = basketCache.getIfPresent(basketToken); - if(basketInfo==null) { - log.warn("Basket {} not found", basketToken ); - return null; - } - - List<org.codeability.sharing.plugins.api.search.SearchResultDTO> result = new ArrayList<>(); - for(SearchResultDTO hit: basketInfo.getShoppingBasket().getItemInfos()) { - result.add(convertFrom(hit)); - } - UserInfo userInfo = null; - final Optional<GitLabAccessInfo> gitLabAccessInfo = basketInfo.getGitLabAccessInfo(); - if(gitLabAccessInfo.isPresent() && gitLabAccessInfo.get().getUser().isPresent()) { - userInfo = new UserInfo(gitLabAccessInfo.get().getUser().get().getUsername()); - } - final ShoppingBasket shoppingBasket = new ShoppingBasket(userInfo, result.toArray(new org.codeability.sharing.plugins.api.search.SearchResultDTO[] {}), basketInfo.tokenValidUntil); - log.info("Basket {} is delivered", basketToken ); - return shoppingBasket; - } + @Autowired + private PluginManagementService pluginManagementService; + + @Autowired + private GitLabRepository gitLabRepository; + + public static class ShoppingBasketRedirectInfoDTO { + + private String redirectURL; + + /** + * @return the redirectURL + */ + public String getRedirectURL() { + return redirectURL; + } + + /** + * @param redirectURL the redirectURL to set + */ + public void setRedirectURL(String redirectURL) { + this.redirectURL = redirectURL; + } + } + + public static class ShoppingBasketInfoDTO { + + private SearchResultDTO[] itemInfos; + private String plugin; + private String action; + + public ShoppingBasketInfoDTO(SearchResultDTO[] itemInfos) { + super(); + this.itemInfos = itemInfos; + } + + public ShoppingBasketInfoDTO() { + // JSON + } + + /** + * @return the itemInfos + */ + public SearchResultDTO[] getItemInfos() { + return itemInfos; + } + + /** + * @param itemInfos the itemInfos to set + */ + public void setItemInfos(SearchResultDTO[] itemInfos) { + this.itemInfos = itemInfos; + } + + /** + * @return the plugin + */ + public String getPlugin() { + return plugin; + } + + /** + * @param plugin the plugin to set + */ + public void setPlugin(String plugin) { + this.plugin = plugin; + } + + /** + * @return the action + */ + public String getAction() { + return action; + } + + /** + * @param action the action to set + */ + public void setAction(String action) { + this.action = action; + } + + public static class ItemInfoDTO { + + String exerciseID; + String gitLabURL; + + public ItemInfoDTO(String exerciseID, String gitLabURl) { + super(); + this.exerciseID = exerciseID; + this.gitLabURL = gitLabURl; + } + + public ItemInfoDTO() { + // JSON + } + + /** + * @return the exerciseIDs + */ + public String getExerciseID() { + return exerciseID; + } + + /** + * @param exerciseIDs the exerciseIDs to set + */ + public void setExerciseID(String exerciseID) { + this.exerciseID = exerciseID; + } + + /** + * @return the gitLabURls + */ + public String getGitLabURL() { + return gitLabURL; + } + + /** + * @param gitLabURL the gitLabURls to set + */ + public void setGitLabURL(String gitLabURL) { + this.gitLabURL = gitLabURL; + } + } + } + + /** + * holds further info for shopping basket. + * @author Michael Breu + * + */ + public static class ExtendedShoppingBasket { + + public ExtendedShoppingBasket( + ShoppingBasketInfoDTO shoppingBasket, + Optional<GitLabAccessInfo> gitLabAccessInfo, + long tokenValidUntil + ) { + super(); + this.shoppingBasket = shoppingBasket; + this.gitLabAccessInfo = gitLabAccessInfo; + this.tokenValidUntil = tokenValidUntil; + } + + public ExtendedShoppingBasket() {} + + private ShoppingBasketInfoDTO shoppingBasket; + private Optional<GitLabAccessInfo> gitLabAccessInfo; + + /** + * token valid until (msecs since 1.1.1970) + */ + private long tokenValidUntil; + + /** + * @return the shoppingBasket + */ + public ShoppingBasketInfoDTO getShoppingBasket() { + return shoppingBasket; + } + + /** + * @param shoppingBasket the shoppingBasket to set + */ + public void setShoppingBasket(ShoppingBasketInfoDTO shoppingBasket) { + this.shoppingBasket = shoppingBasket; + } + + /** + * @return the gitLabAccessInfo + */ + public Optional<GitLabAccessInfo> getGitLabAccessInfo() { + return gitLabAccessInfo; + } + + /** + * @param gitLabAccessInfo the gitLabAccessInfo to set + */ + public void setGitLabAccessInfo(Optional<GitLabAccessInfo> gitLabAccessInfo) { + this.gitLabAccessInfo = gitLabAccessInfo; + } + + /** + * @return the tokenValidUntil + */ + public long getTokenValidUntil() { + return tokenValidUntil; + } + } + + private final Logger log = LoggerFactory.getLogger(ShoppingBasketService.class); + + public ShoppingBasketService() { + // JSON + } + + public ShoppingBasket getBasket(String basketToken) { + if (basketToken == null) { + log.warn("Basket for null not found"); + return null; + } + @Nullable + final ExtendedShoppingBasket basketInfo = basketCache.getIfPresent(basketToken); + if (basketInfo == null) { + log.warn("Basket {} not found", basketToken); + return null; + } + + List<org.codeability.sharing.plugins.api.search.SearchResultDTO> result = new ArrayList<>(); + for (SearchResultDTO hit : basketInfo.getShoppingBasket().getItemInfos()) { + result.add(convertFrom(hit)); + } + UserInfo userInfo = null; + final Optional<GitLabAccessInfo> gitLabAccessInfo = basketInfo.getGitLabAccessInfo(); + if (gitLabAccessInfo.isPresent() && gitLabAccessInfo.get().getUser().isPresent()) { + userInfo = new UserInfo(gitLabAccessInfo.get().getUser().get().getUsername()); + } + final ShoppingBasket shoppingBasket = new ShoppingBasket( + userInfo, + result.toArray(new org.codeability.sharing.plugins.api.search.SearchResultDTO[] {}), + basketInfo.tokenValidUntil + ); + log.info("Basket {} is delivered", basketToken); + return shoppingBasket; + } static ObjectMapper objectMapper = new ObjectMapper(); static { - objectMapper.registerModule(new JavaTimeModule()); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + objectMapper.registerModule(new JavaTimeModule()); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } + private org.codeability.sharing.plugins.api.search.SearchResultDTO convertFrom(SearchResultDTO hit) { + try { + return objectMapper.readValue( + objectMapper.writeValueAsString(hit), + org.codeability.sharing.plugins.api.search.SearchResultDTO.class + ); + } catch (JsonMappingException e) { + log.warn("Cannot map hit", e); + return null; + } catch (JsonProcessingException e) { + log.warn("Cannot convert hit", e); + return null; + } + } + + public InputStream getRepositoryZip(String basketToken, int position) throws GitLabApiException, IOException { + @Nullable + final ExtendedShoppingBasket basketInfo = basketCache.getIfPresent(basketToken); + ShoppingBasket basket = getBasket(basketToken); + final GitLabApi gitLabApi = basketInfo == null + ? gitLabRepository.getGitLabApi(Optional.empty()) + : gitLabRepository.getGitLabApi(basketInfo.getGitLabAccessInfo()); + return rePackageGitLabProjectZip( + new ZipInputStream( + gitLabApi.getRepositoryApi().getRepositoryArchive(basket.exerciseInfo[position].getProject().getProjectId(), "HEAD", "zip") + ), + "from project " + basket.exerciseInfo[position].getProject().getProjectId(), + new String[] {}, + null + ); + } - private org.codeability.sharing.plugins.api.search.SearchResultDTO convertFrom(SearchResultDTO hit) { + /** + * chops of the main folder, and brings every file one level up. Also deleting + * all plain files in main folder. + * + * @param zipIn the zip to be repackaged + * @param originalLocation the original location. For debug purposes only. + * @param filterOut an array of file or foldernames that should be filtered away + * @param exerciseFolderPath the path to the exercises + * @return + * @throws IOException + */ + protected InputStream rePackageGitLabProjectZip( + ZipInputStream zipIn, + String originalLocation, + String[] filterOut, + String exerciseFolderPath + ) throws IOException { + final PipedInputStream pis = new PipedInputStream(1024 * 256); + final PipedOutputStream pos = new PipedOutputStream(pis); + + Runnable rePackage = () -> { + try (ZipOutputStream zipOut = new ZipOutputStream(pos)) { + ZipEntry zipInEntry = zipIn.getNextEntry(); + String prefix = ""; + if (zipInEntry.isDirectory()) { // main directory is prefix to all entries + prefix = zipInEntry.getName(); + } + + while (zipInEntry != null) { + String fileName = zipInEntry.getName(); + if (fileName.startsWith(prefix)) { + String newName = fileName.substring(prefix.length()); + String fileWithSubPath = getWithoutPathPrefix(newName, exerciseFolderPath); + if (fileWithSubPath != null) { // process this file + newName = fileWithSubPath; + if (!StringUtils.isEmpty(newName) && !filterOut(newName, filterOut)) { + ZipEntry zipOutEntry = new ZipEntry(newName); + if (zipInEntry.isDirectory()) { + log.debug("ignoring directory {}", fileName); + zipOut.putNextEntry(zipOutEntry); + } else { + zipOut.putNextEntry(zipOutEntry); + StreamUtils.copy(zipIn, zipOut); + zipOut.closeEntry(); + } + } + } + } + zipInEntry = zipIn.getNextEntry(); + } + zipIn.close(); + } catch (IOException e) { + log.error("Cannot rezip file from {}", originalLocation); + } + }; + + new Thread(rePackage).start(); + + return pis; + } - try { - return objectMapper.readValue(objectMapper.writeValueAsString(hit), org.codeability.sharing.plugins.api.search.SearchResultDTO.class); - } catch (JsonMappingException e) { - log.warn("Cannot map hit", e); - return null; - } catch (JsonProcessingException e) { - log.warn("Cannot convert hit", e); - return null; - } - } - - public InputStream getRepositoryZip(String basketToken, int position) throws GitLabApiException, IOException { - final @Nullable ExtendedShoppingBasket basketInfo = basketCache.getIfPresent(basketToken); - ShoppingBasket basket = getBasket(basketToken); - final GitLabApi gitLabApi = basketInfo==null?gitLabRepository.getGitLabApi(Optional.empty()):gitLabRepository.getGitLabApi(basketInfo.getGitLabAccessInfo()); - return rePackageGitLabProjectZip( - new ZipInputStream(gitLabApi.getRepositoryApi().getRepositoryArchive(basket.exerciseInfo[position].getProject().getProjectId(), "HEAD", "zip")), - "from project " + basket.exerciseInfo[position].getProject().getProjectId(), - new String[] {}, - null); - } - - /** - * chops of the main folder, and brings every file one level up. Also deleting - * all plain files in main folder. - * - * @param zipIn the zip to be repackaged - * @param originalLocation the original location. For debug purposes only. - * @param filterOut an array of file or foldernames that should be filtered away - * @param exerciseFolderPath the path to the exercises - * @return - * @throws IOException - */ - protected InputStream rePackageGitLabProjectZip(ZipInputStream zipIn, String originalLocation, String[] filterOut, String exerciseFolderPath) throws IOException { - final PipedInputStream pis = new PipedInputStream(1024*256); - final PipedOutputStream pos = new PipedOutputStream(pis); - - Runnable rePackage = () -> { - try (ZipOutputStream zipOut = new ZipOutputStream(pos)) { - - ZipEntry zipInEntry = zipIn.getNextEntry(); - String prefix = ""; - if (zipInEntry.isDirectory()) { // main directory is prefix to all entries - prefix = zipInEntry.getName(); - } - - while (zipInEntry != null) { - String fileName = zipInEntry.getName(); - if (fileName.startsWith(prefix)) { - String newName = fileName.substring(prefix.length()); - String fileWithSubPath = getWithoutPathPrefix(newName, exerciseFolderPath); - if(fileWithSubPath != null) { // process this file - newName = fileWithSubPath; - if (!StringUtils.isEmpty(newName) && !filterOut(newName, filterOut)) { - ZipEntry zipOutEntry = new ZipEntry(newName); - if (zipInEntry.isDirectory()) { - log.debug("ignoring directory {}", fileName); - zipOut.putNextEntry(zipOutEntry); - } else { - zipOut.putNextEntry(zipOutEntry); - StreamUtils.copy(zipIn, zipOut); - zipOut.closeEntry(); - } - }}} - zipInEntry = zipIn.getNextEntry(); - } - zipIn.close(); - } catch (IOException e) { - log.error("Cannot rezip file from {}", originalLocation); - } - }; - - new Thread(rePackage).start(); - - return pis; - } - - public String getExerciseFolderPath(String exercisesPath) { - if(exercisesPath==null) return ""; - int slashPos = exercisesPath.lastIndexOf('/'); - if(slashPos < 0) return ""; // root metadata - return exercisesPath.substring(0, slashPos); - } - - /** - * shortens the fileName by the pathPrefix. Returns null, if fileName does not start with path prefix. - * @param fileName the file name - * @param pathPrefix the path prefix - * @return - */ - private String getWithoutPathPrefix(String fileName, String pathPrefix) { - if (StringUtils.isEmpty(pathPrefix)) - return fileName; - if (fileName.startsWith(pathPrefix) - && (fileName.length() == pathPrefix.length() || fileName.charAt(pathPrefix.length()) == '/')) { - return fileName.substring(pathPrefix.length() + 1); - } - return null; - } - - private boolean filterOut(String fileName, String[] filterOut) { - for(String filter: filterOut) { - if(fileName.startsWith(filter)) { - return fileName.length() == filter.length() || fileName.charAt(filter.length()) == '/'; - } - } - return false; - } - - public static final Duration BASKET_EXPIRY_INTERVAL = Duration.ofMinutes(60); - /** - * this is a cache for shopping baskets. Entries expires after BASKET_EXPIRY_INTERVAL. - * TODO: Store in Database, to allow multiple application instances. - */ - protected LoadingCache<String, ExtendedShoppingBasket> basketCache = CacheBuilder.newBuilder() - .maximumSize(10000) - .expireAfterWrite(BASKET_EXPIRY_INTERVAL) - .build( - new CacheLoader<String, ExtendedShoppingBasket>() { - public ExtendedShoppingBasket load(String key) { - return null; - } - }); - - public ShoppingBasketRedirectInfoDTO getRedirectInfo(ShoppingBasketInfoDTO basket, String baseURL) { - - UUID random = UUID.randomUUID(); - long tokenValidUntil = System.currentTimeMillis() + BASKET_EXPIRY_INTERVAL.toMillis(); - basketCache.put(random.toString(), new ExtendedShoppingBasket(basket, gitLabRepository.getGitLabAccessInfo(), tokenValidUntil)); - - ShoppingBasketRedirectInfoDTO result = new ShoppingBasketRedirectInfoDTO(); - - result.setRedirectURL( - pluginManagementService.getRedirectURL(basket.getPlugin(), basket.getAction()) - + "/"+random.toString() - + "?returnURL=" + baseURL - + "&apiBaseURL=" + baseURL+"/api/pluginIF/v0.1"); - - return result; - - } + public String getExerciseFolderPath(String exercisesPath) { + if (exercisesPath == null) return ""; + int slashPos = exercisesPath.lastIndexOf('/'); + if (slashPos < 0) return ""; // root metadata + return exercisesPath.substring(0, slashPos); + } + + /** + * shortens the fileName by the pathPrefix. Returns null, if fileName does not start with path prefix. + * @param fileName the file name + * @param pathPrefix the path prefix + * @return + */ + private String getWithoutPathPrefix(String fileName, String pathPrefix) { + if (StringUtils.isEmpty(pathPrefix)) return fileName; + if (fileName.startsWith(pathPrefix) && (fileName.length() == pathPrefix.length() || fileName.charAt(pathPrefix.length()) == '/')) { + return fileName.substring(pathPrefix.length() + 1); + } + return null; + } + private boolean filterOut(String fileName, String[] filterOut) { + for (String filter : filterOut) { + if (fileName.startsWith(filter)) { + return fileName.length() == filter.length() || fileName.charAt(filter.length()) == '/'; + } + } + return false; + } + + public static final Duration BASKET_EXPIRY_INTERVAL = Duration.ofMinutes(60); + /** + * this is a cache for shopping baskets. Entries expires after BASKET_EXPIRY_INTERVAL. + * TODO: Store in Database, to allow multiple application instances. + */ + protected LoadingCache<String, ExtendedShoppingBasket> basketCache = CacheBuilder + .newBuilder() + .maximumSize(10000) + .expireAfterWrite(BASKET_EXPIRY_INTERVAL) + .build( + new CacheLoader<String, ExtendedShoppingBasket>() { + public ExtendedShoppingBasket load(String key) { + return null; + } + } + ); + + public ShoppingBasketRedirectInfoDTO getRedirectInfo(ShoppingBasketInfoDTO basket, String baseURL) { + UUID random = UUID.randomUUID(); + long tokenValidUntil = System.currentTimeMillis() + BASKET_EXPIRY_INTERVAL.toMillis(); + basketCache.put(random.toString(), new ExtendedShoppingBasket(basket, gitLabRepository.getGitLabAccessInfo(), tokenValidUntil)); + + ShoppingBasketRedirectInfoDTO result = new ShoppingBasketRedirectInfoDTO(); + + result.setRedirectURL( + pluginManagementService.getRedirectURL(basket.getPlugin(), basket.getAction()) + + "/" + + random.toString() + + "?returnURL=" + + baseURL + + "&apiBaseURL=" + + baseURL + + "/api/pluginIF/v0.1" + ); + + return result; + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/StatisticsService.java b/src/main/java/at/ac/uibk/gitsearch/service/StatisticsService.java index 785de36732358f34271bcea32ce91f8d66d1ade1..57bab5dd579275c61f3a30da739c8bf5476bb06f 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/StatisticsService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/StatisticsService.java @@ -1,17 +1,14 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; import java.util.Optional; - import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; - /** * Service Interface for managing {@link at.ac.uibk.gitsearch.domain.Statistics}. */ public interface StatisticsService { - /** * Save a statistics. * @@ -28,7 +25,6 @@ public interface StatisticsService { */ Page<StatisticsDTO> findAll(Pageable pageable); - /** * Get the "id" statistics. * @@ -44,16 +40,15 @@ public interface StatisticsService { */ void delete(Long id); -// /** -// * Search for the statistics corresponding to the query. -// * -// * @param query the query of the search. -// * -// * @param pageable the pagination information. -// * @return the list of entities. -// */ -// Page<StatisticsDTO> search(String query, Pageable pageable); + // /** + // * Search for the statistics corresponding to the query. + // * + // * @param query the query of the search. + // * + // * @param pageable the pagination information. + // * @return the list of entities. + // */ + // Page<StatisticsDTO> search(String query, Pageable pageable); Optional<StatisticsDTO> findOneByExerciseID(String id); - } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/UserService.java b/src/main/java/at/ac/uibk/gitsearch/service/UserService.java index 14ef600d0629c4ede38af5c03522529cc55bb04f..e1a844eb76a37bacbfa12244749aad2945e0eed9 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/UserService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/UserService.java @@ -1,5 +1,15 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.config.Constants; +import at.ac.uibk.gitsearch.domain.Authority; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.repository.AuthorityRepository; +import at.ac.uibk.gitsearch.repository.UserRepository; +import at.ac.uibk.gitsearch.repository.search.UserSearchRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.security.SecurityUtils; +import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; +import at.ac.uibk.gitsearch.service.dto.UserDTO; import java.time.Instant; import java.time.temporal.ChronoUnit; import java.util.HashSet; @@ -8,7 +18,6 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.cache.CacheManager; @@ -19,17 +28,6 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - -import at.ac.uibk.gitsearch.config.Constants; -import at.ac.uibk.gitsearch.domain.Authority; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.repository.AuthorityRepository; -import at.ac.uibk.gitsearch.repository.UserRepository; -import at.ac.uibk.gitsearch.repository.search.UserSearchRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.security.SecurityUtils; -import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; -import at.ac.uibk.gitsearch.service.dto.UserDTO; import tech.jhipster.security.RandomUtil; /** @@ -51,7 +49,13 @@ public class UserService { private final CacheManager cacheManager; - public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, UserSearchRepository userSearchRepository, AuthorityRepository authorityRepository, CacheManager cacheManager) { + public UserService( + UserRepository userRepository, + PasswordEncoder passwordEncoder, + UserSearchRepository userSearchRepository, + AuthorityRepository authorityRepository, + CacheManager cacheManager + ) { this.userRepository = userRepository; this.passwordEncoder = passwordEncoder; this.userSearchRepository = userSearchRepository; @@ -61,7 +65,8 @@ public class UserService { public Optional<User> activateRegistration(String key) { log.debug("Activating user for activation key {}", key); - return userRepository.findOneByActivationKey(key) + return userRepository + .findOneByActivationKey(key) .map(user -> { // activate given user for the registration key. user.setActivated(true); @@ -75,7 +80,8 @@ public class UserService { public Optional<User> completePasswordReset(String newPassword, String key) { log.debug("Reset user password for reset key {}", key); - return userRepository.findOneByResetKey(key) + return userRepository + .findOneByResetKey(key) .filter(user -> user.getResetDate().isAfter(Instant.now().minusSeconds(86400))) .map(user -> { user.setPassword(passwordEncoder.encode(newPassword)); @@ -87,7 +93,8 @@ public class UserService { } public Optional<User> requestPasswordReset(String mail) { - return userRepository.findOneByEmailIgnoreCase(mail) + return userRepository + .findOneByEmailIgnoreCase(mail) .filter(User::isActivated) .map(user -> { user.setResetKey(RandomUtil.generateResetKey()); @@ -98,18 +105,22 @@ public class UserService { } public User registerUser(UserDTO userDTO, String password) { - userRepository.findOneByLogin(userDTO.getLogin().toLowerCase()).ifPresent(existingUser -> { - boolean removed = removeNonActivatedUser(existingUser); - if (!removed) { - throw new UsernameAlreadyUsedException(); - } - }); - userRepository.findOneByEmailIgnoreCase(userDTO.getEmail()).ifPresent(existingUser -> { - boolean removed = removeNonActivatedUser(existingUser); - if (!removed) { - throw new EmailAlreadyUsedException(); - } - }); + userRepository + .findOneByLogin(userDTO.getLogin().toLowerCase()) + .ifPresent(existingUser -> { + boolean removed = removeNonActivatedUser(existingUser); + if (!removed) { + throw new UsernameAlreadyUsedException(); + } + }); + userRepository + .findOneByEmailIgnoreCase(userDTO.getEmail()) + .ifPresent(existingUser -> { + boolean removed = removeNonActivatedUser(existingUser); + if (!removed) { + throw new EmailAlreadyUsedException(); + } + }); User newUser = new User(); String encryptedPassword = passwordEncoder.encode(password); newUser.setLogin(userDTO.getLogin().toLowerCase()); @@ -138,7 +149,7 @@ public class UserService { private boolean removeNonActivatedUser(User existingUser) { if (existingUser.isActivated()) { - return false; + return false; } userRepository.delete(existingUser); userRepository.flush(); @@ -170,9 +181,8 @@ public class UserService { final Set<Authority> userAuthorities = userDTO.getAuthorities().stream().map(Authority::new).collect(Collectors.toSet()); // insert new authorities into managedAuthoritiesTable - userAuthorities.stream().filter(auth -> !allAuthorities.contains(auth)) - .forEach(authorityRepository::save); - user.setAuthorities(userAuthorities); + userAuthorities.stream().filter(auth -> !allAuthorities.contains(auth)).forEach(authorityRepository::save); + user.setAuthorities(userAuthorities); } userRepository.save(user); @@ -181,14 +191,13 @@ public class UserService { log.debug("Created Information for User: {}", user); return user; } - /** * cleans up unused authorities every day at 4:30 */ @Scheduled(cron = "0 30 4 * * ?") public void cleanUpUnusedAuthorities() { - authorityRepository.deleteUnusedAuthorities(); + authorityRepository.deleteUnusedAuthorities(); } /** @@ -198,8 +207,8 @@ public class UserService { * @return updated user. */ public Optional<AdminUserDTO> updateUser(AdminUserDTO userDTO) { - return Optional.of(userRepository - .findById(userDTO.getId())) + return Optional + .of(userRepository.findById(userDTO.getId())) .filter(Optional::isPresent) .map(Optional::get) .map(user -> { @@ -214,12 +223,15 @@ public class UserService { user.setActivated(userDTO.isActivated()); user.setLangKey(userDTO.getLangKey()); final List<Authority> allAuthorities = authorityRepository.findAll(); - - final Set<Authority> userAuthorities = userDTO.getAuthorities().stream().map(authString -> new Authority(authString)).collect(Collectors.toSet()); + + final Set<Authority> userAuthorities = userDTO + .getAuthorities() + .stream() + .map(authString -> new Authority(authString)) + .collect(Collectors.toSet()); // insert new authorities into managedAuthoritiesTable - userAuthorities.stream().filter(auth -> !allAuthorities.contains(auth)) - .forEach(auth -> authorityRepository.save(auth)); - user.setAuthorities(userAuthorities); + userAuthorities.stream().filter(auth -> !allAuthorities.contains(auth)).forEach(auth -> authorityRepository.save(auth)); + user.setAuthorities(userAuthorities); userSearchRepository.save(user); this.clearUserCaches(user); log.debug("Changed Information for User: {}", user); @@ -229,12 +241,14 @@ public class UserService { } public void deleteUser(String login) { - userRepository.findOneByLogin(login).ifPresent(user -> { - userRepository.delete(user); - userSearchRepository.delete(user); - this.clearUserCaches(user); - log.debug("Deleted User: {}", user); - }); + userRepository + .findOneByLogin(login) + .ifPresent(user -> { + userRepository.delete(user); + userSearchRepository.delete(user); + this.clearUserCaches(user); + log.debug("Deleted User: {}", user); + }); } /** @@ -247,7 +261,8 @@ public class UserService { * @param imageUrl image URL of user. */ public void updateUser(String firstName, String lastName, String email, String langKey, String imageUrl) { - SecurityUtils.getCurrentUserLogin() + SecurityUtils + .getCurrentUserLogin() .flatMap(userRepository::findOneByLogin) .ifPresent(user -> { user.setFirstName(firstName); @@ -263,10 +278,10 @@ public class UserService { }); } - @Transactional public void changePassword(String currentClearTextPassword, String newPassword) { - SecurityUtils.getCurrentUserLogin() + SecurityUtils + .getCurrentUserLogin() .flatMap(userRepository::findOneByLogin) .ifPresent(user -> { String currentEncryptedPassword = user.getPassword(); @@ -325,19 +340,19 @@ public class UserService { public List<String> getAuthorities() { return authorityRepository.findAll().stream().map(Authority::getName).collect(Collectors.toList()); } - + public void updateLastLogin(Long userId) { - final User user = userRepository.getById(userId); - user.setLastLogin(Instant.now()); - userRepository.save(user); + final User user = userRepository.getById(userId); + user.setLastLogin(Instant.now()); + userRepository.save(user); } public void updateLastLogin(String userName) { - final Optional<User> userO = userRepository.findOneByLogin(userName); - userO.ifPresent(user -> { - user.setLastLogin(Instant.now()); - userRepository.save(user); - }); + final Optional<User> userO = userRepository.findOneByLogin(userName); + userO.ifPresent(user -> { + user.setLastLogin(Instant.now()); + userRepository.save(user); + }); } private void clearUserCaches(User user) { @@ -346,21 +361,21 @@ public class UserService { Objects.requireNonNull(cacheManager.getCache(UserRepository.USERS_BY_EMAIL_CACHE)).evict(user.getEmail()); } } - + public org.springframework.security.core.userdetails.User convertToSecurityUser(User u) { - return new org.springframework.security.core.userdetails.User(u.getLogin(), "unusedPassword", - u.getAuthorities().stream().map(auth -> new SimpleGrantedAuthority(auth.getName())). - collect(Collectors.toList()) - ); + return new org.springframework.security.core.userdetails.User( + u.getLogin(), + "unusedPassword", + u.getAuthorities().stream().map(auth -> new SimpleGrantedAuthority(auth.getName())).collect(Collectors.toList()) + ); } - + public Optional<org.springframework.security.core.userdetails.User> convertToSecurityUser(Optional<User> u) { - return u.map(this::convertToSecurityUser); + return u.map(this::convertToSecurityUser); } - + @Transactional(readOnly = true) public Page<UserDTO> getAllPublicUsers(Pageable pageable) { return userRepository.findAllByIdNotNullAndActivatedIsTrue(pageable).map(UserDTO::new); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/UserWatchListQueryService.java b/src/main/java/at/ac/uibk/gitsearch/service/UserWatchListQueryService.java index f16c5733d2bcc0087084a07839a110449d851bec..182f98a8966ae7c0ad2d3c63302d5c1a5f5cdb81 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/UserWatchListQueryService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/UserWatchListQueryService.java @@ -1,9 +1,13 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.domain.*; // for static metamodels +import at.ac.uibk.gitsearch.domain.UserWatchList; +import at.ac.uibk.gitsearch.repository.UserWatchListRepository; +import at.ac.uibk.gitsearch.service.dto.UserWatchListCriteria; +import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; +import at.ac.uibk.gitsearch.service.mapper.UserWatchListMapper; import java.util.List; - import javax.persistence.criteria.JoinType; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -11,16 +15,8 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; - import tech.jhipster.service.QueryService; -import at.ac.uibk.gitsearch.domain.UserWatchList; -import at.ac.uibk.gitsearch.domain.*; // for static metamodels -import at.ac.uibk.gitsearch.repository.UserWatchListRepository; -import at.ac.uibk.gitsearch.service.dto.UserWatchListCriteria; -import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; -import at.ac.uibk.gitsearch.service.mapper.UserWatchListMapper; - /** * Service for executing complex queries for {@link UserWatchList} entities in the database. * The main input is a {@link UserWatchListCriteria} which gets converted to {@link Specification}, @@ -64,8 +60,7 @@ public class UserWatchListQueryService extends QueryService<UserWatchList> { public Page<UserWatchListDTO> findByCriteria(UserWatchListCriteria criteria, Pageable page) { log.debug("find by criteria : {}, page: {}", criteria, page); final Specification<UserWatchList> specification = createSpecification(criteria); - return userWatchListRepository.findAll(specification, page) - .map(userWatchListMapper::toDto); + return userWatchListRepository.findAll(specification, page).map(userWatchListMapper::toDto); } /** @@ -98,8 +93,10 @@ public class UserWatchListQueryService extends QueryService<UserWatchList> { specification = specification.and(buildSpecification(criteria.getCheckFrequency(), UserWatchList_.checkFrequency)); } if (criteria.getUserId() != null) { - specification = specification.and(buildSpecification(criteria.getUserId(), - root -> root.join(UserWatchList_.user, JoinType.LEFT).get(User_.id))); + specification = + specification.and( + buildSpecification(criteria.getUserId(), root -> root.join(UserWatchList_.user, JoinType.LEFT).get(User_.id)) + ); } } return specification; diff --git a/src/main/java/at/ac/uibk/gitsearch/service/UserWatchListService.java b/src/main/java/at/ac/uibk/gitsearch/service/UserWatchListService.java index 74588573941746bef334ea8046d2b2e986d5b9bc..9cf74014576cd62dd62a61a74f8e7bcdcdd3a41f 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/UserWatchListService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/UserWatchListService.java @@ -1,12 +1,21 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.domain.UserWatchList; +import at.ac.uibk.gitsearch.domain.WatchListEntry; +import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; +import at.ac.uibk.gitsearch.repository.UserWatchListRepository; +import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants.AuthoritiesConstantEnum; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; +import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; +import at.ac.uibk.gitsearch.service.mapper.UserWatchListMapper; +import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import java.time.Instant; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; - import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,17 +27,6 @@ import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.domain.UserWatchList; -import at.ac.uibk.gitsearch.domain.WatchListEntry; -import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; -import at.ac.uibk.gitsearch.repository.UserWatchListRepository; -import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants.AuthoritiesConstantEnum; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; -import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; -import at.ac.uibk.gitsearch.service.mapper.UserWatchListMapper; -import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; - /** * Service Implementation for managing {@link UserWatchList}. */ @@ -43,14 +41,18 @@ public class UserWatchListService { private final UserWatchListMapper userWatchListMapper; private final TokenProvider tokenProvider; - + private final UserService userService; - + private final MetaDataRepository metaDataRepository; - public UserWatchListService(UserWatchListRepository userWatchListRepository, UserWatchListMapper userWatchListMapper, - TokenProvider tokenProvider, MetaDataRepository metaDataRepository, - UserService userService) { + public UserWatchListService( + UserWatchListRepository userWatchListRepository, + UserWatchListMapper userWatchListMapper, + TokenProvider tokenProvider, + MetaDataRepository metaDataRepository, + UserService userService + ) { this.userWatchListRepository = userWatchListRepository; this.userWatchListMapper = userWatchListMapper; this.tokenProvider = tokenProvider; @@ -65,29 +67,29 @@ public class UserWatchListService { * @param mustExist if true, access fails if not existing * @throws BadRequestAlertException if access not allowed */ - public Optional<UserWatchListDTO> checkAccessToWatchList(final Long watchlistId, final String description, boolean mustExist) throws IllegalAccessError { - final Optional<User> currentPrincipal = tokenProvider.getCurrentPrincipal(); - if(currentPrincipal.isEmpty()) { - log.warn("Cannot find a principal for watchlist {} for exercise {}", watchlistId, description); + public Optional<UserWatchListDTO> checkAccessToWatchList(final Long watchlistId, final String description, boolean mustExist) + throws IllegalAccessError { + final Optional<User> currentPrincipal = tokenProvider.getCurrentPrincipal(); + if (currentPrincipal.isEmpty()) { + log.warn("Cannot find a principal for watchlist {} for exercise {}", watchlistId, description); throw new IllegalAccessError("Cannot find a principal"); - } - final Optional<UserWatchListDTO> watchListO = findOne(watchlistId); - if(currentPrincipal.get().getAuthorities().contains(AuthoritiesConstantEnum.ADMIN.getGrantedAuthority())) { - return watchListO; // ADMIN is always allowed - } - if(watchListO.isEmpty() && mustExist) { - log.warn("Cannot find watchlist for : {} for exercise {}", watchlistId, description); + } + final Optional<UserWatchListDTO> watchListO = findOne(watchlistId); + if (currentPrincipal.get().getAuthorities().contains(AuthoritiesConstantEnum.ADMIN.getGrantedAuthority())) { + return watchListO; // ADMIN is always allowed + } + if (watchListO.isEmpty() && mustExist) { + log.warn("Cannot find watchlist for : {} for exercise {}", watchlistId, description); throw new IllegalAccessError("Cannot find watchlist"); - } - if(!mustExist) - return Optional.empty(); - final boolean isAccessible = watchListO.get().getUserLogin().equals(currentPrincipal.get().getUsername()); - if(!isAccessible) { - log.warn("watchlist {} does not belong to current user", watchListO.get().getName()); + } + if (!mustExist) return Optional.empty(); + final boolean isAccessible = watchListO.get().getUserLogin().equals(currentPrincipal.get().getUsername()); + if (!isAccessible) { + log.warn("watchlist {} does not belong to current user", watchListO.get().getName()); throw new IllegalAccessError("watchlist does not belong to current User"); - } - return watchListO; // ADMIN is always allowed - } + } + return watchListO; // ADMIN is always allowed + } /** * Save a userWatchList. @@ -96,12 +98,13 @@ public class UserWatchListService { * @return the persisted entity. */ public UserWatchListDTO save(UserWatchListDTO userWatchListDTO) { - - Optional<UserWatchList> previous = userWatchListDTO.getId()!=null?userWatchListRepository.findById(userWatchListDTO.getId()):Optional.empty(); + Optional<UserWatchList> previous = userWatchListDTO.getId() != null + ? userWatchListRepository.findById(userWatchListDTO.getId()) + : Optional.empty(); log.debug("Request to save UserWatchList : {}", userWatchListDTO); UserWatchList userWatchList = userWatchListMapper.toEntity(userWatchListDTO); - if(previous.isPresent()) { - userWatchList.setWatchListEntries(previous.get().getWatchListEntries()); + if (previous.isPresent()) { + userWatchList.setWatchListEntries(previous.get().getWatchListEntries()); } userWatchList = userWatchListRepository.save(userWatchList); UserWatchListDTO result = userWatchListMapper.toDto(userWatchList); @@ -117,8 +120,7 @@ public class UserWatchListService { @Transactional(readOnly = true) public Page<UserWatchListDTO> findAll(Pageable pageable) { log.debug("Request to get all UserWatchLists"); - return userWatchListRepository.findAll(pageable) - .map(userWatchListMapper::toDto); + return userWatchListRepository.findAll(pageable).map(userWatchListMapper::toDto); } /** @@ -130,11 +132,9 @@ public class UserWatchListService { @Transactional(readOnly = true) public List<UserWatchListDTO> findByUserIdIsCurrentUser() { log.debug("Request to get all UserWatchLists"); - return userWatchListRepository.findByUserIsCurrentUser().stream() - .map(userWatchListMapper::toDto).collect(Collectors.toList()); + return userWatchListRepository.findByUserIsCurrentUser().stream().map(userWatchListMapper::toDto).collect(Collectors.toList()); } - /** * Get one userWatchList by id. * @@ -144,8 +144,7 @@ public class UserWatchListService { @Transactional(readOnly = true) public Optional<UserWatchListDTO> findOne(Long id) { log.debug("Request to get UserWatchList : {}", id); - return userWatchListRepository.findById(id) - .map(userWatchListMapper::toDto); + return userWatchListRepository.findById(id).map(userWatchListMapper::toDto); } /** @@ -168,10 +167,13 @@ public class UserWatchListService { @Transactional(readOnly = true) public Page<UserWatchListDTO> search(String query, Pageable pageable) { log.debug("Request to search for a page of UserWatchLists for query {}", query); - final List<Sort.Order> cleanSortOrder = pageable.getSort().get().filter(order -> !order.getProperty().equals( "_score")).collect(Collectors.toList()); + final List<Sort.Order> cleanSortOrder = pageable + .getSort() + .get() + .filter(order -> !order.getProperty().equals("_score")) + .collect(Collectors.toList()); Pageable cleanedPageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(cleanSortOrder)); - return userWatchListRepository.search(query, cleanedPageRequest) - .map(userWatchListMapper::toDto); + return userWatchListRepository.search(query, cleanedPageRequest).map(userWatchListMapper::toDto); } /** @@ -184,41 +186,53 @@ public class UserWatchListService { @Transactional(readOnly = true) public Page<UserWatchListDTO> searchForCurrentUser(String query, Pageable pageable) { log.debug("Request to search for a page of CurrentUserWatchLists for query {}", query); - final List<Sort.Order> cleanSortOrder = pageable.getSort().get().filter(order -> !order.getProperty().equals( "_score")).collect(Collectors.toList()); + final List<Sort.Order> cleanSortOrder = pageable + .getSort() + .get() + .filter(order -> !order.getProperty().equals("_score")) + .collect(Collectors.toList()); Pageable cleanedPageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(), Sort.by(cleanSortOrder)); - return userWatchListRepository.searchForCurrentUser(query, cleanedPageRequest) - .map(userWatchListMapper::toDto); + return userWatchListRepository.searchForCurrentUser(query, cleanedPageRequest).map(userWatchListMapper::toDto); } - + public List<UserWatchList> findByUser(at.ac.uibk.gitsearch.domain.User user) { - return userWatchListRepository.findByUser(user); + return userWatchListRepository.findByUser(user); } - + /** - * find all SearchResultDTO that are watched by some stored Watchlist, and + * find all SearchResultDTO that are watched by some stored Watchlist, and * @param since * @param user * @return */ public Map<SearchResultDTO, UserWatchList> findChangesSince(Instant since, at.ac.uibk.gitsearch.domain.User user) { - Map<SearchResultDTO, UserWatchList> result = new HashMap<>(); - findByUser(user).stream() - .filter(wl -> wl.getCheckFrequency() != CheckFrequency.NEVER) - .forEach(wl -> - metaDataRepository.getExercisesById(wl.getWatchListEntries().stream().map( WatchListEntry::getExerciseId ) , - userService.convertToSecurityUser(Optional.of(user)), 0, 100, since). - getSearchResult().forEach( - sr -> { - UserWatchList previousWatchList = result.get(sr); - if( previousWatchList == null || // none found or - previousWatchList.getCheckFrequency().ordinal() > wl.getCheckFrequency().ordinal()) { // earlier - result.put(sr, wl); - } - } - )); - return result; + Map<SearchResultDTO, UserWatchList> result = new HashMap<>(); + findByUser(user) + .stream() + .filter(wl -> wl.getCheckFrequency() != CheckFrequency.NEVER) + .forEach(wl -> + metaDataRepository + .getExercisesById( + wl.getWatchListEntries().stream().map(WatchListEntry::getExerciseId), + userService.convertToSecurityUser(Optional.of(user)), + 0, + 100, + since + ) + .getSearchResult() + .forEach(sr -> { + UserWatchList previousWatchList = result.get(sr); + if ( + previousWatchList == null || // none found or + previousWatchList.getCheckFrequency().ordinal() > wl.getCheckFrequency().ordinal() + ) { // earlier + result.put(sr, wl); + } + }) + ); + return result; } - + /** * not really useful. * @param checkFrequency @@ -226,11 +240,11 @@ public class UserWatchListService { * @return */ public Map<SearchResultDTO, UserWatchList> findChangesSince(CheckFrequency checkFrequency, at.ac.uibk.gitsearch.domain.User user) { - Map<SearchResultDTO, UserWatchList> changesSince = findChangesSince(checkFrequency.getChangedBefore(), user); - return changesSince.entrySet().stream(). - filter(entry -> entry.getValue().getCheckFrequency().ordinal() <= checkFrequency.ordinal()) - .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue())); - + Map<SearchResultDTO, UserWatchList> changesSince = findChangesSince(checkFrequency.getChangedBefore(), user); + return changesSince + .entrySet() + .stream() + .filter(entry -> entry.getValue().getCheckFrequency().ordinal() <= checkFrequency.ordinal()) + .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue())); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/WatchListEntryService.java b/src/main/java/at/ac/uibk/gitsearch/service/WatchListEntryService.java index a1130750e6bbc0448d3ed4b6789c2bc9e744e166..0b2d8b06499e4dc61679852039bd09ded203a5d7 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/WatchListEntryService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/WatchListEntryService.java @@ -1,8 +1,13 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.domain.WatchListEntry; +import at.ac.uibk.gitsearch.repository.UserWatchListRepository; +import at.ac.uibk.gitsearch.repository.WatchListEntryRepository; +import at.ac.uibk.gitsearch.repository.search.WatchListEntrySearchRepository; +import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; +import at.ac.uibk.gitsearch.service.mapper.WatchListEntryMapper; import java.util.List; import java.util.Optional; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -10,13 +15,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.domain.WatchListEntry; -import at.ac.uibk.gitsearch.repository.UserWatchListRepository; -import at.ac.uibk.gitsearch.repository.WatchListEntryRepository; -import at.ac.uibk.gitsearch.repository.search.WatchListEntrySearchRepository; -import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; -import at.ac.uibk.gitsearch.service.mapper.WatchListEntryMapper; - /** * Service Implementation for managing {@link WatchListEntry}. */ @@ -27,17 +25,20 @@ public class WatchListEntryService { private final Logger log = LoggerFactory.getLogger(WatchListEntryService.class); private final WatchListEntryRepository watchListEntryRepository; + @SuppressWarnings("unused") - private final UserWatchListRepository userWatchListRepository; + private final UserWatchListRepository userWatchListRepository; private final WatchListEntryMapper watchListEntryMapper; private final WatchListEntrySearchRepository watchListEntrySearchRepository; - public WatchListEntryService(WatchListEntryRepository watchListEntryRepository, - UserWatchListRepository userWatchListRepository, - WatchListEntryMapper watchListEntryMapper, - WatchListEntrySearchRepository watchListEntrySearchRepository) { + public WatchListEntryService( + WatchListEntryRepository watchListEntryRepository, + UserWatchListRepository userWatchListRepository, + WatchListEntryMapper watchListEntryMapper, + WatchListEntrySearchRepository watchListEntrySearchRepository + ) { this.watchListEntryRepository = watchListEntryRepository; this.watchListEntryMapper = watchListEntryMapper; this.watchListEntrySearchRepository = watchListEntrySearchRepository; @@ -68,11 +69,9 @@ public class WatchListEntryService { @Transactional(readOnly = true) public Page<WatchListEntryDTO> findAll(Pageable pageable) { log.debug("Request to get all WatchListEntries"); - return watchListEntryRepository.findAll(pageable) - .map(watchListEntryMapper::toDto); + return watchListEntryRepository.findAll(pageable).map(watchListEntryMapper::toDto); } - /** * Get one watchListEntry by id. * @@ -82,8 +81,7 @@ public class WatchListEntryService { @Transactional(readOnly = true) public Optional<WatchListEntryDTO> findOne(Long id) { log.debug("Request to get WatchListEntry : {}", id); - return watchListEntryRepository.findById(id) - .map(watchListEntryMapper::toDto); + return watchListEntryRepository.findById(id).map(watchListEntryMapper::toDto); } /** @@ -103,23 +101,24 @@ public class WatchListEntryService { * @param id the id of the entity. */ public void deleteInWatchlist(Long watchListId, String exerciseId) { - final List<WatchListEntry> entries = watchListEntryRepository.getEntriesByWatchlistAndExerciseId(watchListId, exerciseId); - entries.forEach(en -> delete(en.getId())); + final List<WatchListEntry> entries = watchListEntryRepository.getEntriesByWatchlistAndExerciseId(watchListId, exerciseId); + entries.forEach(en -> delete(en.getId())); } -// /** -// * Search for the watchListEntry corresponding to the query. -// * -// * @param query the query of the search. -// * @param pageable the pagination information. -// * @return the list of entities. -// */ -// @Transactional(readOnly = true) -// public Page<WatchListEntryDTO> search(String query, Pageable pageable) { -// log.debug("Request to search for a page of WatchListEntries for query {}", query); -// return watchListEntrySearchRepository.search(queryStringQuery(query), pageable) -// .map(watchListEntryMapper::toDto); -// } -// + + // /** + // * Search for the watchListEntry corresponding to the query. + // * + // * @param query the query of the search. + // * @param pageable the pagination information. + // * @return the list of entities. + // */ + // @Transactional(readOnly = true) + // public Page<WatchListEntryDTO> search(String query, Pageable pageable) { + // log.debug("Request to search for a page of WatchListEntries for query {}", query); + // return watchListEntrySearchRepository.search(queryStringQuery(query), pageable) + // .map(watchListEntryMapper::toDto); + // } + // /** * Search for the watchListEntry for a watchlist. * @@ -131,5 +130,4 @@ public class WatchListEntryService { public List<WatchListEntryDTO> getEntriesForWatchlist(Long watchlistId) { return watchListEntryMapper.toDto(watchListEntryRepository.getEntriesByWatchlist(watchlistId)); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/AutoCompleteEntry.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/AutoCompleteEntry.java index a7e82618c3af5e27ddc87b31a10ed5372d451b35..c9c28eaebf1f72f8d5008c5b22d88c00b123feab 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/AutoCompleteEntry.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/AutoCompleteEntry.java @@ -6,40 +6,41 @@ package at.ac.uibk.gitsearch.service.dto; * */ public class AutoCompleteEntry { - private String target; - private int hitCount; - - public AutoCompleteEntry(String target, int hitCount) { - super(); - this.target = target; - this.hitCount = hitCount; - } - - public AutoCompleteEntry(String target) { - super(); - this.target = target; - this.hitCount = 1; - } - - public AutoCompleteEntry() { - // JSON - } - - public void increaseHitCount() { - this.hitCount++; - } - - /** - * @return the target - */ - public String getTarget() { - return target; - } - /** - * @return the hitCount - */ - public int getHitCount() { - return hitCount; - } - -} \ No newline at end of file + + private String target; + private int hitCount; + + public AutoCompleteEntry(String target, int hitCount) { + super(); + this.target = target; + this.hitCount = hitCount; + } + + public AutoCompleteEntry(String target) { + super(); + this.target = target; + this.hitCount = 1; + } + + public AutoCompleteEntry() { + // JSON + } + + public void increaseHitCount() { + this.hitCount++; + } + + /** + * @return the target + */ + public String getTarget() { + return target; + } + + /** + * @return the hitCount + */ + public int getHitCount() { + return hitCount; + } +} diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/BroadCastMessageDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/BroadCastMessageDTO.java index 85ef0c813cc7919a9098da0d6361c3c937b99d7d..79b639788be41d95338c63dd4fea2e92d8d8becb 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/BroadCastMessageDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/BroadCastMessageDTO.java @@ -3,15 +3,16 @@ package at.ac.uibk.gitsearch.service.dto; import java.util.Date; public class BroadCastMessageDTO { - public String message; - public Date starts_at; - public Date ends_at; - public String color; // :"#E75E40", - public String font; // #FFFFFF", - public int id; // 1, - public boolean active; // false, - public String target_path; // "*/welcome", - public String broadcast_type; // "banner", - public boolean dismissable; // false -} \ No newline at end of file + public String message; + public Date starts_at; + public Date ends_at; + + public String color; // :"#E75E40", + public String font; // #FFFFFF", + public int id; // 1, + public boolean active; // false, + public String target_path; // "*/welcome", + public String broadcast_type; // "banner", + public boolean dismissable; // false +} diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/EditorialPageDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/EditorialPageDTO.java index 8bc5ddeca310e57d3df2d4e5299728b106b1b18a..3c02b8fed9f06829b86950a43ea47366bb7cf39a 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/EditorialPageDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/EditorialPageDTO.java @@ -1,42 +1,45 @@ package at.ac.uibk.gitsearch.service.dto; public class EditorialPageDTO { - private String path; - private String content; - - - public EditorialPageDTO(String path, String content) { - super(); - this.path = path; - this.content = content; - } - - public EditorialPageDTO() { - // JSON - } - - /** - * @return the path - */ - public String getPath() { - return path; - } - /** - * @param path the path to set - */ - public void setPath(String path) { - this.path = path; - } - /** - * @return the content - */ - public String getContent() { - return content; - } - /** - * @param content the content to set - */ - public void setContent(String content) { - this.content = content; - } + + private String path; + private String content; + + public EditorialPageDTO(String path, String content) { + super(); + this.path = path; + this.content = content; + } + + public EditorialPageDTO() { + // JSON + } + + /** + * @return the path + */ + public String getPath() { + return path; + } + + /** + * @param path the path to set + */ + public void setPath(String path) { + this.path = path; + } + + /** + * @return the content + */ + public String getContent() { + return content; + } + + /** + * @param content the content to set + */ + public void setContent(String content) { + this.content = content; + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/FragmentDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/FragmentDTO.java index 577464b172ba73d9af53ed0a70333e4eac32c25b..6f4a6203580ff8b750105a8e4ce4b448762ec9a2 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/FragmentDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/FragmentDTO.java @@ -10,9 +10,7 @@ public class FragmentDTO { } public FragmentDTO matchFillLine(String content, String fragment, String preTag, String postTag) { - String fragmentWOHighlight = fragment - .replaceAll(preTag, "") - .replaceAll(postTag, ""); + String fragmentWOHighlight = fragment.replaceAll(preTag, "").replaceAll(postTag, ""); int idx = content.indexOf(fragmentWOHighlight); int idxEnd = idx + fragmentWOHighlight.length(); diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/FrequencyDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/FrequencyDTO.java index aeb702b47bb94003af3811db8d65f2f4e70b42df..106f9a243fa7eaad7c99ff499e5c11221431d7d9 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/FrequencyDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/FrequencyDTO.java @@ -1,11 +1,11 @@ package at.ac.uibk.gitsearch.service.dto; public class FrequencyDTO<T> { + private T key; private Long value; - public FrequencyDTO() { - } + public FrequencyDTO() {} public FrequencyDTO(T key, Long value) { this.key = key; diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesAggregationDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesAggregationDTO.java index a58a8a2b07982603e4e161ebadf3a4e486e17418..ae786ae97e676b823fcbb5f72ffd857d8ea6afa1 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesAggregationDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesAggregationDTO.java @@ -1,12 +1,11 @@ package at.ac.uibk.gitsearch.service.dto; import at.ac.uibk.gitsearch.repository.search.SearchRepositoryConstants; -import org.elasticsearch.search.aggregations.Aggregations; -import org.elasticsearch.search.aggregations.bucket.terms.Terms; - import java.util.Collection; import java.util.List; import java.util.stream.Collectors; +import org.elasticsearch.search.aggregations.Aggregations; +import org.elasticsearch.search.aggregations.bucket.terms.Terms; public class GitFilesAggregationDTO { @@ -15,19 +14,22 @@ public class GitFilesAggregationDTO { private List<FrequencyDTO<String>> university; @SuppressWarnings("unchecked") - public GitFilesAggregationDTO(Aggregations aggregations) { + public GitFilesAggregationDTO(Aggregations aggregations) { Terms terms = aggregations.get(SearchRepositoryConstants.FULLTEXT_SUB_GROUP_AGG); - Collection<Terms.Bucket> buckets = (Collection<Terms.Bucket>) terms.getBuckets(); - this.university = buckets.stream().map(bucket -> new FrequencyDTO<>(bucket.getKeyAsString(), bucket.getDocCount())).collect(Collectors.toList()); + Collection<Terms.Bucket> buckets = (Collection<Terms.Bucket>) terms.getBuckets(); + this.university = + buckets.stream().map(bucket -> new FrequencyDTO<>(bucket.getKeyAsString(), bucket.getDocCount())).collect(Collectors.toList()); terms = aggregations.get(SearchRepositoryConstants.FULLTEXT_REPOSITORY_AGG); buckets = (Collection<Terms.Bucket>) terms.getBuckets(); - this.repositories = buckets.stream().map(bucket -> new FrequencyDTO<>(bucket.getKeyAsString(), bucket.getDocCount())).collect(Collectors.toList()); + this.repositories = + buckets.stream().map(bucket -> new FrequencyDTO<>(bucket.getKeyAsString(), bucket.getDocCount())).collect(Collectors.toList()); terms = aggregations.get(SearchRepositoryConstants.FULLTEXT_FILE_EXTENSION_AGG); buckets = (Collection<Terms.Bucket>) terms.getBuckets(); - this.fileFormat = buckets.stream().map(bucket -> new FrequencyDTO<>(bucket.getKeyAsString(), bucket.getDocCount())).collect(Collectors.toList()); + this.fileFormat = + buckets.stream().map(bucket -> new FrequencyDTO<>(bucket.getKeyAsString(), bucket.getDocCount())).collect(Collectors.toList()); } public List<FrequencyDTO<String>> getFileFormat() { diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesDTO.java index 976ad5d17bb238cd36873054e289f60a613b97fe..64936d08fc88ba30aa7e9add032e82059f5b2224 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesDTO.java @@ -1,13 +1,11 @@ package at.ac.uibk.gitsearch.service.dto; +import at.ac.uibk.gitsearch.es.model.DocumentInfo; +import at.ac.uibk.gitsearch.repository.search.SearchRepositoryConstants; import java.util.Map; - import org.elasticsearch.search.SearchHit; import org.elasticsearch.search.fetch.subphase.highlight.HighlightField; -import at.ac.uibk.gitsearch.es.model.DocumentInfo; -import at.ac.uibk.gitsearch.repository.search.SearchRepositoryConstants; - public class GitFilesDTO { private final String content; diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesPageDetailsDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesPageDetailsDTO.java index b5b3370638ffad8e7bd3250e87ef48d8f98f9476..ff731f3aa3a4dc390f1a0d45fba245b7865e9de3 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesPageDetailsDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/GitFilesPageDetailsDTO.java @@ -3,6 +3,7 @@ package at.ac.uibk.gitsearch.service.dto; import java.util.List; public class GitFilesPageDetailsDTO { + private List<GitFilesDTO> gitFiles; long hitCount; @@ -11,9 +12,7 @@ public class GitFilesPageDetailsDTO { this.hitCount = hitCount; } - public GitFilesPageDetailsDTO() { - - } + public GitFilesPageDetailsDTO() {} public List<GitFilesDTO> getGitFiles() { return gitFiles; diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/LikesCriteria.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/LikesCriteria.java index 24aa6e36d665e8bc862750827cb0a319d7f91a1e..07c89e35ffbea9356420cedd157062b0b7ca5838 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/LikesCriteria.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/LikesCriteria.java @@ -2,7 +2,6 @@ package at.ac.uibk.gitsearch.service.dto; import java.io.Serializable; import java.util.Objects; - import tech.jhipster.service.Criteria; import tech.jhipster.service.filter.Filter; import tech.jhipster.service.filter.IntegerFilter; @@ -31,8 +30,7 @@ public class LikesCriteria implements Serializable, Criteria { private StringFilter exerciseID; - public LikesCriteria() { - } + public LikesCriteria() {} public LikesCriteria(LikesCriteria other) { this.id = other.id == null ? null : other.id.copy(); @@ -78,7 +76,6 @@ public class LikesCriteria implements Serializable, Criteria { this.exerciseID = exerciseID; } - @Override public boolean equals(Object o) { if (this == o) { @@ -88,21 +85,16 @@ public class LikesCriteria implements Serializable, Criteria { return false; } final LikesCriteria that = (LikesCriteria) o; - return + return ( Objects.equals(id, that.id) && Objects.equals(date, that.date) && Objects.equals(userID, that.userID) && - Objects.equals(exerciseID, that.exerciseID); + Objects.equals(exerciseID, that.exerciseID) + ); } @Override public int hashCode() { - return Objects.hash( - id, - date, - userID, - exerciseID - ); + return Objects.hash(id, date, userID, exerciseID); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/MessageDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/MessageDTO.java index 6151dc38da36af469d38b123c56ed62e5691d842..e634bc3650ddbc3c28bd516ff17cf304bf57f47b 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/MessageDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/MessageDTO.java @@ -6,31 +6,27 @@ package at.ac.uibk.gitsearch.service.dto; * */ public class MessageDTO { - - public MessageDTO() { - } - public MessageDTO(String message) { - super(); - this.message = message; - } + public MessageDTO() {} + public MessageDTO(String message) { + super(); + this.message = message; + } - private String message; - - + private String message; - /** - * @return the message - */ - public String getMessage() { - return message; - } + /** + * @return the message + */ + public String getMessage() { + return message; + } - /** - * @param message the message to set - */ - public void setMessage(String message) { - this.message = message; - } + /** + * @param message the message to set + */ + public void setMessage(String message) { + this.message = message; + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/MetadataUserDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/MetadataUserDTO.java index caa1bc3bd29cda1d2e904a2d06ffa4dc25fb2bf1..fcf92dd2b4f4e92a2a34adf21dd8f50c65a13e80 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/MetadataUserDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/MetadataUserDTO.java @@ -1,10 +1,9 @@ package at.ac.uibk.gitsearch.service.dto; import com.fasterxml.jackson.annotation.JsonInclude; - +import java.util.Objects; import javax.validation.constraints.Email; import javax.validation.constraints.Size; -import java.util.Objects; /** * DTO representing users contained in metadata such @@ -23,9 +22,7 @@ public class MetadataUserDTO { @Size(min = 5, max = 254) private String email; - public MetadataUserDTO() { - - } + public MetadataUserDTO() {} public MetadataUserDTO(String name, String affiliation, String email) { this.name = name; @@ -60,10 +57,6 @@ public class MetadataUserDTO { @Override public String toString() { - return "MetadataUserDTO{" + - "name='" + name + '\'' + - ", affiliation='" + affiliation + '\'' + - ", email='" + email + '\'' + - '}'; + return "MetadataUserDTO{" + "name='" + name + '\'' + ", affiliation='" + affiliation + '\'' + ", email='" + email + '\'' + '}'; } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/OAuth2ConfigDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/OAuth2ConfigDTO.java index 633242bb61e42f8c48ead389c23845bdd74609c6..5fb861baaa69af297c3a76dc0ff7272c142788a5 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/OAuth2ConfigDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/OAuth2ConfigDTO.java @@ -1,86 +1,74 @@ package at.ac.uibk.gitsearch.service.dto; import java.util.stream.Collectors; - import org.springframework.security.oauth2.client.registration.ClientRegistration; /** * transfers infos of an OAuth2Config to client - * + * * @author Michael Breu * */ public class OAuth2ConfigDTO { - private String registrationId; - private String clientURL; - private String scopes; + private String registrationId; + private String clientURL; + private String scopes; - public String getRegistrationId() { - return registrationId; - } + public String getRegistrationId() { + return registrationId; + } - public String getClientURL() { - return clientURL; - } + public String getClientURL() { + return clientURL; + } - public String getScopes() { - return scopes; - } + public String getScopes() { + return scopes; + } - public OAuth2ConfigDTO(ClientRegistration registration) { - clientURL = registration.getRedirectUri(); - registrationId = registration.getRegistrationId(); - if(registration.getScopes()==null) - scopes = ""; - else - scopes = registration.getScopes().stream().collect(Collectors.joining(",")); - } + public OAuth2ConfigDTO(ClientRegistration registration) { + clientURL = registration.getRedirectUri(); + registrationId = registration.getRegistrationId(); + if (registration.getScopes() == null) scopes = ""; else scopes = registration.getScopes().stream().collect(Collectors.joining(",")); + } - public OAuth2ConfigDTO() { - // JSON - } + public OAuth2ConfigDTO() { + // JSON + } - @Override - public final int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((clientURL == null) ? 0 : clientURL.hashCode()); - result = prime * result + ((registrationId == null) ? 0 : registrationId.hashCode()); - result = prime * result + ((scopes == null) ? 0 : scopes.hashCode()); - return result; - } + @Override + public final int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((clientURL == null) ? 0 : clientURL.hashCode()); + result = prime * result + ((registrationId == null) ? 0 : registrationId.hashCode()); + result = prime * result + ((scopes == null) ? 0 : scopes.hashCode()); + return result; + } - @Override - public final boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (!(obj instanceof OAuth2ConfigDTO)) { - return false; - } - OAuth2ConfigDTO other = (OAuth2ConfigDTO) obj; - if (clientURL == null) { - if (other.clientURL != null) - return false; - } else if (!clientURL.equals(other.clientURL)) - return false; - if (registrationId == null) { - if (other.registrationId != null) - return false; - } else if (!registrationId.equals(other.registrationId)) - return false; - if (scopes == null) { - if (other.scopes != null) - return false; - } else if (!scopes.equals(other.scopes)) - return false; - return true; - } + @Override + public final boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (!(obj instanceof OAuth2ConfigDTO)) { + return false; + } + OAuth2ConfigDTO other = (OAuth2ConfigDTO) obj; + if (clientURL == null) { + if (other.clientURL != null) return false; + } else if (!clientURL.equals(other.clientURL)) return false; + if (registrationId == null) { + if (other.registrationId != null) return false; + } else if (!registrationId.equals(other.registrationId)) return false; + if (scopes == null) { + if (other.scopes != null) return false; + } else if (!scopes.equals(other.scopes)) return false; + return true; + } - @Override - public String toString() { - return "OAuth2ConfigDTO [for '" + registrationId + "']"; - } + @Override + public String toString() { + return "OAuth2ConfigDTO [for '" + registrationId + "']"; + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/StatisticsDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/StatisticsDTO.java index cc46ef0e9cb8004985451afe6b922c11bb02c5b5..fb35fb8ef1fa310ff4191aee0a46e58853e416e4 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/StatisticsDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/StatisticsDTO.java @@ -6,13 +6,13 @@ import java.io.Serializable; * A DTO for the {@link at.ac.uibk.gitsearch.domain.Statistics} entity. */ public class StatisticsDTO implements Serializable { - + /** - * - */ - private static final long serialVersionUID = 1L; + * + */ + private static final long serialVersionUID = 1L; - private Long id; + private Long id; private Integer views; @@ -20,7 +20,6 @@ public class StatisticsDTO implements Serializable { private String exerciseID; - public Long getId() { return id; } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/UserDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/UserDTO.java index 94f743676150ed38449b70df40b1aab3d708fd98..4e19a2fb7989a80f9bf4b2e7d2cda65a67dc05fb 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/UserDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/UserDTO.java @@ -1,14 +1,12 @@ package at.ac.uibk.gitsearch.service.dto; import at.ac.uibk.gitsearch.config.Constants; - import at.ac.uibk.gitsearch.domain.Authority; import at.ac.uibk.gitsearch.domain.User; - -import javax.validation.constraints.*; import java.time.Instant; import java.util.Set; import java.util.stream.Collectors; +import javax.validation.constraints.*; /** * A DTO representing a user, with his authorities. @@ -54,7 +52,6 @@ public class UserDTO { private Instant lastMailSent; - public UserDTO() { // Empty constructor needed for Jackson. } @@ -72,9 +69,7 @@ public class UserDTO { this.createdDate = user.getCreatedDate(); this.lastModifiedBy = user.getLastModifiedBy(); this.lastModifiedDate = user.getLastModifiedDate(); - this.authorities = user.getAuthorities().stream() - .map(Authority::getName) - .collect(Collectors.toSet()); + this.authorities = user.getAuthorities().stream().map(Authority::getName).collect(Collectors.toSet()); this.lastLogin = user.getLastLogin(); this.lastMailSent = user.getLastMailSent(); } @@ -199,7 +194,6 @@ public class UserDTO { this.lastMailSent = lastMailSent; } - // prettier-ignore @Override public String toString() { diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/UserWatchListCriteria.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/UserWatchListCriteria.java index ba0ec8bcccc79024175c0f0366c6343dea65fecb..e485c7ae7f5d43dc393010930ec28c18d63246c3 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/UserWatchListCriteria.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/UserWatchListCriteria.java @@ -1,9 +1,8 @@ package at.ac.uibk.gitsearch.service.dto; +import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; import java.io.Serializable; import java.util.Objects; - -import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; import tech.jhipster.service.Criteria; import tech.jhipster.service.filter.Filter; import tech.jhipster.service.filter.LongFilter; @@ -19,18 +18,18 @@ import tech.jhipster.service.filter.StringFilter; * fix type specific filters. */ public class UserWatchListCriteria implements Serializable, Criteria { + /** * Class for filtering CheckFrequency */ public static class CheckFrequencyFilter extends Filter<CheckFrequency> implements Serializable { /** - * - */ - private static final long serialVersionUID = 1L; + * + */ + private static final long serialVersionUID = 1L; - public CheckFrequencyFilter() { - } + public CheckFrequencyFilter() {} public CheckFrequencyFilter(CheckFrequencyFilter filter) { super(filter); @@ -40,7 +39,6 @@ public class UserWatchListCriteria implements Serializable, Criteria { public CheckFrequencyFilter copy() { return new CheckFrequencyFilter(this); } - } private static final long serialVersionUID = 1L; @@ -53,8 +51,7 @@ public class UserWatchListCriteria implements Serializable, Criteria { private LongFilter userId; - public UserWatchListCriteria() { - } + public UserWatchListCriteria() {} public UserWatchListCriteria(UserWatchListCriteria other) { this.id = other.id == null ? null : other.id.copy(); @@ -100,7 +97,6 @@ public class UserWatchListCriteria implements Serializable, Criteria { this.userId = userId; } - @Override public boolean equals(Object o) { if (this == o) { @@ -110,21 +106,17 @@ public class UserWatchListCriteria implements Serializable, Criteria { return false; } final UserWatchListCriteria that = (UserWatchListCriteria) o; - return + return ( Objects.equals(id, that.id) && Objects.equals(name, that.name) && Objects.equals(checkFrequency, that.checkFrequency) && - Objects.equals(userId, that.userId); + Objects.equals(userId, that.userId) + ); } @Override public int hashCode() { - return Objects.hash( - id, - name, - checkFrequency, - userId - ); + return Objects.hash(id, name, checkFrequency, userId); } // prettier-ignore @@ -137,5 +129,4 @@ public class UserWatchListCriteria implements Serializable, Criteria { (userId != null ? "userId=" + userId + ", " : "") + "}"; } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/UserWatchListDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/UserWatchListDTO.java index bbd65a6557c7e898d5c143c550d1a3d65e61569d..fa023b68253bc035f6c81cbe7fa7867083e268a7 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/UserWatchListDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/UserWatchListDTO.java @@ -1,18 +1,18 @@ package at.ac.uibk.gitsearch.service.dto; -import javax.validation.constraints.*; -import java.io.Serializable; import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; +import java.io.Serializable; +import javax.validation.constraints.*; /** * A DTO for the {@link at.ac.uibk.gitsearch.domain.UserWatchList} entity. */ public class UserWatchListDTO implements Serializable { - + /** - * - */ - private static final long serialVersionUID = 1L; + * + */ + private static final long serialVersionUID = 1L; private Long id; @@ -23,11 +23,10 @@ public class UserWatchListDTO implements Serializable { @NotNull private CheckFrequency checkFrequency; - private Long userId; private String userLogin; - + public Long getId() { return id; } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/dto/WatchListEntryDTO.java b/src/main/java/at/ac/uibk/gitsearch/service/dto/WatchListEntryDTO.java index 1e15b7526897f7a087711172cb988ac5cad91390..12654a4c8147459f341daed5ccbc43d1892119ed 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/dto/WatchListEntryDTO.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/dto/WatchListEntryDTO.java @@ -1,28 +1,27 @@ package at.ac.uibk.gitsearch.service.dto; -import javax.validation.constraints.*; import java.io.Serializable; +import javax.validation.constraints.*; /** * A DTO for the {@link at.ac.uibk.gitsearch.domain.WatchListEntry} entity. */ public class WatchListEntryDTO implements Serializable { - + /** - * - */ - private static final long serialVersionUID = 1L; + * + */ + private static final long serialVersionUID = 1L; - private Long id; + private Long id; @NotNull private String exerciseId; private String exerciseName; - private Long watchlistId; - + public Long getId() { return id; } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/impl/StatisticsServiceImpl.java b/src/main/java/at/ac/uibk/gitsearch/service/impl/StatisticsServiceImpl.java index c24dd3d40bc87d9ee6126fde7cd3317535bf6a60..2c7b6e8bfdd75f3c254ecaa55c930a231bf24148 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/impl/StatisticsServiceImpl.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/impl/StatisticsServiceImpl.java @@ -1,7 +1,12 @@ package at.ac.uibk.gitsearch.service.impl; +import at.ac.uibk.gitsearch.domain.Statistics; +import at.ac.uibk.gitsearch.repository.StatisticsRepository; +import at.ac.uibk.gitsearch.repository.search.StatisticsSearchRepository; +import at.ac.uibk.gitsearch.service.StatisticsService; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; +import at.ac.uibk.gitsearch.service.mapper.StatisticsMapper; import java.util.Optional; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -9,13 +14,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.domain.Statistics; -import at.ac.uibk.gitsearch.repository.StatisticsRepository; -import at.ac.uibk.gitsearch.repository.search.StatisticsSearchRepository; -import at.ac.uibk.gitsearch.service.StatisticsService; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; -import at.ac.uibk.gitsearch.service.mapper.StatisticsMapper; - /** * Service Implementation for managing {@link Statistics}. */ @@ -31,7 +29,11 @@ public class StatisticsServiceImpl implements StatisticsService { private final StatisticsSearchRepository statisticsSearchRepository; - public StatisticsServiceImpl(StatisticsRepository statisticsRepository, StatisticsMapper statisticsMapper, StatisticsSearchRepository statisticsSearchRepository) { + public StatisticsServiceImpl( + StatisticsRepository statisticsRepository, + StatisticsMapper statisticsMapper, + StatisticsSearchRepository statisticsSearchRepository + ) { this.statisticsRepository = statisticsRepository; this.statisticsMapper = statisticsMapper; this.statisticsSearchRepository = statisticsSearchRepository; @@ -45,10 +47,10 @@ public class StatisticsServiceImpl implements StatisticsService { StatisticsDTO result = statisticsMapper.toDto(statistics); // TODO temporary fix: statistics has a problem with complex exercise ids (e.g. 10:if1/exercise1) :-) try { - statisticsSearchRepository.save(statistics); - } catch (Exception e) { - log.error("Please fix this problem! ExerciseIds are not numeric any more!", e); - } + statisticsSearchRepository.save(statistics); + } catch (Exception e) { + log.error("Please fix this problem! ExerciseIds are not numeric any more!", e); + } return result; } @@ -56,24 +58,20 @@ public class StatisticsServiceImpl implements StatisticsService { @Transactional(readOnly = true) public Page<StatisticsDTO> findAll(Pageable pageable) { log.debug("Request to get all Statistics"); - return statisticsRepository.findAll(pageable) - .map(statisticsMapper::toDto); + return statisticsRepository.findAll(pageable).map(statisticsMapper::toDto); } - @Override @Transactional(readOnly = true) public Optional<StatisticsDTO> findOne(Long id) { log.debug("Request to get Statistics : {}", id); - return statisticsRepository.findById(id) - .map(statisticsMapper::toDto); + return statisticsRepository.findById(id).map(statisticsMapper::toDto); } @Override public Optional<StatisticsDTO> findOneByExerciseID(String id) { log.debug("Request to get Statistics by ExerciseId : {}", id); - return statisticsRepository.findByExerciseID(id) - .map(statisticsMapper::toDto); + return statisticsRepository.findByExerciseID(id).map(statisticsMapper::toDto); } @Override @@ -82,13 +80,12 @@ public class StatisticsServiceImpl implements StatisticsService { statisticsRepository.deleteById(id); statisticsSearchRepository.deleteById(id); } - -// @Override -// @Transactional(readOnly = true) -// public Page<StatisticsDTO> search(String query, Pageable pageable) { -// log.debug("Request to search for a page of Statistics for query {}", query); -// return statisticsSearchRepository.search(queryStringQuery(query), pageable) -// .map(statisticsMapper::toDto); -// } + // @Override + // @Transactional(readOnly = true) + // public Page<StatisticsDTO> search(String query, Pageable pageable) { + // log.debug("Request to search for a page of Statistics for query {}", query); + // return statisticsSearchRepository.search(queryStringQuery(query), pageable) + // .map(statisticsMapper::toDto); + // } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/management/PluginHealthCheckRegistry.java b/src/main/java/at/ac/uibk/gitsearch/service/management/PluginHealthCheckRegistry.java index f12911c902e294ad40dd7f81c50c6aea90b506fc..4b5f6016305ec412a8dbc00d337d230e1574a96b 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/management/PluginHealthCheckRegistry.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/management/PluginHealthCheckRegistry.java @@ -1,10 +1,12 @@ package at.ac.uibk.gitsearch.service.management; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; +import at.ac.uibk.gitsearch.properties.ApplicationProperties.RegisteredConnector; +import at.ac.uibk.gitsearch.service.PluginManagementService; +import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper; import java.util.List; import java.util.Map; - import javax.annotation.PostConstruct; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -14,66 +16,65 @@ import org.springframework.boot.actuate.health.HealthContributorRegistry; import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.stereotype.Service; -import at.ac.uibk.gitsearch.properties.ApplicationProperties; -import at.ac.uibk.gitsearch.properties.ApplicationProperties.RegisteredConnector; -import at.ac.uibk.gitsearch.service.PluginManagementService; -import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper; - @Service //@Endpoint(id = "pluginHealth") public class PluginHealthCheckRegistry { - private static final Logger log = LoggerFactory.getLogger(PluginHealthCheckRegistry.class); - - @Autowired - protected PluginManagementService pluginManagementService; - @Autowired - private ApplicationProperties applicationProperties; - @Autowired - private HealthContributorRegistry healthContributorRegistry; - - @PostConstruct - protected void registerPluginHealth() { - final List<RegisteredConnector> registeredPlugins = applicationProperties.getRegisteredConnectors(); - if(registeredPlugins==null) { - log.warn("No plugins defined?"); - return; - } - for (RegisteredConnector configURL : registeredPlugins) { - healthContributorRegistry.registerContributor(configURL.getUrl(), - new PluginHealthCheck(configURL.getUrl(), pluginManagementService)); - } - - } - - public static class PluginHealthCheck implements HealthContributor, HealthIndicator { - - protected PluginManagementService pluginManagementService; - private String configURL; - - public PluginHealthCheck(String configURL, PluginManagementService pluginManagementService) { - super(); - this.configURL = configURL; - this.pluginManagementService = pluginManagementService; - } - - public Health health() { - - for (ConnectorConfigWrapper pluginConfig : pluginManagementService.getRegisteredPluginConfigs()) { - if (configURL.equals(pluginConfig.getConfigURL())) { - final String message = String.format("Running as %s with %d actions", pluginConfig.getPluginName(), - pluginConfig.getActions().size()); - return Health.up().withDetail(pluginConfig.getPluginName(), message).build(); - } - } - for (Map.Entry<RegisteredConnector, Exception> failures : pluginManagementService.getConfigFailures().entrySet()) { - if (configURL.equals(failures.getKey().getUrl())) { - return Health.down(failures.getValue()).withDetail(configURL, "has failed").build(); - } - } - - return Health.unknown().build(); - } - } - + private static final Logger log = LoggerFactory.getLogger(PluginHealthCheckRegistry.class); + + @Autowired + protected PluginManagementService pluginManagementService; + + @Autowired + private ApplicationProperties applicationProperties; + + @Autowired + private HealthContributorRegistry healthContributorRegistry; + + @PostConstruct + protected void registerPluginHealth() { + final List<RegisteredConnector> registeredPlugins = applicationProperties.getRegisteredConnectors(); + if (registeredPlugins == null) { + log.warn("No plugins defined?"); + return; + } + for (RegisteredConnector configURL : registeredPlugins) { + healthContributorRegistry.registerContributor( + configURL.getUrl(), + new PluginHealthCheck(configURL.getUrl(), pluginManagementService) + ); + } + } + + public static class PluginHealthCheck implements HealthContributor, HealthIndicator { + + protected PluginManagementService pluginManagementService; + private String configURL; + + public PluginHealthCheck(String configURL, PluginManagementService pluginManagementService) { + super(); + this.configURL = configURL; + this.pluginManagementService = pluginManagementService; + } + + public Health health() { + for (ConnectorConfigWrapper pluginConfig : pluginManagementService.getRegisteredPluginConfigs()) { + if (configURL.equals(pluginConfig.getConfigURL())) { + final String message = String.format( + "Running as %s with %d actions", + pluginConfig.getPluginName(), + pluginConfig.getActions().size() + ); + return Health.up().withDetail(pluginConfig.getPluginName(), message).build(); + } + } + for (Map.Entry<RegisteredConnector, Exception> failures : pluginManagementService.getConfigFailures().entrySet()) { + if (configURL.equals(failures.getKey().getUrl())) { + return Health.down(failures.getValue()).withDetail(configURL, "has failed").build(); + } + } + + return Health.unknown().build(); + } + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/mapper/SavedSearchesMapper.java b/src/main/java/at/ac/uibk/gitsearch/service/mapper/SavedSearchesMapper.java index a77ececd669c938c29b77b74868961b76d7a34ee..b512fdef16a0d3701c62827819cd622adbf4bd59 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/mapper/SavedSearchesMapper.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/mapper/SavedSearchesMapper.java @@ -3,7 +3,6 @@ package at.ac.uibk.gitsearch.service.mapper; import at.ac.uibk.gitsearch.domain.Authority; import at.ac.uibk.gitsearch.domain.SavedSearches; import at.ac.uibk.gitsearch.service.dto.SavedSearchesDTO; - import java.util.Collections; import java.util.Set; import java.util.stream.Collectors; @@ -14,10 +13,9 @@ import org.mapstruct.*; */ @Mapper(componentModel = "spring", uses = { UserMapper.class }) public interface SavedSearchesMapper extends EntityMapper<SavedSearchesDTO, SavedSearches> { - - default Set<Authority> stringToAuths(Set<String> auths) { - if(auths==null) {return Collections.emptySet();} - else - return auths.stream().map(Authority::new).collect(Collectors.toSet()); + default Set<Authority> stringToAuths(Set<String> auths) { + if (auths == null) { + return Collections.emptySet(); + } else return auths.stream().map(Authority::new).collect(Collectors.toSet()); } } diff --git a/src/main/java/at/ac/uibk/gitsearch/service/mapper/StatisticsMapper.java b/src/main/java/at/ac/uibk/gitsearch/service/mapper/StatisticsMapper.java index 0144416937b2114a1708133c1ef46562205bafa0..9642045a5fd0f1dafe78933c8c91f19e4e773e4f 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/mapper/StatisticsMapper.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/mapper/StatisticsMapper.java @@ -1,9 +1,7 @@ package at.ac.uibk.gitsearch.service.mapper; - import at.ac.uibk.gitsearch.domain.*; import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; - import org.mapstruct.*; /** @@ -11,9 +9,6 @@ import org.mapstruct.*; */ @Mapper(componentModel = "spring", uses = {}) public interface StatisticsMapper extends EntityMapper<StatisticsDTO, Statistics> { - - - default Statistics fromId(Long id) { if (id == null) { return null; diff --git a/src/main/java/at/ac/uibk/gitsearch/service/mapper/UserWatchListMapper.java b/src/main/java/at/ac/uibk/gitsearch/service/mapper/UserWatchListMapper.java index 531e5595aa7c4355994d3f7ef13d45ad3a5e13a8..f7ff6dea0529aa55a0f1d56f8c4a5b84279824e7 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/mapper/UserWatchListMapper.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/mapper/UserWatchListMapper.java @@ -1,17 +1,14 @@ package at.ac.uibk.gitsearch.service.mapper; - import at.ac.uibk.gitsearch.domain.*; import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; - import org.mapstruct.*; /** * Mapper for the entity {@link UserWatchList} and its DTO {@link UserWatchListDTO}. */ -@Mapper(componentModel = "spring", uses = {UserMapper.class}) +@Mapper(componentModel = "spring", uses = { UserMapper.class }) public interface UserWatchListMapper extends EntityMapper<UserWatchListDTO, UserWatchList> { - @Mapping(source = "user.id", target = "userId") @Mapping(source = "user.login", target = "userLogin") UserWatchListDTO toDto(UserWatchList userWatchList); diff --git a/src/main/java/at/ac/uibk/gitsearch/service/mapper/WatchListEntryMapper.java b/src/main/java/at/ac/uibk/gitsearch/service/mapper/WatchListEntryMapper.java index 631bc2e2caabfe1018e895cd2f90be8c31b95d06..361965d6af0f98cfcba2d32e94573d428ff20cda 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/mapper/WatchListEntryMapper.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/mapper/WatchListEntryMapper.java @@ -1,17 +1,14 @@ package at.ac.uibk.gitsearch.service.mapper; - import at.ac.uibk.gitsearch.domain.*; import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; - import org.mapstruct.*; /** * Mapper for the entity {@link WatchListEntry} and its DTO {@link WatchListEntryDTO}. */ -@Mapper(componentModel = "spring", uses = {UserWatchListMapper.class}) +@Mapper(componentModel = "spring", uses = { UserWatchListMapper.class }) public interface WatchListEntryMapper extends EntityMapper<WatchListEntryDTO, WatchListEntry> { - @Mapping(source = "watchlist.id", target = "watchlistId") WatchListEntryDTO toDto(WatchListEntry watchListEntry); diff --git a/src/main/java/at/ac/uibk/gitsearch/service/oauth2/OAuth2ConfigService.java b/src/main/java/at/ac/uibk/gitsearch/service/oauth2/OAuth2ConfigService.java index dde962bb0206ad34f37cb4cbd30b7c83321ac2a8..c68f70f2adce9afd61aa6d808ee93c34085b26c1 100644 --- a/src/main/java/at/ac/uibk/gitsearch/service/oauth2/OAuth2ConfigService.java +++ b/src/main/java/at/ac/uibk/gitsearch/service/oauth2/OAuth2ConfigService.java @@ -1,8 +1,8 @@ package at.ac.uibk.gitsearch.service.oauth2; +import at.ac.uibk.gitsearch.service.dto.OAuth2ConfigDTO; import java.util.ArrayList; import java.util.List; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -11,42 +11,39 @@ import org.springframework.security.oauth2.client.registration.ClientRegistratio import org.springframework.security.oauth2.client.registration.InMemoryClientRegistrationRepository; import org.springframework.stereotype.Service; -import at.ac.uibk.gitsearch.service.dto.OAuth2ConfigDTO; - /** * provides functions for the retrieval of OAuth2 services * @author Michael Breu - */ + */ @Service - public class OAuth2ConfigService { - + private final Logger log = LoggerFactory.getLogger(OAuth2ConfigService.class); - - @Autowired - private ClientRegistrationRepository oauth2ClientRegistrationRepositories; - public OAuth2ConfigDTO findByRegistrationId(String registrationId) { - final ClientRegistration registration = oauth2ClientRegistrationRepositories.findByRegistrationId(registrationId); - if(registration==null) return null; - return buildConfigFromRegistration(registration); - } - - public OAuth2ConfigDTO[] getPublicRegistrations() { - if (oauth2ClientRegistrationRepositories instanceof InMemoryClientRegistrationRepository) { - InMemoryClientRegistrationRepository imOAuth2ClientRegistrationRepositories = (InMemoryClientRegistrationRepository) oauth2ClientRegistrationRepositories; - final List<OAuth2ConfigDTO> result = new ArrayList<>(); - imOAuth2ClientRegistrationRepositories.iterator().forEachRemaining(registration -> result.add(buildConfigFromRegistration(registration))); - return result.toArray(new OAuth2ConfigDTO[] {}); - } - else { - log.warn("Cannot find any OAuth2 Registrations"); - return new OAuth2ConfigDTO[] {}; - } - } + @Autowired + private ClientRegistrationRepository oauth2ClientRegistrationRepositories; + + public OAuth2ConfigDTO findByRegistrationId(String registrationId) { + final ClientRegistration registration = oauth2ClientRegistrationRepositories.findByRegistrationId(registrationId); + if (registration == null) return null; + return buildConfigFromRegistration(registration); + } + + public OAuth2ConfigDTO[] getPublicRegistrations() { + if (oauth2ClientRegistrationRepositories instanceof InMemoryClientRegistrationRepository) { + InMemoryClientRegistrationRepository imOAuth2ClientRegistrationRepositories = (InMemoryClientRegistrationRepository) oauth2ClientRegistrationRepositories; + final List<OAuth2ConfigDTO> result = new ArrayList<>(); + imOAuth2ClientRegistrationRepositories + .iterator() + .forEachRemaining(registration -> result.add(buildConfigFromRegistration(registration))); + return result.toArray(new OAuth2ConfigDTO[] {}); + } else { + log.warn("Cannot find any OAuth2 Registrations"); + return new OAuth2ConfigDTO[] {}; + } + } - private OAuth2ConfigDTO buildConfigFromRegistration(ClientRegistration registration) { - return new OAuth2ConfigDTO(registration); - } - + private OAuth2ConfigDTO buildConfigFromRegistration(ClientRegistration registration) { + return new OAuth2ConfigDTO(registration); + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/AccountResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/AccountResource.java index 0ae65fe76fc8f81494669de4e48240c95da9c7db..8593cea0637dd236e426ab22e87f3c806d937d58 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/AccountResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/AccountResource.java @@ -29,11 +29,11 @@ public class AccountResource { public static class AccountResourceException extends RuntimeException { /** - * - */ - private static final long serialVersionUID = 5875604197924631116L; + * + */ + private static final long serialVersionUID = 5875604197924631116L; - public AccountResourceException(String message) { + public AccountResourceException(String message) { super(message); } } @@ -63,12 +63,12 @@ public class AccountResource { @PostMapping("/register") @ResponseStatus(HttpStatus.CREATED) public void registerAccount(@Valid @RequestBody ManagedUserVM managedUserVM) { - throw new AccountResourceException("Self registration not supported"); - // if (isPasswordLengthInvalid(managedUserVM.getPassword())) { -// throw new InvalidPasswordException(); -// } -// User user = userService.registerUser(managedUserVM, managedUserVM.getPassword()); -// mailService.sendActivationEmail(user); + throw new AccountResourceException("Self registration not supported"); + // if (isPasswordLengthInvalid(managedUserVM.getPassword())) { + // throw new InvalidPasswordException(); + // } + // User user = userService.registerUser(managedUserVM, managedUserVM.getPassword()); + // mailService.sendActivationEmail(user); } /** diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/AchievementResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/AchievementResource.java index 284b07bb1b0a169432f15118d97e3e0c16666c1b..4fa796b2586347605e96211020892776c48d9ff8 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/AchievementResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/AchievementResource.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.web.rest; - +import at.ac.uibk.gitsearch.service.AchievementService; +import at.ac.uibk.gitsearch.service.UserService; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; @@ -13,18 +14,10 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import at.ac.uibk.gitsearch.service.AchievementService; -import at.ac.uibk.gitsearch.service.UserService; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; - - - @RestController @RequestMapping("/api") @Transactional public class AchievementResource { - - private final Logger log = LoggerFactory.getLogger(SearchResource.class); @@ -32,7 +25,6 @@ public class AchievementResource { private final UserService userService; - public AchievementResource(UserService userService, AchievementService achievementService) { this.userService = userService; this.achievementService = achievementService; @@ -45,7 +37,5 @@ public class AchievementResource { log.debug("REST request to search statistics for user {}", email); StatisticsDTO toReturn = achievementService.searchUserStatistics(email); return new ResponseEntity<>(toReturn, HttpStatus.OK); - - } } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/ApplicationInfoResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/ApplicationInfoResource.java index 7183fc71f95652fa4f6e83d136342df5446075f6..8a3f92d6d1e307893d5d60b6b821d61a54b1905e 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/ApplicationInfoResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/ApplicationInfoResource.java @@ -1,16 +1,15 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; +import at.ac.uibk.gitsearch.properties.ApplicationProperties.DeploymentInfo; +import at.ac.uibk.gitsearch.service.MessageService; +import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import at.ac.uibk.gitsearch.properties.ApplicationProperties; -import at.ac.uibk.gitsearch.properties.ApplicationProperties.DeploymentInfo; -import at.ac.uibk.gitsearch.service.MessageService; -import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; - /** * REST controller to retrieve deployment infos. */ @@ -18,16 +17,15 @@ import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; @RequestMapping("/api") public class ApplicationInfoResource { - @SuppressWarnings("unused") - private final Logger log = LoggerFactory.getLogger(ApplicationInfoResource.class); + private final Logger log = LoggerFactory.getLogger(ApplicationInfoResource.class); private final ApplicationProperties applicationProperties; private final MessageService messageService; public ApplicationInfoResource(ApplicationProperties applicationProperties, MessageService messageService) { - this.applicationProperties = applicationProperties; - this.messageService = messageService; + this.applicationProperties = applicationProperties; + this.messageService = messageService; } /** @@ -37,25 +35,24 @@ public class ApplicationInfoResource { @GetMapping("/applicationInfo/deploymentInfo") public ApplicationProperties.DeploymentInfo getApplicationInfo() { final DeploymentInfo deploymentInfo = applicationProperties.getDeploymentInfo(); - if(deploymentInfo==null || "${gitBranch}".equals(deploymentInfo.getBranch())) { - return new ApplicationProperties.DeploymentInfo(); // application info is not initialized properly! Return an empty info + if (deploymentInfo == null || "${gitBranch}".equals(deploymentInfo.getBranch())) { + return new ApplicationProperties.DeploymentInfo(); // application info is not initialized properly! Return an empty info } - return deploymentInfo; + return deploymentInfo; } @GetMapping("/applicationInfo/oerLinkInfo") public String getOerLink() { final String oerLink = applicationProperties.getOerLink(); - return oerLink; + return oerLink; } - + /** * {@code GET /applicationInfo/deploymentInfo} : get generic deployment info. * */ @GetMapping("/applicationInfo/broadcastMessages") public BroadCastMessageDTO[] getBroadCastMessages() { - return messageService.getMessages(); + return messageService.getMessages(); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/AuditResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/AuditResource.java index dfec234b18e843b70565432b9b577c41bfa36cd0..86dbf5d3444b4831780ae2c333bbf32bdd4966c8 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/AuditResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/AuditResource.java @@ -1,9 +1,10 @@ package at.ac.uibk.gitsearch.web.rest; import at.ac.uibk.gitsearch.service.AuditEventService; - -import tech.jhipster.web.util.PaginationUtil; -import tech.jhipster.web.util.ResponseUtil; +import java.time.Instant; +import java.time.LocalDate; +import java.time.ZoneId; +import java.util.List; import org.springframework.boot.actuate.audit.AuditEvent; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -12,11 +13,8 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import java.time.Instant; -import java.time.LocalDate; -import java.time.ZoneId; -import java.util.List; +import tech.jhipster.web.util.PaginationUtil; +import tech.jhipster.web.util.ResponseUtil; /** * REST controller for getting the {@link AuditEvent}s. @@ -52,12 +50,12 @@ public class AuditResource { * @param pageable the pagination information. * @return the {@link ResponseEntity} with status {@code 200 (OK)} and the list of {@link AuditEvent} in body. */ - @GetMapping(params = {"fromDate", "toDate"}) + @GetMapping(params = { "fromDate", "toDate" }) public ResponseEntity<List<AuditEvent>> getByDates( @RequestParam(value = "fromDate") LocalDate fromDate, @RequestParam(value = "toDate") LocalDate toDate, - Pageable pageable) { - + Pageable pageable + ) { Instant from = fromDate.atStartOfDay(ZoneId.systemDefault()).toInstant(); Instant to = toDate.atStartOfDay(ZoneId.systemDefault()).plusDays(1).toInstant(); diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/CheckResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/CheckResource.java index 2c37cf0ffbb682deb123cd24cfc571f11ba3c3ae..014eb355fa8b3508cf8994a5a2fab7f2a01ddc2a 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/CheckResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/CheckResource.java @@ -1,18 +1,16 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; +import at.ac.uibk.gitsearch.service.MailService; +import at.ac.uibk.gitsearch.service.UserService; +import at.ac.uibk.gitsearch.service.dto.MessageDTO; import java.util.Optional; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; -import at.ac.uibk.gitsearch.service.MailService; -import at.ac.uibk.gitsearch.service.UserService; -import at.ac.uibk.gitsearch.service.dto.MessageDTO; - /** * REST controller for various tests that can be initiated by the user. */ @@ -23,13 +21,13 @@ public class CheckResource { private final Logger log = LoggerFactory.getLogger(CheckResource.class); private final MailService mailService; + @SuppressWarnings("unused") - private final TokenProvider tokenProvider; + private final TokenProvider tokenProvider; + private final UserService userService; - - public CheckResource(MailService mailService, - TokenProvider tokenProvider, UserService userService - ) { + + public CheckResource(MailService mailService, TokenProvider tokenProvider, UserService userService) { this.mailService = mailService; this.tokenProvider = tokenProvider; this.userService = userService; @@ -39,17 +37,18 @@ public class CheckResource { * {@code Get /triggerInfoMail} : Triggers the info mail for the current user. */ @GetMapping("/triggerInfoMail") - public MessageDTO triggerInfoMail() { - - Optional<at.ac.uibk.gitsearch.domain.User> uo = userService.getUserWithAuthorities(); - - if(uo.isEmpty()) { - log.debug("unknown user for triggerInfoMail"); - throw new AccountResource.AccountResourceException("User could not be found"); - } - boolean wasSent = mailService.sendInfoMail(uo.get(), true /* even if no content */); - return new MessageDTO(wasSent?"Mail successfully sent to " + uo.get().getEmail():"no relevant content found (or potential mailing problems). No Mail sent to " + uo.get().getEmail()); + public MessageDTO triggerInfoMail() { + Optional<at.ac.uibk.gitsearch.domain.User> uo = userService.getUserWithAuthorities(); + + if (uo.isEmpty()) { + log.debug("unknown user for triggerInfoMail"); + throw new AccountResource.AccountResourceException("User could not be found"); + } + boolean wasSent = mailService.sendInfoMail(uo.get(), true/* even if no content */); + return new MessageDTO( + wasSent + ? "Mail successfully sent to " + uo.get().getEmail() + : "no relevant content found (or potential mailing problems). No Mail sent to " + uo.get().getEmail() + ); } - - } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/EditorialPagesResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/EditorialPagesResource.java index d3c579afdf3b1eac6c712c669fc9da29103a5c1d..76c34f8f5fe29f491fe90fc379b4bb250ccb937b 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/EditorialPagesResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/EditorialPagesResource.java @@ -1,7 +1,8 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.service.EditorialPagesService; +import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; import javax.ws.rs.core.MediaType; - import org.gitlab4j.api.GitLabApiException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -12,9 +13,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import at.ac.uibk.gitsearch.service.EditorialPagesService; -import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; - /** * REST controller for requesting Pages. */ @@ -23,7 +21,7 @@ import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; public class EditorialPagesResource { @SuppressWarnings("unused") - private final Logger log = LoggerFactory.getLogger(EditorialPagesResource.class); + private final Logger log = LoggerFactory.getLogger(EditorialPagesResource.class); private final EditorialPagesService editorialPagesService; @@ -39,8 +37,7 @@ public class EditorialPagesResource { */ @GetMapping("/pages") public ResponseEntity<EditorialPageDTO> getPage(@RequestParam String path) throws GitLabApiException { - - EditorialPageDTO content = editorialPagesService.getContent(path); + EditorialPageDTO content = editorialPagesService.getContent(path); return ResponseEntity.ok().body(content); } @@ -50,20 +47,17 @@ public class EditorialPagesResource { * @param path the path to the page * @throws GitLabApiException, if page is not available */ - @GetMapping(value="/pages/attachment", produces = MediaType.TEXT_PLAIN) + @GetMapping(value = "/pages/attachment", produces = MediaType.TEXT_PLAIN) public ResponseEntity<String> mapPageAttachmentsUrl(@RequestParam String path) throws GitLabApiException { - String content = editorialPagesService.getAttachmentURL(path); + String content = editorialPagesService.getAttachmentURL(path); return ResponseEntity.ok().body(content); } -/** + + /** * {@code DELETE /page} : Resets the pages cache. Does not really delete all pages */ @DeleteMapping("/pages") - public void resetPages() { - - editorialPagesService.resetCache(); - + public void resetPages() { + editorialPagesService.resetCache(); } - - } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/ExerciseResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/ExerciseResource.java index 89a644e12f67a76dba913acaab2232cd463ea564..9ba53e1e923b61ae770a4d9ac48ed85876afa192 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/ExerciseResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/ExerciseResource.java @@ -1,21 +1,28 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.es.model.ArtemisExerciseInfo; +import at.ac.uibk.gitsearch.security.SecurityUtils; +import at.ac.uibk.gitsearch.service.ArtemisImportError; +import at.ac.uibk.gitsearch.service.ExerciseService; +import at.ac.uibk.gitsearch.service.GitlabService; +import at.ac.uibk.gitsearch.service.SearchService; +import at.ac.uibk.gitsearch.service.StatisticsService; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; +import at.ac.uibk.gitsearch.web.util.HeaderUtil; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.nio.file.Files; import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.Files; import java.text.ParseException; import java.util.Optional; - import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response; - import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.codeability.sharing.plugins.api.search.util.ExerciseId; import org.eclipse.jgit.api.errors.GitAPIException; @@ -39,16 +46,6 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.HandlerMapping; -import at.ac.uibk.gitsearch.es.model.ArtemisExerciseInfo; -import at.ac.uibk.gitsearch.security.SecurityUtils; -import at.ac.uibk.gitsearch.service.ArtemisImportError; -import at.ac.uibk.gitsearch.service.ExerciseService; -import at.ac.uibk.gitsearch.service.GitlabService; -import at.ac.uibk.gitsearch.service.SearchService; -import at.ac.uibk.gitsearch.service.StatisticsService; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; -import at.ac.uibk.gitsearch.web.util.HeaderUtil; - /** * this resource should give access to various aspects of an exercise or course * @author Michael Breu @@ -62,9 +59,9 @@ public class ExerciseResource { private static final String ENTITY_NAME = "ExerciseResource"; - private static final String REPOSITORYFILE = "RepositoryFile"; + private static final String REPOSITORYFILE = "RepositoryFile"; - private final Logger log = LoggerFactory.getLogger(ExerciseResource.class); + private final Logger log = LoggerFactory.getLogger(ExerciseResource.class); @Value("${application.registeredConnectorsCallBackURL}") String baseApiUrl; @@ -84,7 +81,6 @@ public class ExerciseResource { @Value("${jhipster.clientApp.name}") private String applicationName; - /** * GET some file of an exercise. * @@ -92,26 +88,48 @@ public class ExerciseResource { * @return the ResponseEntity with status 200 (OK) and with body the exercise file, or with status 404 (Not Found) */ @GetMapping("/exerciseFile/**") - public ResponseEntity<Resource> getRepositoryFile(HttpServletRequest request, @RequestParam("filePath") String filePath) throws IOException { - String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); + public ResponseEntity<Resource> getRepositoryFile(HttpServletRequest request, @RequestParam("filePath") String filePath) + throws IOException { + String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); - String exerciseId = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); + String exerciseId = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); - ExerciseId parsedId; - try { - parsedId = ExerciseId.fromString(exerciseId); - } catch (ParseException e) { - return ResponseEntity.notFound().headers(HeaderUtil.createFailureAlert(applicationName, true, REPOSITORYFILE, NOT_FOUND, - "There was an error finding your exercise " + exerciseId + ".")).build(); - } + ExerciseId parsedId; + try { + parsedId = ExerciseId.fromString(exerciseId); + } catch (ParseException e) { + return ResponseEntity + .notFound() + .headers( + HeaderUtil.createFailureAlert( + applicationName, + true, + REPOSITORYFILE, + NOT_FOUND, + "There was an error finding your exercise " + exerciseId + "." + ) + ) + .build(); + } InputStream repositoryStream = null; try { repositoryStream = gitLabService.getRepositoryFile(parsedId, filePath); } catch (IOException | GitLabApiException e) { log.warn("Cannot read file for exercise {} and path {}: {}", exerciseId, filePath, e.getMessage()); - return ResponseEntity.notFound().headers(HeaderUtil.createFailureAlert(applicationName, true, REPOSITORYFILE, NOT_FOUND, - "There was an error on the server and the resource file could not be created.")).build(); } + return ResponseEntity + .notFound() + .headers( + HeaderUtil.createFailureAlert( + applicationName, + true, + REPOSITORYFILE, + NOT_FOUND, + "There was an error on the server and the resource file could not be created." + ) + ) + .build(); + } InputStreamResource resource = new InputStreamResource(repositoryStream); @@ -126,57 +144,94 @@ public class ExerciseResource { */ @GetMapping("/exercise/**") public ResponseEntity<SearchResultDTO> getExerciseById(HttpServletRequest request) throws IOException { - String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); - - String exerciseId = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); + String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); - ExerciseId parsedId; - try { - parsedId = ExerciseId.fromString(exerciseId); - } catch (ParseException e) { - return ResponseEntity.notFound().headers(HeaderUtil.createFailureAlert(applicationName, true, REPOSITORYFILE, NOT_FOUND, - "There was an error with your requested id " + exerciseId + ".")).build(); - } + String exerciseId = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); - final Optional<SearchResultDTO> result = searchService.findExerciseById(parsedId); + ExerciseId parsedId; + try { + parsedId = ExerciseId.fromString(exerciseId); + } catch (ParseException e) { + return ResponseEntity + .notFound() + .headers( + HeaderUtil.createFailureAlert( + applicationName, + true, + REPOSITORYFILE, + NOT_FOUND, + "There was an error with your requested id " + exerciseId + "." + ) + ) + .build(); + } + final Optional<SearchResultDTO> result = searchService.findExerciseById(parsedId); - if(result.isPresent()) { - return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result.get()); - } else { - return ResponseEntity.notFound().headers(HeaderUtil.createFailureAlert(applicationName, true, REPOSITORYFILE, NOT_FOUND, - "There was an error finding your exercise " + exerciseId + ".")).build(); - } + if (result.isPresent()) { + return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON).body(result.get()); + } else { + return ResponseEntity + .notFound() + .headers( + HeaderUtil.createFailureAlert( + applicationName, + true, + REPOSITORYFILE, + NOT_FOUND, + "There was an error finding your exercise " + exerciseId + "." + ) + ) + .build(); + } } - /** * POST /exerciseFiles/:exerciseId: sends all repositories and details of the programming exercise as zip. * However excepted files/folders are omitted, if exercise is publicVisibility - * + * * @param exerciseId the id of the exercise to get the repos from * ResponseEntity with status * @throws IOException if something during the zip process went wrong */ @PostMapping("/exerciseFiles/**") public ResponseEntity<Resource> exportProgrammingExercise(HttpServletRequest request) throws IOException { - String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); - - String exerciseId = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); - - ExerciseId parsedId; - try { - parsedId = ExerciseId.fromString(exerciseId); - } catch (ParseException e) { - return ResponseEntity.notFound().headers(HeaderUtil.createFailureAlert(applicationName, true, REPOSITORYFILE, NOT_FOUND, - "There was an error finding your exercise " + exerciseId + ".")).build(); - } - + String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); + + String exerciseId = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); + + ExerciseId parsedId; + try { + parsedId = ExerciseId.fromString(exerciseId); + } catch (ParseException e) { + return ResponseEntity + .notFound() + .headers( + HeaderUtil.createFailureAlert( + applicationName, + true, + REPOSITORYFILE, + NOT_FOUND, + "There was an error finding your exercise " + exerciseId + "." + ) + ) + .build(); + } + File zipFile = searchService.exportExercise(parsedId); if (zipFile == null) { - return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(applicationName, true, ENTITY_NAME, - "internalServerError", "There was an error on the server and the zip file could not be created.")) - .body(null); + return ResponseEntity + .badRequest() + .headers( + HeaderUtil.createFailureAlert( + applicationName, + true, + ENTITY_NAME, + "internalServerError", + "There was an error on the server and the zip file could not be created." + ) + ) + .body(null); } /* @@ -196,19 +251,17 @@ public class ExerciseResource { public void close() throws IOException { super.close(); try { - Files.delete(file.toPath()); - } - catch(IOException e) { - log.info("Cannot delete {}", file.getAbsoluteFile(), e); + Files.delete(file.toPath()); + } catch (IOException e) { + log.info("Cannot delete {}", file.getAbsoluteFile(), e); } } - } InputStreamResource resource = new InputStreamResource(new NewFileInputStream(zipFile)); log.debug("REST request to get Statistics for ExerciseID : {}", exerciseId); Optional<StatisticsDTO> statisticsDTO = statisticsService.findOneByExerciseID(exerciseId); - if(statisticsDTO.isPresent()) { + if (statisticsDTO.isPresent()) { StatisticsDTO newStats = statisticsDTO.get(); newStats.setDownloads(newStats.getDownloads() + 1); statisticsService.save(newStats); @@ -223,8 +276,12 @@ public class ExerciseResource { log.debug("Created new statistics entry for exerciseID: {}", exerciseId); } - return ResponseEntity.ok().contentLength(zipFile.length()).contentType(MediaType.APPLICATION_OCTET_STREAM) - .header("filename", zipFile.getName()).body(resource); + return ResponseEntity + .ok() + .contentLength(zipFile.length()) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .header("filename", zipFile.getName()) + .body(resource); } /** @@ -239,9 +296,11 @@ public class ExerciseResource { * @throws URISyntaxException */ @GetMapping("/exercise/import") - public ResponseEntity<URI> importExerciseFromArtemis(@RequestParam("exerciseUrl") String exerciseUrl, - @RequestParam("apiKey") Optional<String> apiKey, - HttpServletRequest request) throws ArtemisImportError, MalformedURLException, URISyntaxException { + public ResponseEntity<URI> importExerciseFromArtemis( + @RequestParam("exerciseUrl") String exerciseUrl, + @RequestParam("apiKey") Optional<String> apiKey, + HttpServletRequest request + ) throws ArtemisImportError, MalformedURLException, URISyntaxException { if (apiKey.isPresent() && exerciseService.validate(apiKey.get())) { exerciseService.importExerciseFromArtemis(exerciseUrl); } else { @@ -262,10 +321,11 @@ public class ExerciseResource { * @throws IOException */ @GetMapping("/exercise/imported-exercise-info/{exerciseToken}") - public ResponseEntity<ArtemisExerciseInfo> getImportedExerciseInfo(@PathVariable("exerciseToken") String exerciseToken) throws IOException { + public ResponseEntity<ArtemisExerciseInfo> getImportedExerciseInfo(@PathVariable("exerciseToken") String exerciseToken) + throws IOException { if (SecurityUtils.isAuthenticated()) { try { - return ResponseEntity.ok(exerciseService.getArtemisExerciseInfo(exerciseToken)); + return ResponseEntity.ok(exerciseService.getArtemisExerciseInfo(exerciseToken)); } catch (NullPointerException npe) { return ResponseEntity.notFound().build(); } @@ -286,9 +346,11 @@ public class ExerciseResource { * @throws IOException */ @PostMapping("/exercise/import-exercise/{exerciseToken}/{gitlabGroupId}") - public Response importExercise(@RequestBody() ArtemisExerciseInfo exerciseInfo, - @PathVariable("exerciseToken") String exerciseToken, - @PathVariable("gitlabGroupId") Integer gitlabGroupId) throws GitLabApiException, GitAPIException, IOException, ArtemisImportError { + public Response importExercise( + @RequestBody ArtemisExerciseInfo exerciseInfo, + @PathVariable("exerciseToken") String exerciseToken, + @PathVariable("gitlabGroupId") Integer gitlabGroupId + ) throws GitLabApiException, GitAPIException, IOException, ArtemisImportError { if (SecurityUtils.isAuthenticated()) { exerciseService.importExercise(exerciseInfo, exerciseToken, gitlabGroupId); return Response.ok().build(); diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/GitFilesResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/GitFilesResource.java index 9c27564fa459bd8664aa089b305acb2c5ef5d11b..6305a3c6607d2cdff8d7263485084e69849051d3 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/GitFilesResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/GitFilesResource.java @@ -1,7 +1,9 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.es.model.DocumentInfo; +import at.ac.uibk.gitsearch.repository.search.GitFilesRepository; +import at.ac.uibk.gitsearch.service.dto.GitFilesAggregationDTO; import java.io.IOException; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -11,10 +13,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import at.ac.uibk.gitsearch.es.model.DocumentInfo; -import at.ac.uibk.gitsearch.repository.search.GitFilesRepository; -import at.ac.uibk.gitsearch.service.dto.GitFilesAggregationDTO; - /** * REST controller for managing {@link DocumentInfo}. */ diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/GitlabResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/GitlabResource.java index 6c6467a7ac1aa8f6111133f732831e76a57d5093..a9407f5daec9cb38f175fb570f8e23c112f19cf1 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/GitlabResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/GitlabResource.java @@ -1,7 +1,7 @@ package at.ac.uibk.gitsearch.web.rest; import at.ac.uibk.gitsearch.service.GitlabService; - +import java.util.List; import org.apache.http.auth.AuthenticationException; import org.gitlab4j.api.GitLabApiException; import org.gitlab4j.api.models.Group; @@ -13,14 +13,12 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.List; - @RestController @RequestMapping("/api/gitlab") public class GitlabResource { @SuppressWarnings("unused") - private final static Logger log = LoggerFactory.getLogger(GitlabResource.class); + private static final Logger log = LoggerFactory.getLogger(GitlabResource.class); private final GitlabService gitlabService; diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/LikesResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/LikesResource.java index 1ce66d3413902d00348e8699d1926e3dfe200c00..347c57aa4fa0cd5d3b89224d1b31c0c2a76de194 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/LikesResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/LikesResource.java @@ -1,14 +1,19 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.domain.Likes; +import at.ac.uibk.gitsearch.service.LikesQueryService; +import at.ac.uibk.gitsearch.service.LikesService; +import at.ac.uibk.gitsearch.service.SearchService; +import at.ac.uibk.gitsearch.service.UserService; +import at.ac.uibk.gitsearch.service.dto.LikesCriteria; +import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import java.net.URI; import java.net.URISyntaxException; import java.time.LocalDate; import java.util.List; import java.util.Optional; - import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -24,14 +29,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.HandlerMapping; - -import at.ac.uibk.gitsearch.domain.Likes; -import at.ac.uibk.gitsearch.service.LikesQueryService; -import at.ac.uibk.gitsearch.service.LikesService; -import at.ac.uibk.gitsearch.service.SearchService; -import at.ac.uibk.gitsearch.service.UserService; -import at.ac.uibk.gitsearch.service.dto.LikesCriteria; -import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import tech.jhipster.web.util.HeaderUtil; import tech.jhipster.web.util.ResponseUtil; @@ -55,7 +52,12 @@ public class LikesResource { private final LikesQueryService likesQueryService; - public LikesResource(LikesService likesService, LikesQueryService likesQueryService, UserService userService, SearchService searchService) { + public LikesResource( + LikesService likesService, + LikesQueryService likesQueryService, + UserService userService, + SearchService searchService + ) { this.likesService = likesService; this.likesQueryService = likesQueryService; this.userService = userService; @@ -80,9 +82,9 @@ public class LikesResource { } Likes result = likesService.save(likes); return ResponseEntity - .created(new URI("/api/likes/" + result.getId())).headers(HeaderUtil - .createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString())) - .body(result); + .created(new URI("/api/likes/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString())) + .body(result); } /** @@ -103,56 +105,58 @@ public class LikesResource { throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); } Likes result = likesService.save(likes); - return ResponseEntity.ok().headers( - HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, likes.getId().toString())) - .body(result); + return ResponseEntity + .ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, likes.getId().toString())) + .body(result); } @PutMapping("/likes/likeExercise") public ResponseEntity<Likes> updateLikeWithexerciseID(@RequestBody Likes likes) { - if (likes.getExerciseID() != null && searchService.hasAccessToExerciseId(likes.getExerciseID())) { + Likes like = likesService.findLikesByUserIDandExerciseID( + userService.getUserWithAuthorities().get().getId().intValue(), + likes.getExerciseID() + ); - Likes like = likesService.findLikesByUserIDandExerciseID(userService.getUserWithAuthorities().get().getId().intValue(), likes.getExerciseID()); - - if(like == null){ + if (like == null) { log.debug("Like not known atm creating new one"); like = new Likes(); like.setUserID(userService.getUserWithAuthorities().get().getId().intValue()); like.setExerciseID(likes.getExerciseID()); } - like.date(LocalDate.now()); - log.debug("REST request to update Like by exercise id : {}", likes.getExerciseID()); + like.date(LocalDate.now()); + log.debug("REST request to update Like by exercise id : {}", likes.getExerciseID()); - Likes result = likesService.save(like); - - return ResponseEntity.ok().headers( - HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, like.getId().toString())) - .body(result); - } - return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(applicationName,true,ENTITY_NAME,"internalServerError","The exerciseID was not set")).body(null); + Likes result = likesService.save(like); + return ResponseEntity + .ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, like.getId().toString())) + .body(result); + } + return ResponseEntity + .badRequest() + .headers(HeaderUtil.createFailureAlert(applicationName, true, ENTITY_NAME, "internalServerError", "The exerciseID was not set")) + .body(null); } @DeleteMapping("/likes/unlikeExercise/**") public ResponseEntity<Void> deleteLikeWithexerciseID(HttpServletRequest request) { + String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); - - String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); - - String exerciseID = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); + String exerciseID = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); log.debug("REST request to delete Likes for project : {}", exerciseID); likesService.deleteByUserIDandExerciseID(userService.getUserWithAuthorities().get().getId().intValue(), exerciseID); - return ResponseEntity.noContent() - .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, exerciseID)) - .build(); + return ResponseEntity + .noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, exerciseID)) + .build(); } - @GetMapping("/likes/numberOfLikes/**") public ResponseEntity<Integer> getNumberOfLikesForExerciseID(HttpServletRequest request) { - String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); String exerciseID = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); @@ -170,15 +174,19 @@ public class LikesResource { log.debug("REST request to see if user has liked project {}", exerciseID); Boolean bool = false; - if(userService.getUserWithAuthorities().isPresent()){ - Likes like = likesService.findLikesByUserIDandExerciseID(userService.getUserWithAuthorities().get().getId().intValue(), exerciseID); - if(like != null){ - log.debug("User has liked this project yet"); - bool = true; - }} + if (userService.getUserWithAuthorities().isPresent()) { + Likes like = likesService.findLikesByUserIDandExerciseID( + userService.getUserWithAuthorities().get().getId().intValue(), + exerciseID + ); + if (like != null) { + log.debug("User has liked this project yet"); + bool = true; + } + } return ResponseEntity.ok().body(bool); } - + /** * {@code GET /likes} : get all the likes. * @@ -234,22 +242,22 @@ public class LikesResource { public ResponseEntity<Void> deleteLikes(@PathVariable Long id) { log.debug("REST request to delete Likes : {}", id); likesService.delete(id); - return ResponseEntity.noContent() - .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())) - .build(); + return ResponseEntity + .noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())) + .build(); } - -// /** -// * {@code SEARCH /_search/likes?query=:query} : search for the likes -// * corresponding to the query. -// * -// * @param query the query of the likes search. -// * @return the result of the search. -// */ -// @GetMapping("/_search/likes") -// @PreAuthorize("hasAnyRole('ADMIN')") -// public List<Likes> searchLikes(@RequestParam String query) { -// log.debug("REST request to search Likes for query {}", query); -// return likesService.search(query); -// } + // /** + // * {@code SEARCH /_search/likes?query=:query} : search for the likes + // * corresponding to the query. + // * + // * @param query the query of the likes search. + // * @return the result of the search. + // */ + // @GetMapping("/_search/likes") + // @PreAuthorize("hasAnyRole('ADMIN')") + // public List<Likes> searchLikes(@RequestParam String query) { + // log.debug("REST request to search Likes for query {}", query); + // return likesService.search(query); + // } } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/OAuth2ConfigResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/OAuth2ConfigResource.java index 84bbe0bd2ce334dfc3a8bc45eeaf70a21012f227..c18dc075d9681d917edb3b42092588843172a88a 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/OAuth2ConfigResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/OAuth2ConfigResource.java @@ -1,5 +1,7 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.service.dto.OAuth2ConfigDTO; +import at.ac.uibk.gitsearch.service.oauth2.OAuth2ConfigService; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -7,9 +9,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import at.ac.uibk.gitsearch.service.dto.OAuth2ConfigDTO; -import at.ac.uibk.gitsearch.service.oauth2.OAuth2ConfigService; - /** * Controller to to provide OAuth2 configurations. */ @@ -17,21 +16,19 @@ import at.ac.uibk.gitsearch.service.oauth2.OAuth2ConfigService; @RequestMapping("/oauth2Config") public class OAuth2ConfigResource { - private OAuth2ConfigService oAuth2ConfigService; + private OAuth2ConfigService oAuth2ConfigService; public OAuth2ConfigResource(OAuth2ConfigService oAuth2ConfigService) { - this.oAuth2ConfigService = oAuth2ConfigService; + this.oAuth2ConfigService = oAuth2ConfigService; } @GetMapping("/config/{configId}") public ResponseEntity<OAuth2ConfigDTO> getOAuth2Config(@PathVariable(value = "configId") String configId) { - - return new ResponseEntity<>(oAuth2ConfigService.findByRegistrationId(configId), HttpStatus.OK); + return new ResponseEntity<>(oAuth2ConfigService.findByRegistrationId(configId), HttpStatus.OK); } - + @GetMapping("/allConfigs") public ResponseEntity<OAuth2ConfigDTO[]> getOAuth2Configs() { - return new ResponseEntity<>(oAuth2ConfigService.getPublicRegistrations(), HttpStatus.OK); + return new ResponseEntity<>(oAuth2ConfigService.getPublicRegistrations(), HttpStatus.OK); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/PluginInterfaceResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/PluginInterfaceResource.java index a03a511513250891a7d4a2cf19e99a7829a82c8b..89aa547c5bcf90ffaee41de402f19c6e84da48b9 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/PluginInterfaceResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/PluginInterfaceResource.java @@ -1,8 +1,13 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.es.model.DocumentInfo; +import at.ac.uibk.gitsearch.service.GitlabService; +import at.ac.uibk.gitsearch.service.SearchService; +import at.ac.uibk.gitsearch.service.ShoppingBasketService; +import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketInfoDTO; +import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirectInfoDTO; import java.io.IOException; import java.io.InputStream; - import org.codeability.sharing.plugins.api.ShoppingBasket; import org.codeability.sharing.plugins.api.search.SearchResultsDTO; import org.gitlab4j.api.GitLabApiException; @@ -25,13 +30,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; -import at.ac.uibk.gitsearch.es.model.DocumentInfo; -import at.ac.uibk.gitsearch.service.GitlabService; -import at.ac.uibk.gitsearch.service.SearchService; -import at.ac.uibk.gitsearch.service.ShoppingBasketService; -import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketInfoDTO; -import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirectInfoDTO; - /** * REST controller for managing {@link DocumentInfo}. */ @@ -40,33 +38,31 @@ import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirect @Transactional public class PluginInterfaceResource { - private final Logger log = LoggerFactory.getLogger(PluginInterfaceResource.class); + private final Logger log = LoggerFactory.getLogger(PluginInterfaceResource.class); - @Autowired - private ShoppingBasketService basketService; - @Autowired - private SearchService searchService; - @Autowired - private GitlabService gitlabService; - + @Autowired + private ShoppingBasketService basketService; + @Autowired + private SearchService searchService; + @Autowired + private GitlabService gitlabService; - /** - * assigns a shopping basket on server, and provides a redirect link together with the shopping basket token. - * This is called by the local frontend. - * It has no side effects, beside storing the shopping basket for a limited time frame and return it to the requesting - * service. - * @param basketInfo - * @return - */ - @PostMapping("/pluginIF/getPluginRedirectInfos") - public ShoppingBasketRedirectInfoDTO getRedirectInfos(@RequestBody ShoppingBasketInfoDTO basketInfo) { - final String baseUrl = - ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); - return basketService.getRedirectInfo(basketInfo, baseUrl); + /** + * assigns a shopping basket on server, and provides a redirect link together with the shopping basket token. + * This is called by the local frontend. + * It has no side effects, beside storing the shopping basket for a limited time frame and return it to the requesting + * service. + * @param basketInfo + * @return + */ + @PostMapping("/pluginIF/getPluginRedirectInfos") + public ShoppingBasketRedirectInfoDTO getRedirectInfos(@RequestBody ShoppingBasketInfoDTO basketInfo) { + final String baseUrl = ServletUriComponentsBuilder.fromCurrentContextPath().build().toUriString(); + return basketService.getRedirectInfo(basketInfo, baseUrl); } - + /** * {@code SEARCH /search/page-details} : search for the searchResults corresponding * to the query. @@ -75,52 +71,51 @@ public class PluginInterfaceResource { * @return the result of the search. */ @PostMapping("/pluginIF/v0.1/page-details") - public SearchResultsDTO - searchPageDetails(@RequestBody org.codeability.sharing.plugins.api.search.SearchRequestDTO searchRequest) throws IOException { - final Authentication gitLabAuthentication = gitlabService.getGitLabAuthentication(searchRequest.getUserPrincipal().getName(), searchRequest.getUserPrincipal().getGitLabAccessToken()); - SecurityContext sc = SecurityContextHolder.getContext(); - sc.setAuthentication(gitLabAuthentication); + public SearchResultsDTO searchPageDetails(@RequestBody org.codeability.sharing.plugins.api.search.SearchRequestDTO searchRequest) + throws IOException { + final Authentication gitLabAuthentication = gitlabService.getGitLabAuthentication( + searchRequest.getUserPrincipal().getName(), + searchRequest.getUserPrincipal().getGitLabAccessToken() + ); + SecurityContext sc = SecurityContextHolder.getContext(); + sc.setAuthentication(gitLabAuthentication); log.debug("REST request to search {}", searchRequest.getQuery()); - return searchService.searchResultPage(searchRequest.getQuery()); + return searchService.searchResultPage(searchRequest.getQuery()); } - @Mapper public static interface SearchResultsDTOMapper { - - SearchResultsDTOMapper INSTANCE = Mappers.getMapper( SearchResultsDTOMapper.class ); - - org.codeability.sharing.plugins.api.search.SearchResultsDTO searchResultsToPlugin(SearchResultsDTO searchResult); + SearchResultsDTOMapper INSTANCE = Mappers.getMapper(SearchResultsDTOMapper.class); + + org.codeability.sharing.plugins.api.search.SearchResultsDTO searchResultsToPlugin(SearchResultsDTO searchResult); } - /** * {@code SEARCH /search/page-details} : search for the searchResults corresponding * to the query. * - * @param query the query of the searchResult search. - * @return the result of the search. + * @param query the query of the searchResult search. + * @return the result of the search. */ - @GetMapping("/pluginIF/v0.1/basket/{basketToken}") - public ShoppingBasket getBasket( - @PathVariable("basketToken") String basketToken) throws IOException { + @GetMapping("/pluginIF/v0.1/basket/{basketToken}") + public ShoppingBasket getBasket(@PathVariable("basketToken") String basketToken) throws IOException { log.debug("REST request for basket {}", basketToken); return basketService.getBasket(basketToken); } - - @GetMapping("/pluginIF/v0.1/basket/{basketToken}/repository/{exerciseId}") + @GetMapping("/pluginIF/v0.1/basket/{basketToken}/repository/{exerciseId}") public ResponseEntity<?> getRepositoryZip(@PathVariable String basketToken, @PathVariable int exerciseId) throws IOException { - InputStream zip; - try { - zip = basketService.getRepositoryZip(basketToken, exerciseId); - } catch (GitLabApiException e) { - return ResponseEntity.unprocessableEntity().body(e.getMessage()); - } - InputStreamResource resource = new InputStreamResource(zip); - return ResponseEntity.ok().contentType(org.springframework.http.MediaType.APPLICATION_OCTET_STREAM).header("filename", "Repository"+exerciseId).body(resource); - + InputStream zip; + try { + zip = basketService.getRepositoryZip(basketToken, exerciseId); + } catch (GitLabApiException e) { + return ResponseEntity.unprocessableEntity().body(e.getMessage()); + } + InputStreamResource resource = new InputStreamResource(zip); + return ResponseEntity + .ok() + .contentType(org.springframework.http.MediaType.APPLICATION_OCTET_STREAM) + .header("filename", "Repository" + exerciseId) + .body(resource); } - - } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/PublicUserResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/PublicUserResource.java index 27cb1d85c58a9c24683af0f6af9c959864e7bc8e..6ffd9228e81c3a9c1491881067433714574a2371 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/PublicUserResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/PublicUserResource.java @@ -1,15 +1,17 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.config.Constants; +import at.ac.uibk.gitsearch.repository.search.UserSearchRepository; +import at.ac.uibk.gitsearch.service.UserService; +import at.ac.uibk.gitsearch.service.dto.UserDTO; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; import java.util.stream.StreamSupport; - import javax.validation.constraints.NotBlank; import javax.validation.constraints.Pattern; import javax.validation.constraints.Size; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -24,11 +26,6 @@ import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import at.ac.uibk.gitsearch.config.Constants; -import at.ac.uibk.gitsearch.repository.search.UserSearchRepository; -import at.ac.uibk.gitsearch.service.UserService; -import at.ac.uibk.gitsearch.service.dto.UserDTO; import tech.jhipster.web.util.PaginationUtil; @RestController @@ -44,49 +41,45 @@ public class PublicUserResource { * @author Michael Breu * */ - public static class PublicUserDTO { - private String login; - private String firstName; - private String lastName; - - - - public PublicUserDTO( - String login, - String firstName, - String lastName) { - super(); - this.login = login; - this.firstName = firstName; - this.lastName = lastName; - } - - public String getLogin() { - return login; - } - - public void setLogin(String login) { - this.login = login; - } - - public String getFirstName() { - return firstName; - } - - public void setFirstName(String firstName) { - this.firstName = firstName; - } - - public String getLastName() { - return lastName; - } - - public void setLastName(String lastName) { - this.lastName = lastName; - } - } - - private final Logger log = LoggerFactory.getLogger(PublicUserResource.class); + public static class PublicUserDTO { + + private String login; + private String firstName; + private String lastName; + + public PublicUserDTO(String login, String firstName, String lastName) { + super(); + this.login = login; + this.firstName = firstName; + this.lastName = lastName; + } + + public String getLogin() { + return login; + } + + public void setLogin(String login) { + this.login = login; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + } + + private final Logger log = LoggerFactory.getLogger(PublicUserResource.class); private final UserService userService; private final UserSearchRepository userSearchRepository; @@ -97,8 +90,9 @@ public class PublicUserResource { } private static PublicUserDTO fromUserDTO(UserDTO u) { - return new PublicUserDTO(u.getLogin(), u.getFirstName(), u.getLastName()); + return new PublicUserDTO(u.getLogin(), u.getFirstName(), u.getLastName()); } + /** * {@code GET /users} : get all users with only the public informations - calling this are allowed for anyone. * @@ -115,7 +109,7 @@ public class PublicUserResource { final Page<UserDTO> page = userService.getAllPublicUsers(pageable); Page<PublicUserDTO> ppage = page.map(PublicUserResource::fromUserDTO); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), ppage); - + return new ResponseEntity<>(ppage.getContent(), headers, HttpStatus.OK); } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/SearchResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/SearchResource.java index 69b1a648663f7e948f816844747b7afdf44c782a..516411d65685590de8e1e357eb7b72b1f31656c6 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/SearchResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/SearchResource.java @@ -1,5 +1,11 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.es.model.DocumentInfo; +import at.ac.uibk.gitsearch.service.SearchService; +import at.ac.uibk.gitsearch.service.StatisticsService; +import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; +import at.ac.uibk.gitsearch.web.util.HeaderUtil; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -8,7 +14,6 @@ import java.nio.file.Files; import java.text.ParseException; import java.util.List; import java.util.Optional; - import org.codeability.sharing.plugins.api.search.SearchResultsDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,13 +30,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import at.ac.uibk.gitsearch.es.model.DocumentInfo; -import at.ac.uibk.gitsearch.service.SearchService; -import at.ac.uibk.gitsearch.service.StatisticsService; -import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; -import at.ac.uibk.gitsearch.web.util.HeaderUtil; - /** * REST controller for managing {@link DocumentInfo}. */ @@ -40,8 +38,8 @@ import at.ac.uibk.gitsearch.web.util.HeaderUtil; @Transactional public class SearchResource { -// @Value("${jhipster.clientApp.name}") // warning: inconsistent rename of gitSearchApp to gitSearchV2App :-( - private final static String applicationName = "gitsearchApp"; + // @Value("${jhipster.clientApp.name}") // warning: inconsistent rename of gitSearchApp to gitSearchV2App :-( + private static final String applicationName = "gitsearchApp"; private static final String ENTITY_NAME = "SearchResource"; @@ -64,12 +62,12 @@ public class SearchResource { * @return the result of the search. */ @PostMapping("/search/page-details") - public SearchResultsDTO searchPageDetails(@RequestBody org.codeability.sharing.plugins.api.search.SearchInputDTO query) throws IOException { + public SearchResultsDTO searchPageDetails(@RequestBody org.codeability.sharing.plugins.api.search.SearchInputDTO query) + throws IOException { log.debug("REST request to search {}", query); return searchService.searchResultPage(query); } - /** * returns all keyword autocompletes for keyWord * @@ -79,11 +77,12 @@ public class SearchResource { * @throws IOException */ @GetMapping("/search/keywordsAutoComplete") - public List<AutoCompleteEntry> getKeywordsAutoComplete(@RequestParam String keyWordPrefix, @RequestParam(defaultValue = "10") int max) throws IOException { + public List<AutoCompleteEntry> getKeywordsAutoComplete(@RequestParam String keyWordPrefix, @RequestParam(defaultValue = "10") int max) + throws IOException { return searchService.getKeywordsAutoComplete(keyWordPrefix, max); } - /** + /** * returns all keyword autocompletes for keyWord * * @param formatPrefix @@ -92,7 +91,8 @@ public class SearchResource { * @throws IOException */ @GetMapping("/search/formatsAutoComplete") - public List<AutoCompleteEntry> getFormatsAutoComplete(@RequestParam String formatPrefix, @RequestParam(defaultValue = "10") int max) throws IOException { + public List<AutoCompleteEntry> getFormatsAutoComplete(@RequestParam String formatPrefix, @RequestParam(defaultValue = "10") int max) + throws IOException { return searchService.getFormatsAutoComplete(formatPrefix, max); } @@ -105,7 +105,8 @@ public class SearchResource { * @throws IOException */ @GetMapping("/search/creatorAutoComplete") - public List<AutoCompleteEntry> getCreatorAutoComplete(@RequestParam String creatorPrefix, @RequestParam(defaultValue = "10") int max) throws IOException { + public List<AutoCompleteEntry> getCreatorAutoComplete(@RequestParam String creatorPrefix, @RequestParam(defaultValue = "10") int max) + throws IOException { return searchService.getCreatorAutoComplete(creatorPrefix, max); } @@ -118,22 +119,26 @@ public class SearchResource { * @throws IOException */ @GetMapping("/search/contributorAutoComplete") - public List<AutoCompleteEntry> getContributorAutoComplete(@RequestParam String contributorPrefix, @RequestParam(defaultValue = "10") int max) throws IOException { + public List<AutoCompleteEntry> getContributorAutoComplete( + @RequestParam String contributorPrefix, + @RequestParam(defaultValue = "10") int max + ) throws IOException { return searchService.getContributorAutoComplete(contributorPrefix, max); } - /** - * returns all contributor and author autocompletes - * - * @param contributorPrefix + /** + * returns all contributor and author autocompletes + * + * @param contributorPrefix * @param max the maximum number of hits returned - * @return - * @throws IOException - */ + * @return + * @throws IOException + */ @GetMapping("/search/contributorCreatorAutoComplete") - public List<AutoCompleteEntry> getContributorCreatorAutoComplete(String contributorPrefix, @RequestParam(defaultValue = "10") int max) throws IOException { - return searchService.getContributorCreatorAutoComplete(contributorPrefix, max); - } + public List<AutoCompleteEntry> getContributorCreatorAutoComplete(String contributorPrefix, @RequestParam(defaultValue = "10") int max) + throws IOException { + return searchService.getContributorCreatorAutoComplete(contributorPrefix, max); + } /** * returns all programmingLanguage autocompletes for keyWord @@ -144,7 +149,10 @@ public class SearchResource { * @throws IOException */ @GetMapping("/search/programmingLanguageAutoComplete") - public List<AutoCompleteEntry> getProgrammingLanguageAutoComplete(@RequestParam String programmingLanguagePrefix, @RequestParam(defaultValue = "10") int max) throws IOException { + public List<AutoCompleteEntry> getProgrammingLanguageAutoComplete( + @RequestParam String programmingLanguagePrefix, + @RequestParam(defaultValue = "10") int max + ) throws IOException { return searchService.getProgrammingLanguageAutoComplete(programmingLanguagePrefix, max); } @@ -158,17 +166,25 @@ public class SearchResource { */ @PostMapping("/programming-exercises/{exerciseId}/export-programming-exercise") public ResponseEntity<Resource> exportProgrammingExercise(@PathVariable String exerciseId) throws IOException { - File zipFile = null; - try { - zipFile = searchService.exportExercise(exerciseId); - } catch (ParseException e) { - throw new IOException("Cannot parse " + exerciseId, e); - } + try { + zipFile = searchService.exportExercise(exerciseId); + } catch (ParseException e) { + throw new IOException("Cannot parse " + exerciseId, e); + } if (zipFile == null) { - return ResponseEntity.badRequest().headers(HeaderUtil.createFailureAlert(applicationName, true, ENTITY_NAME, - "internalServerError", "There was an error on the server and the zip file could not be created.")) - .body(null); + return ResponseEntity + .badRequest() + .headers( + HeaderUtil.createFailureAlert( + applicationName, + true, + ENTITY_NAME, + "internalServerError", + "There was an error on the server and the zip file could not be created." + ) + ) + .body(null); } /* @@ -187,19 +203,17 @@ public class SearchResource { public void close() throws IOException { super.close(); try { - Files.delete(file.toPath()); - } - catch(IOException e) { - log.info("Cannot delete {}", file.getAbsoluteFile(), e); + Files.delete(file.toPath()); + } catch (IOException e) { + log.info("Cannot delete {}", file.getAbsoluteFile(), e); } } - } InputStreamResource resource = new InputStreamResource(new NewFileInputStream(zipFile)); log.debug("REST request to get Statistics for ExerciseID : {}", exerciseId); Optional<StatisticsDTO> statisticsDTO = statisticsService.findOneByExerciseID(exerciseId); - if(statisticsDTO.isPresent()) { + if (statisticsDTO.isPresent()) { StatisticsDTO newStats = statisticsDTO.get(); newStats.setDownloads(newStats.getDownloads() + 1); statisticsService.save(newStats); @@ -214,8 +228,11 @@ public class SearchResource { log.debug("Created new statistics entry for exerciseID: {}", exerciseId); } - return ResponseEntity.ok().contentLength(zipFile.length()).contentType(MediaType.APPLICATION_OCTET_STREAM) - .header("filename", zipFile.getName()).body(resource); + return ResponseEntity + .ok() + .contentLength(zipFile.length()) + .contentType(MediaType.APPLICATION_OCTET_STREAM) + .header("filename", zipFile.getName()) + .body(resource); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/StatisticsResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/StatisticsResource.java index 2475438c0f50b8202efb9f4d7ab49d6ea33d7268..650707ca96ceedb27d635eae2d0bcad5946b0fa4 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/StatisticsResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/StatisticsResource.java @@ -1,15 +1,18 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.repository.StatisticsRepository; +import at.ac.uibk.gitsearch.service.SearchService; +import at.ac.uibk.gitsearch.service.StatisticsService; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; +import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import java.net.URI; import java.net.URISyntaxException; import java.text.ParseException; import java.util.List; import java.util.Optional; import java.util.regex.Pattern; - import javax.servlet.http.HttpServletRequest; import javax.validation.Valid; - import org.codeability.sharing.plugins.api.search.util.ExerciseId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,12 +33,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import at.ac.uibk.gitsearch.repository.StatisticsRepository; -import at.ac.uibk.gitsearch.service.SearchService; -import at.ac.uibk.gitsearch.service.StatisticsService; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; -import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import tech.jhipster.web.util.HeaderUtil; import tech.jhipster.web.util.PaginationUtil; import tech.jhipster.web.util.ResponseUtil; @@ -51,8 +48,8 @@ public class StatisticsResource { private static final String ENTITY_NAME = "statistics"; -// @Value("${jhipster.clientApp.name}") // warning: inconsistent rename of gitSearchApp to gitSearchV2App :-( - private final static String applicationName = "gitsearchApp"; + // @Value("${jhipster.clientApp.name}") // warning: inconsistent rename of gitSearchApp to gitSearchV2App :-( + private static final String applicationName = "gitsearchApp"; private final StatisticsService statisticsService; @@ -60,7 +57,7 @@ public class StatisticsResource { private final SearchService searchService; private final StatisticsRepository statisticsRepository; - + public StatisticsResource(StatisticsService statisticsService, SearchService searchService, StatisticsRepository statisticsRepository) { this.statisticsService = statisticsService; this.searchService = searchService; @@ -78,17 +75,16 @@ public class StatisticsResource { */ @PostMapping("/statistics") @PreAuthorize("hasAnyRole('ADMIN')") - public ResponseEntity<StatisticsDTO> createStatistics(@Valid @RequestBody StatisticsDTO statisticsDTO) - throws URISyntaxException { + public ResponseEntity<StatisticsDTO> createStatistics(@Valid @RequestBody StatisticsDTO statisticsDTO) throws URISyntaxException { log.debug("REST request to save Statistics : {}", statisticsDTO); if (statisticsDTO.getId() != null) { throw new BadRequestAlertException("A new statistics cannot already have an ID", ENTITY_NAME, "idexists"); } StatisticsDTO result = statisticsService.save(statisticsDTO); return ResponseEntity - .created(new URI("/api/statistics/" + result.getId())).headers(HeaderUtil - .createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString())) - .body(result); + .created(new URI("/api/statistics/" + result.getId())) + .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString())) + .body(result); } /** @@ -104,15 +100,16 @@ public class StatisticsResource { */ @PutMapping("/statistics") @PreAuthorize("hasAnyRole('ADMIN')") - public ResponseEntity<StatisticsDTO> updateStatistics(@Valid @RequestBody StatisticsDTO statisticsDTO) - throws URISyntaxException { + public ResponseEntity<StatisticsDTO> updateStatistics(@Valid @RequestBody StatisticsDTO statisticsDTO) throws URISyntaxException { log.debug("REST request to update Statistics : {}", statisticsDTO); if (statisticsDTO.getId() == null) { throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); } StatisticsDTO result = statisticsService.save(statisticsDTO); - return ResponseEntity.ok().headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, - statisticsDTO.getId().toString())).body(result); + return ResponseEntity + .ok() + .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, statisticsDTO.getId().toString())) + .body(result); } /** @@ -127,8 +124,7 @@ public class StatisticsResource { public ResponseEntity<List<StatisticsDTO>> getAllStatistics(Pageable pageable) { log.debug("REST request to get a page of Statistics"); Page<StatisticsDTO> page = statisticsService.findAll(pageable); - HttpHeaders headers = PaginationUtil - .generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); return ResponseEntity.ok().headers(headers).body(page.getContent()); } @@ -147,23 +143,22 @@ public class StatisticsResource { return ResponseUtil.wrapOrNotFound(statisticsDTO); } - protected static final Pattern ExerciseIdPattern = Pattern.compile("(\\d+):(.*)"); + /* getStatisticsByExerciseId is used to match the exerciseId of a Gitlab project with the database object for the statistics If a rest request for an exerciseId comes from the client and there is no object with a fitting exerciseId in the DB the server will create a new db entry with number of views as 1 and downloads as 0 */ - @GetMapping("/statistics/exercise/**") - public ResponseEntity<StatisticsDTO> getStatisticsByExerciseId(HttpServletRequest request) { - - String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); + @GetMapping("/statistics/exercise/**") + public ResponseEntity<StatisticsDTO> getStatisticsByExerciseId(HttpServletRequest request) { + String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); - String exerciseId = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); + String exerciseId = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); - log.debug("REST request to get Statistics for ExerciseID : {}", exerciseId); - Optional<StatisticsDTO> statisticsDTO = statisticsService.findOneByExerciseID(exerciseId); + log.debug("REST request to get Statistics for ExerciseID : {}", exerciseId); + Optional<StatisticsDTO> statisticsDTO = statisticsService.findOneByExerciseID(exerciseId); if (statisticsDTO.isPresent()) { StatisticsDTO newStats = statisticsDTO.get(); @@ -172,25 +167,25 @@ public class StatisticsResource { return ResponseUtil.wrapOrNotFound(Optional.of(newStats)); } - ExerciseId parsedId; - try { - parsedId = ExerciseId.fromString(exerciseId); - } catch (ParseException e) { - return ResponseUtil.wrapOrNotFound(statisticsDTO); - } - - if (searchService.findExerciseById(parsedId).isPresent()){ - StatisticsDTO newStats = new StatisticsDTO(); - newStats.setDownloads(0); - newStats.setViews(1); - newStats.setExerciseID(exerciseId); - statisticsService.save(newStats); - log.debug("Created new statistics entry for exerciseID: {}", exerciseId); - statisticsDTO = Optional.of(newStats); - return ResponseUtil.wrapOrNotFound(statisticsDTO); - } - return ResponseUtil.wrapOrNotFound(statisticsDTO); - } + ExerciseId parsedId; + try { + parsedId = ExerciseId.fromString(exerciseId); + } catch (ParseException e) { + return ResponseUtil.wrapOrNotFound(statisticsDTO); + } + + if (searchService.findExerciseById(parsedId).isPresent()) { + StatisticsDTO newStats = new StatisticsDTO(); + newStats.setDownloads(0); + newStats.setViews(1); + newStats.setExerciseID(exerciseId); + statisticsService.save(newStats); + log.debug("Created new statistics entry for exerciseID: {}", exerciseId); + statisticsDTO = Optional.of(newStats); + return ResponseUtil.wrapOrNotFound(statisticsDTO); + } + return ResponseUtil.wrapOrNotFound(statisticsDTO); + } /** * {@code DELETE /statistics/:id} : delete the "id" statistics. @@ -203,32 +198,32 @@ public class StatisticsResource { public ResponseEntity<Void> deleteStatistics(@PathVariable Long id) { log.debug("REST request to delete Statistics : {}", id); statisticsService.delete(id); - return ResponseEntity.noContent() - .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())) - .build(); + return ResponseEntity + .noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())) + .build(); } -// /** -// * {@code SEARCH /_search/statistics?query=:query} : search for the statistics -// * corresponding to the query. -// * -// * @param query the query of the statistics search. -// * @param pageable the pagination information. -// * @return the result of the search. -// */ -// @GetMapping("/_search/statistics") -// @PreAuthorize("hasAnyRole('ADMIN')") -// public ResponseEntity<List<StatisticsDTO>> searchStatistics(@RequestParam String query, Pageable pageable) { -// log.debug("REST request to search for a page of Statistics for query {}", query); -// Page<StatisticsDTO> page = statisticsService.search(query, pageable); -// HttpHeaders headers = PaginationUtil -// .generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); -// return ResponseEntity.ok().headers(headers).body(page.getContent()); -// } + // /** + // * {@code SEARCH /_search/statistics?query=:query} : search for the statistics + // * corresponding to the query. + // * + // * @param query the query of the statistics search. + // * @param pageable the pagination information. + // * @return the result of the search. + // */ + // @GetMapping("/_search/statistics") + // @PreAuthorize("hasAnyRole('ADMIN')") + // public ResponseEntity<List<StatisticsDTO>> searchStatistics(@RequestParam String query, Pageable pageable) { + // log.debug("REST request to search for a page of Statistics for query {}", query); + // Page<StatisticsDTO> page = statisticsService.search(query, pageable); + // HttpHeaders headers = PaginationUtil + // .generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + // return ResponseEntity.ok().headers(headers).body(page.getContent()); + // } @GetMapping("/statistics/numberOfWatchlistEntries/**") public ResponseEntity<Integer> getNumberOfWatchListEntriesForExerciseID(HttpServletRequest request) { - String pattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE); String exerciseID = new AntPathMatcher().extractPathWithinPattern(pattern, request.getRequestURI()); diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/UserJWTController.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/UserJWTController.java index bd066718edefe5ca31fef24a463840d60b59f3e9..78b7d4c33e33fb1d422a1e23394198448be9f002 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/UserJWTController.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/UserJWTController.java @@ -6,9 +6,7 @@ import at.ac.uibk.gitsearch.security.jwt.TokenProvider; import at.ac.uibk.gitsearch.service.UserService; import at.ac.uibk.gitsearch.web.rest.vm.LoginVM; import com.fasterxml.jackson.annotation.JsonProperty; - import java.util.Map; - import javax.validation.Valid; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; @@ -32,9 +30,11 @@ public class UserJWTController { private final AuthenticationManagerBuilder authenticationManagerBuilder; - public UserJWTController(TokenProvider tokenProvider, - AuthenticationManagerBuilder authenticationManagerBuilder, - UserService userService) { + public UserJWTController( + TokenProvider tokenProvider, + AuthenticationManagerBuilder authenticationManagerBuilder, + UserService userService + ) { this.tokenProvider = tokenProvider; this.authenticationManagerBuilder = authenticationManagerBuilder; this.userService = userService; @@ -42,9 +42,10 @@ public class UserJWTController { @PostMapping("/authenticate") public ResponseEntity<JWTToken> authorize(@Valid @RequestBody LoginVM loginVM) { - - UsernamePasswordAuthenticationToken authenticationToken = - new UsernamePasswordAuthenticationToken(loginVM.getUsername(), loginVM.getPassword()); + UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken( + loginVM.getUsername(), + loginVM.getPassword() + ); Authentication authentication = authenticationManagerBuilder.getObject().authenticate(authenticationToken); updateLastLogin(authentication); @@ -56,34 +57,34 @@ public class UserJWTController { return new ResponseEntity<>(new JWTToken(jwt), httpHeaders, HttpStatus.OK); } - private void updateLastLogin(Authentication authentication) { - if (authentication.getPrincipal() instanceof User) { - User user = (User) authentication.getPrincipal(); - userService.updateLastLogin(user.getId()); - } else if (authentication.getPrincipal() instanceof org.springframework.security.core.userdetails.User) { - org.springframework.security.core.userdetails.User user = (org.springframework.security.core.userdetails.User) authentication.getPrincipal(); - userService.updateLastLogin(user.getUsername()); - } - } - + private void updateLastLogin(Authentication authentication) { + if (authentication.getPrincipal() instanceof User) { + User user = (User) authentication.getPrincipal(); + userService.updateLastLogin(user.getId()); + } else if (authentication.getPrincipal() instanceof org.springframework.security.core.userdetails.User) { + org.springframework.security.core.userdetails.User user = (org.springframework.security.core.userdetails.User) authentication.getPrincipal(); + userService.updateLastLogin(user.getUsername()); + } + } + @PostMapping("/refreshToken") public ResponseEntity<JWTToken> refreshToken(@RequestParam("token") String token) { - if(!tokenProvider.validateToken(token)) { - return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED); - } else { - Authentication authentication = tokenProvider.getAuthentication(token); - @SuppressWarnings("unchecked") - Map<String, String> details = (Map<String, String>) authentication.getDetails(); - if(!details.containsKey(TokenProvider.PRE_TOKEN_CLAIM)) { - return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED); - } - updateLastLogin(authentication); - SecurityContextHolder.getContext().setAuthentication(authentication); - String jwt = tokenProvider.createToken(authentication, false); - HttpHeaders httpHeaders = new HttpHeaders(); - httpHeaders.add(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt); - return new ResponseEntity<>(new JWTToken(jwt), httpHeaders, HttpStatus.OK); - } + if (!tokenProvider.validateToken(token)) { + return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED); + } else { + Authentication authentication = tokenProvider.getAuthentication(token); + @SuppressWarnings("unchecked") + Map<String, String> details = (Map<String, String>) authentication.getDetails(); + if (!details.containsKey(TokenProvider.PRE_TOKEN_CLAIM)) { + return new ResponseEntity<>(null, HttpStatus.UNAUTHORIZED); + } + updateLastLogin(authentication); + SecurityContextHolder.getContext().setAuthentication(authentication); + String jwt = tokenProvider.createToken(authentication, false); + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add(JWTFilter.AUTHORIZATION_HEADER, "Bearer " + jwt); + return new ResponseEntity<>(new JWTToken(jwt), httpHeaders, HttpStatus.OK); + } } /** diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/UserResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/UserResource.java index 5fe25316d0fd2e5a46cc9ed2bcec27a2d58412e4..0e6f5679ff4f0e8c7b5f5e0027659ac7b24f4a64 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/UserResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/UserResource.java @@ -1,15 +1,23 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.config.Constants; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.repository.UserRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.service.MailService; +import at.ac.uibk.gitsearch.service.UserService; +import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; +import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; +import at.ac.uibk.gitsearch.web.rest.errors.EmailAlreadyUsedException; +import at.ac.uibk.gitsearch.web.rest.errors.LoginAlreadyUsedException; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Optional; - import javax.validation.Valid; import javax.validation.constraints.Pattern; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -29,17 +37,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import at.ac.uibk.gitsearch.config.Constants; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.repository.UserRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.service.MailService; -import at.ac.uibk.gitsearch.service.UserService; -import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; -import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; -import at.ac.uibk.gitsearch.web.rest.errors.EmailAlreadyUsedException; -import at.ac.uibk.gitsearch.web.rest.errors.LoginAlreadyUsedException; import tech.jhipster.web.util.HeaderUtil; import tech.jhipster.web.util.PaginationUtil; import tech.jhipster.web.util.ResponseUtil; diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/UserWatchListResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/UserWatchListResource.java index 95d2dca49e186165f5f280a5c943176420d1115b..1a6f16de26da2c4417e2b97b33bdfb5f4ded91e9 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/UserWatchListResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/UserWatchListResource.java @@ -1,13 +1,22 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.security.SecurityUtils; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; +import at.ac.uibk.gitsearch.service.SearchService; +import at.ac.uibk.gitsearch.service.UserService; +import at.ac.uibk.gitsearch.service.UserWatchListQueryService; +import at.ac.uibk.gitsearch.service.UserWatchListService; +import at.ac.uibk.gitsearch.service.WatchListEntryService; +import at.ac.uibk.gitsearch.service.dto.UserWatchListCriteria; +import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; +import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; +import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.Optional; - import javax.validation.Valid; - import org.codeability.sharing.plugins.api.search.SearchResultsDTO; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,18 +36,6 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import at.ac.uibk.gitsearch.security.SecurityUtils; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; -import at.ac.uibk.gitsearch.service.SearchService; -import at.ac.uibk.gitsearch.service.UserService; -import at.ac.uibk.gitsearch.service.UserWatchListQueryService; -import at.ac.uibk.gitsearch.service.UserWatchListService; -import at.ac.uibk.gitsearch.service.WatchListEntryService; -import at.ac.uibk.gitsearch.service.dto.UserWatchListCriteria; -import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; -import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; -import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import tech.jhipster.service.filter.LongFilter; import tech.jhipster.web.util.HeaderUtil; import tech.jhipster.web.util.PaginationUtil; @@ -55,24 +52,27 @@ public class UserWatchListResource { private static final String ENTITY_NAME = "userWatchList"; -// @Value("${jhipster.clientApp.name}") // warning: inconsistent rename of gitSearchApp to gitSearchV2App :-( - private final static String applicationName = "gitsearchApp"; + // @Value("${jhipster.clientApp.name}") // warning: inconsistent rename of gitSearchApp to gitSearchV2App :-( + private static final String applicationName = "gitsearchApp"; private final UserService userService; private final SearchService searchService; - + private final UserWatchListService userWatchListService; private final WatchListEntryService watchListEntryService; private final UserWatchListQueryService userWatchListQueryService; private final TokenProvider tokenProvider; - - public UserWatchListResource(UserWatchListService userWatchListService, - UserWatchListQueryService userWatchListQueryService, - TokenProvider tokenProvider, UserService userService, - SearchService searchService, - WatchListEntryService watchListEntryService) { + + public UserWatchListResource( + UserWatchListService userWatchListService, + UserWatchListQueryService userWatchListQueryService, + TokenProvider tokenProvider, + UserService userService, + SearchService searchService, + WatchListEntryService watchListEntryService + ) { this.userWatchListService = userWatchListService; this.userWatchListQueryService = userWatchListQueryService; this.tokenProvider = tokenProvider; @@ -89,26 +89,30 @@ public class UserWatchListResource { * @throws URISyntaxException if the Location URI syntax is incorrect. */ @PostMapping("/user-watch-lists") - public ResponseEntity<UserWatchListDTO> createUserWatchList(@Valid @RequestBody UserWatchListDTO userWatchListDTO) throws URISyntaxException { + public ResponseEntity<UserWatchListDTO> createUserWatchList(@Valid @RequestBody UserWatchListDTO userWatchListDTO) + throws URISyntaxException { log.debug("REST request to save UserWatchList : {}", userWatchListDTO); - if(tokenProvider.getCurrentPrincipal().isEmpty()) { - log.debug("unknown user cannot create watchlist {}", userWatchListDTO.getName()); - return ResponseEntity.badRequest().build(); - } - if(userWatchListDTO.getUserId() == null) { - Optional<at.ac.uibk.gitsearch.domain.User> u = userService.getUserWithAuthoritiesByLogin(SecurityUtils.getCurrentUserLogin().get()); - if(u.isEmpty()) { - log.debug(" user not found, cannot create watchlist {}", userWatchListDTO.getName()); - return ResponseEntity.badRequest().build(); - } - userWatchListDTO.setUserId(u.get().getId()); - userWatchListDTO.setUserLogin(u.get().getLastName()); - } + if (tokenProvider.getCurrentPrincipal().isEmpty()) { + log.debug("unknown user cannot create watchlist {}", userWatchListDTO.getName()); + return ResponseEntity.badRequest().build(); + } + if (userWatchListDTO.getUserId() == null) { + Optional<at.ac.uibk.gitsearch.domain.User> u = userService.getUserWithAuthoritiesByLogin( + SecurityUtils.getCurrentUserLogin().get() + ); + if (u.isEmpty()) { + log.debug(" user not found, cannot create watchlist {}", userWatchListDTO.getName()); + return ResponseEntity.badRequest().build(); + } + userWatchListDTO.setUserId(u.get().getId()); + userWatchListDTO.setUserLogin(u.get().getLastName()); + } if (userWatchListDTO.getId() != null) { throw new BadRequestAlertException("A new userWatchList cannot already have an ID", ENTITY_NAME, "idexists"); } UserWatchListDTO result = userWatchListService.save(userWatchListDTO); - return ResponseEntity.created(new URI("/api/user-watch-lists/" + result.getId())) + return ResponseEntity + .created(new URI("/api/user-watch-lists/" + result.getId())) .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString())) .body(result); } @@ -121,26 +125,30 @@ public class UserWatchListResource { * @throws URISyntaxException if the Location URI syntax is incorrect. */ @PostMapping("/currentuser-watch-lists") - public ResponseEntity<UserWatchListDTO> createWatchListForCurrentUser(@Valid @RequestBody UserWatchListDTO userWatchListDTO) throws URISyntaxException { + public ResponseEntity<UserWatchListDTO> createWatchListForCurrentUser(@Valid @RequestBody UserWatchListDTO userWatchListDTO) + throws URISyntaxException { log.debug("REST request to save UserWatchList for current User: {}", userWatchListDTO); if (userWatchListDTO.getId() != null) { throw new BadRequestAlertException("A new userWatchList cannot already have an ID", ENTITY_NAME, "idexists"); } final Optional<User> currentUser = tokenProvider.getCurrentPrincipal(); - if(currentUser.isEmpty()) { - log.warn("Cannot create a watchlist {} for unknown user", userWatchListDTO.getName()); + if (currentUser.isEmpty()) { + log.warn("Cannot create a watchlist {} for unknown user", userWatchListDTO.getName()); throw new BadRequestAlertException("Cannot create a watchlist for unknown user", ENTITY_NAME, "unknownUser"); } User springUser = currentUser.get(); - final Optional<at.ac.uibk.gitsearch.domain.User> userWithAuthoritiesByLogin = userService.getUserWithAuthoritiesByLogin(springUser.getUsername()); - if(userWithAuthoritiesByLogin.isEmpty()) { - log.warn("Cannot create a watchlist {} for unknown user", springUser.getUsername()); + final Optional<at.ac.uibk.gitsearch.domain.User> userWithAuthoritiesByLogin = userService.getUserWithAuthoritiesByLogin( + springUser.getUsername() + ); + if (userWithAuthoritiesByLogin.isEmpty()) { + log.warn("Cannot create a watchlist {} for unknown user", springUser.getUsername()); throw new BadRequestAlertException("Cannot create a watchlist for unknown user", ENTITY_NAME, "unknownUser"); } userWatchListDTO.setUserLogin(springUser.getUsername()); - userWatchListDTO.setUserId(userWithAuthoritiesByLogin.get().getId()); + userWatchListDTO.setUserId(userWithAuthoritiesByLogin.get().getId()); UserWatchListDTO result = userWatchListService.save(userWatchListDTO); - return ResponseEntity.created(new URI("/api/user-watch-lists/" + result.getId())) + return ResponseEntity + .created(new URI("/api/user-watch-lists/" + result.getId())) .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString())) .body(result); } @@ -155,19 +163,21 @@ public class UserWatchListResource { * @throws URISyntaxException if the Location URI syntax is incorrect. */ @PutMapping("/user-watch-lists") - public ResponseEntity<UserWatchListDTO> updateUserWatchList(@Valid @RequestBody UserWatchListDTO userWatchListDTO) throws URISyntaxException { + public ResponseEntity<UserWatchListDTO> updateUserWatchList(@Valid @RequestBody UserWatchListDTO userWatchListDTO) + throws URISyntaxException { log.debug("REST request to update UserWatchList : {}", userWatchListDTO); Long id = userWatchListDTO.getId(); if (id == null) { throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); } - try { - userWatchListService.checkAccessToWatchList(id, "searchExercisesOnWatchlist", true); - } catch (IllegalAccessError e) { + try { + userWatchListService.checkAccessToWatchList(id, "searchExercisesOnWatchlist", true); + } catch (IllegalAccessError e) { throw new BadRequestAlertException("Empty id", ENTITY_NAME, ""); - } + } UserWatchListDTO result = userWatchListService.save(userWatchListDTO); - return ResponseEntity.ok() + return ResponseEntity + .ok() .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, userWatchListDTO.getId().toString())) .body(result); } @@ -199,14 +209,16 @@ public class UserWatchListResource { public ResponseEntity<List<UserWatchListDTO>> getUserWatchListsOfCurrentUser(UserWatchListCriteria criteria, Pageable pageable) { log.debug("REST request to get CurrentUserWatchLists by criteria: {}", criteria); final Optional<at.ac.uibk.gitsearch.domain.User> currentUser = userService.getUserWithAuthorities(); - if(currentUser.isEmpty()) { - return ResponseEntity.notFound().headers(HeaderUtil.createFailureAlert(applicationName, true, "User", "not found", - "There was an error: User not found.")).build(); + if (currentUser.isEmpty()) { + return ResponseEntity + .notFound() + .headers(HeaderUtil.createFailureAlert(applicationName, true, "User", "not found", "There was an error: User not found.")) + .build(); } final LongFilter userIdFilter = new LongFilter(); userIdFilter.setEquals(currentUser.get().getId()); - - criteria.setUserId(userIdFilter); + + criteria.setUserId(userIdFilter); Page<UserWatchListDTO> page = userWatchListQueryService.findByCriteria(criteria, pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); return ResponseEntity.ok().headers(headers).body(page.getContent()); @@ -233,7 +245,7 @@ public class UserWatchListResource { */ @GetMapping("/user-watch-lists/{id}") public ResponseEntity<UserWatchListDTO> getUserWatchList(@PathVariable Long id) { - userWatchListService.checkAccessToWatchList(id, "searchExercisesOnWatchlist", false); + userWatchListService.checkAccessToWatchList(id, "searchExercisesOnWatchlist", false); log.debug("REST request to get UserWatchList : {}", id); Optional<UserWatchListDTO> userWatchListDTO = userWatchListService.findOne(id); return ResponseUtil.wrapOrNotFound(userWatchListDTO); @@ -247,10 +259,13 @@ public class UserWatchListResource { */ @DeleteMapping("/user-watch-lists/{id}") public ResponseEntity<Void> deleteUserWatchList(@PathVariable Long id) { - userWatchListService.checkAccessToWatchList(id, "searchExercisesOnWatchlist", true); + userWatchListService.checkAccessToWatchList(id, "searchExercisesOnWatchlist", true); log.debug("REST request to delete UserWatchList : {}", id); userWatchListService.delete(id); - return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())).build(); + return ResponseEntity + .noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())) + .build(); } /** @@ -268,8 +283,8 @@ public class UserWatchListResource { Page<UserWatchListDTO> page = userWatchListService.search(query, pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); return ResponseEntity.ok().headers(headers).body(page.getContent()); - } - + } + /** * {@code SEARCH /_search/user-watch-lists?query=:query} : search for the userWatchList of the current user corresponding * to the query. @@ -284,15 +299,13 @@ public class UserWatchListResource { Page<UserWatchListDTO> page = userWatchListService.searchForCurrentUser(query, pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); return ResponseEntity.ok().headers(headers).body(page.getContent()); - } + } @PostMapping("/currentuser-watch-lists/{id}") - public SearchResultsDTO - searchExercisesOnWatchlist(@PathVariable Long id, @RequestBody Integer page) throws IOException { - if(page == null) page = 0; - userWatchListService.checkAccessToWatchList(id, "searchExercisesOnWatchlist", true); - final List<WatchListEntryDTO> entriesForWatchlist = watchListEntryService.getEntriesForWatchlist(id); + public SearchResultsDTO searchExercisesOnWatchlist(@PathVariable Long id, @RequestBody Integer page) throws IOException { + if (page == null) page = 0; + userWatchListService.checkAccessToWatchList(id, "searchExercisesOnWatchlist", true); + final List<WatchListEntryDTO> entriesForWatchlist = watchListEntryService.getEntriesForWatchlist(id); return searchService.watchListResultPage(entriesForWatchlist.stream().map(WatchListEntryDTO::getExerciseId), page, 10); } - } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/rest/WatchListEntryResource.java b/src/main/java/at/ac/uibk/gitsearch/web/rest/WatchListEntryResource.java index e2e576b29c2d4260a7fe72d3ba4aece5d89b484b..ae5559e19801e69111214226055b14e1f1ff5780 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/rest/WatchListEntryResource.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/rest/WatchListEntryResource.java @@ -1,12 +1,15 @@ package at.ac.uibk.gitsearch.web.rest; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; +import at.ac.uibk.gitsearch.service.UserWatchListService; +import at.ac.uibk.gitsearch.service.WatchListEntryService; +import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; +import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import java.net.URI; import java.net.URISyntaxException; import java.util.List; import java.util.Optional; - import javax.validation.Valid; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; @@ -22,12 +25,6 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.support.ServletUriComponentsBuilder; - -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; -import at.ac.uibk.gitsearch.service.UserWatchListService; -import at.ac.uibk.gitsearch.service.WatchListEntryService; -import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; -import at.ac.uibk.gitsearch.web.rest.errors.BadRequestAlertException; import tech.jhipster.web.util.HeaderUtil; import tech.jhipster.web.util.PaginationUtil; import tech.jhipster.web.util.ResponseUtil; @@ -43,13 +40,17 @@ public class WatchListEntryResource { private static final String ENTITY_NAME = "watchListEntry"; -// @Value("${jhipster.clientApp.name}") // warning: inconsistent rename of gitSearchApp to gitSearchV2App :-( - private final static String applicationName = "gitsearchApp"; + // @Value("${jhipster.clientApp.name}") // warning: inconsistent rename of gitSearchApp to gitSearchV2App :-( + private static final String applicationName = "gitsearchApp"; private final WatchListEntryService watchListEntryService; private final UserWatchListService userWatchListService; - public WatchListEntryResource(WatchListEntryService watchListEntryService, UserWatchListService userWatchListService, TokenProvider tokenProvider) { + public WatchListEntryResource( + WatchListEntryService watchListEntryService, + UserWatchListService userWatchListService, + TokenProvider tokenProvider + ) { this.watchListEntryService = watchListEntryService; this.userWatchListService = userWatchListService; } @@ -62,13 +63,15 @@ public class WatchListEntryResource { * @throws URISyntaxException if the Location URI syntax is incorrect. */ @PostMapping("/watch-list-entries") - public ResponseEntity<WatchListEntryDTO> createWatchListEntry(@Valid @RequestBody WatchListEntryDTO watchListEntryDTO) throws URISyntaxException { + public ResponseEntity<WatchListEntryDTO> createWatchListEntry(@Valid @RequestBody WatchListEntryDTO watchListEntryDTO) + throws URISyntaxException { log.debug("REST request to save WatchListEntry : {}", watchListEntryDTO); if (watchListEntryDTO.getId() != null) { throw new BadRequestAlertException("A new watchListEntry cannot already have an ID", ENTITY_NAME, "idexists"); } WatchListEntryDTO result = watchListEntryService.save(watchListEntryDTO); - return ResponseEntity.created(new URI("/api/watch-list-entries/" + result.getId())) + return ResponseEntity + .created(new URI("/api/watch-list-entries/" + result.getId())) .headers(HeaderUtil.createEntityCreationAlert(applicationName, true, ENTITY_NAME, result.getId().toString())) .body(result); } @@ -81,13 +84,13 @@ public class WatchListEntryResource { * @throws URISyntaxException if the Location URI syntax is incorrect. */ @PostMapping("/currentuser-watch-list-entries") - public ResponseEntity<WatchListEntryDTO> createWatchListEntryForCurrentUser(@Valid @RequestBody WatchListEntryDTO watchListEntryDTO) throws URISyntaxException { - userWatchListService.checkAccessToWatchList(watchListEntryDTO.getWatchlistId(), watchListEntryDTO.getExerciseName(), false); + public ResponseEntity<WatchListEntryDTO> createWatchListEntryForCurrentUser(@Valid @RequestBody WatchListEntryDTO watchListEntryDTO) + throws URISyntaxException { + userWatchListService.checkAccessToWatchList(watchListEntryDTO.getWatchlistId(), watchListEntryDTO.getExerciseName(), false); - return createWatchListEntry(watchListEntryDTO); + return createWatchListEntry(watchListEntryDTO); } - /** * {@code PUT /watch-list-entries} : Updates an existing watchListEntry. * @@ -98,13 +101,15 @@ public class WatchListEntryResource { * @throws URISyntaxException if the Location URI syntax is incorrect. */ @PutMapping("/watch-list-entries") - public ResponseEntity<WatchListEntryDTO> updateWatchListEntry(@Valid @RequestBody WatchListEntryDTO watchListEntryDTO) throws URISyntaxException { + public ResponseEntity<WatchListEntryDTO> updateWatchListEntry(@Valid @RequestBody WatchListEntryDTO watchListEntryDTO) + throws URISyntaxException { log.debug("REST request to update WatchListEntry : {}", watchListEntryDTO); if (watchListEntryDTO.getId() == null) { throw new BadRequestAlertException("Invalid id", ENTITY_NAME, "idnull"); } WatchListEntryDTO result = watchListEntryService.save(watchListEntryDTO); - return ResponseEntity.ok() + return ResponseEntity + .ok() .headers(HeaderUtil.createEntityUpdateAlert(applicationName, true, ENTITY_NAME, watchListEntryDTO.getId().toString())) .body(result); } @@ -146,43 +151,51 @@ public class WatchListEntryResource { public ResponseEntity<Void> deleteWatchListEntry(@PathVariable Long id) { log.debug("REST request to delete WatchListEntry : {}", id); watchListEntryService.delete(id); - return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())).build(); + return ResponseEntity + .noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, id.toString())) + .build(); } -// /** -// * {@code SEARCH /_search/watch-list-entries?query=:query} : search for the watchListEntry corresponding -// * to the query. -// * -// * @param query the query of the watchListEntry search. -// * @param pageable the pagination information. -// * @return the result of the search. -// */ -// @GetMapping("/_search/watch-list-entries") -// public ResponseEntity<List<WatchListEntryDTO>> searchWatchListEntries(@RequestParam String query, -// Pageable pageable) { -// log.debug("REST request to search for a page of WatchListEntries for query {}", query); -// Page<WatchListEntryDTO> page = watchListEntryService.search(query, pageable); -// HttpHeaders headers = PaginationUtil -// .generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); -// return ResponseEntity.ok().headers(headers).body(page.getContent()); -// } - - @GetMapping("/user-watch-lists/{id}/entries") - public ResponseEntity<List<WatchListEntryDTO>> getWatchListEntries(@PathVariable Long id) { - return ResponseEntity.ok().body(watchListEntryService.getEntriesForWatchlist(id)); - } - - @GetMapping("/currentuser-watch-lists/{id}/entries") - public ResponseEntity<List<WatchListEntryDTO>> getWatchListEntriesIfCurrentUser(@PathVariable Long id) { - userWatchListService.checkAccessToWatchList(id, "getWatchlist", true); - return getWatchListEntries(id); - } - - @DeleteMapping("/currentuser-watch-lists/{watchListId}/entries/{exerciseId}") - public ResponseEntity<Void> deleteWatchListEntryIfCurrentUser( - @PathVariable("watchListId") Long watchListId, @PathVariable String exerciseId) { - userWatchListService.checkAccessToWatchList(watchListId, "deleteOnWatchlist", true); + // /** + // * {@code SEARCH /_search/watch-list-entries?query=:query} : search for the watchListEntry corresponding + // * to the query. + // * + // * @param query the query of the watchListEntry search. + // * @param pageable the pagination information. + // * @return the result of the search. + // */ + // @GetMapping("/_search/watch-list-entries") + // public ResponseEntity<List<WatchListEntryDTO>> searchWatchListEntries(@RequestParam String query, + // Pageable pageable) { + // log.debug("REST request to search for a page of WatchListEntries for query {}", query); + // Page<WatchListEntryDTO> page = watchListEntryService.search(query, pageable); + // HttpHeaders headers = PaginationUtil + // .generatePaginationHttpHeaders(ServletUriComponentsBuilder.fromCurrentRequest(), page); + // return ResponseEntity.ok().headers(headers).body(page.getContent()); + // } + + @GetMapping("/user-watch-lists/{id}/entries") + public ResponseEntity<List<WatchListEntryDTO>> getWatchListEntries(@PathVariable Long id) { + return ResponseEntity.ok().body(watchListEntryService.getEntriesForWatchlist(id)); + } + + @GetMapping("/currentuser-watch-lists/{id}/entries") + public ResponseEntity<List<WatchListEntryDTO>> getWatchListEntriesIfCurrentUser(@PathVariable Long id) { + userWatchListService.checkAccessToWatchList(id, "getWatchlist", true); + return getWatchListEntries(id); + } + + @DeleteMapping("/currentuser-watch-lists/{watchListId}/entries/{exerciseId}") + public ResponseEntity<Void> deleteWatchListEntryIfCurrentUser( + @PathVariable("watchListId") Long watchListId, + @PathVariable String exerciseId + ) { + userWatchListService.checkAccessToWatchList(watchListId, "deleteOnWatchlist", true); watchListEntryService.deleteInWatchlist(watchListId, exerciseId); - return ResponseEntity.noContent().headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, exerciseId)).build(); - } + return ResponseEntity + .noContent() + .headers(HeaderUtil.createEntityDeletionAlert(applicationName, true, ENTITY_NAME, exerciseId)) + .build(); + } } diff --git a/src/main/java/at/ac/uibk/gitsearch/web/util/HeaderUtil.java b/src/main/java/at/ac/uibk/gitsearch/web/util/HeaderUtil.java index 2c98b61b5ed68f840f72575d3dbe502c6409ba3f..6e31345351e812354309406b478c2c8474c47c6c 100644 --- a/src/main/java/at/ac/uibk/gitsearch/web/util/HeaderUtil.java +++ b/src/main/java/at/ac/uibk/gitsearch/web/util/HeaderUtil.java @@ -10,15 +10,25 @@ import org.springframework.http.HttpHeaders; public final class HeaderUtil { @SuppressWarnings("unused") - private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class); + private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class); - private HeaderUtil() { - } + private HeaderUtil() {} - public static HttpHeaders createFailureAlert(String applicationName, boolean enableTranslation, String entityName, String errorKey, String defaultMessage) { - HttpHeaders headers = tech.jhipster.web.util.HeaderUtil.createFailureAlert(applicationName, enableTranslation, entityName, errorKey, defaultMessage); + public static HttpHeaders createFailureAlert( + String applicationName, + boolean enableTranslation, + String entityName, + String errorKey, + String defaultMessage + ) { + HttpHeaders headers = tech.jhipster.web.util.HeaderUtil.createFailureAlert( + applicationName, + enableTranslation, + entityName, + errorKey, + defaultMessage + ); headers.add("X-" + applicationName + "-message", defaultMessage); return headers; } - -} \ No newline at end of file +} diff --git a/src/main/resources/META-INF/additional-spring-configuration-metadata.json b/src/main/resources/META-INF/additional-spring-configuration-metadata.json index aa370797fbfaa7f72fa747b294f6a52b305e560d..b72423a742507f7a3821df97e531da94da0b4e88 100644 --- a/src/main/resources/META-INF/additional-spring-configuration-metadata.json +++ b/src/main/resources/META-INF/additional-spring-configuration-metadata.json @@ -1,7 +1,9 @@ -{"properties": [ - { - "name": "spring.security.oauth2.client.gitlabOidc.icon", - "type": "java.lang.String", - "description": "custom configurations: Icon for oauth2 client" - } -]} \ No newline at end of file +{ + "properties": [ + { + "name": "spring.security.oauth2.client.gitlabOidc.icon", + "type": "java.lang.String", + "description": "custom configurations: Icon for oauth2 client" + } + ] +} diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml index 9ec7066f7e53bf630847ba4157e4c757a7f65948..5dac210fe4c1b404b52c50fece113c41c3151e43 100644 --- a/src/main/resources/config/application.yml +++ b/src/main/resources/config/application.yml @@ -221,6 +221,6 @@ application: guestAccessToken: secreit adminAccessToken: secret deployment-info: - commit-id: "${gitCommitId}" - branch: "${gitBranch}" - deploymentDate: ${gitCommitDate} \ No newline at end of file + commit-id: '${gitCommitId}' + branch: '${gitBranch}' + deploymentDate: ${gitCommitDate} diff --git a/src/main/resources/swagger-ts-generator/generate.js b/src/main/resources/swagger-ts-generator/generate.js index 26efd3340af8fc20274055dac439bb483c36fb38..c614730056e951f7c19af58c8ddd19c0a3ddf675 100644 --- a/src/main/resources/swagger-ts-generator/generate.js +++ b/src/main/resources/swagger-ts-generator/generate.js @@ -1,16 +1,629 @@ /* eslint @typescript-eslint/no-var-requires: "off" */ const { generateTSFiles } = require('swagger-ts-generator'); - + // const config = { // file: __dirname + '\\swagger.json' // }; - + generateTSFiles( - // Better read from URL http://localhost:8080/v2/api-docs - {"swagger":"2.0","info":{"description":"gitsearch API documentation","version":"0.1.0","title":"gitsearch API","contact":{},"license":{"name":"unlicensed"}},"host":"localhost:8080","basePath":"/","tags":[{"name":"account-resource","description":"Account Resource"},{"name":"git-files-resource","description":"Git Files Resource"},{"name":"search-resource","description":"Search Resource"},{"name":"user-jwt-controller","description":"User JWT Controller"},{"name":"user-resource","description":"User Resource"}],"schemes":["http","https"],"paths":{"/api/_search/git-files/aggregation":{"get":{"tags":["git-files-resource"],"summary":"gitFilesAggregation","operationId":"gitFilesAggregationUsingGET","produces":["*/*"],"parameters":[{"name":"query","in":"query","description":"query","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/GitFilesAggregationDTO"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/_search/git-files/page-details":{"get":{"tags":["git-files-resource"],"summary":"gitFilesPageDetails","operationId":"gitFilesPageDetailsUsingGET","produces":["*/*"],"parameters":[{"name":"fulltextQuery","in":"query","description":"fulltextQuery","required":true,"type":"string"},{"name":"metadataAuthor","in":"query","description":"metadataAuthor","required":true,"type":"string"},{"name":"metadataKeywords","in":"query","description":"metadataKeywords","required":true,"type":"string"},{"name":"metadataLicense","in":"query","description":"metadataLicense","required":true,"type":"string"},{"name":"metadataNaturalLanguage","in":"query","description":"metadataNaturalLanguage","required":true,"type":"string"},{"name":"metadataProgrammingLanguage","in":"query","description":"metadataProgrammingLanguage","required":true,"type":"string"},{"name":"page","in":"query","description":"page","required":true,"type":"integer","format":"int32"},{"name":"pageSize","in":"query","description":"pageSize","required":true,"type":"integer","format":"int32"},{"name":"selectedFileFormat","in":"query","description":"selectedFileFormat","required":true,"type":"array","items":{"type":"string"},"collectionFormat":"multi"},{"name":"selectedRepository","in":"query","description":"selectedRepository","required":true,"type":"array","items":{"type":"string"},"collectionFormat":"multi"},{"name":"selectedUniversity","in":"query","description":"selectedUniversity","required":true,"type":"array","items":{"type":"string"},"collectionFormat":"multi"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/GitFilesPageDetailsDTO"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/_search/users/{query}":{"get":{"tags":["user-resource"],"summary":"search","operationId":"searchUsingGET","produces":["*/*"],"parameters":[{"name":"query","in":"path","description":"query","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/User"}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/account":{"get":{"tags":["account-resource"],"summary":"getAccount","operationId":"getAccountUsingGET","produces":["*/*"],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/UserDTO"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false},"post":{"tags":["account-resource"],"summary":"saveAccount","operationId":"saveAccountUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"userDTO","description":"userDTO","required":true,"schema":{"$ref":"#/definitions/UserDTO"}}],"responses":{"200":{"description":"OK"},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/account/change-password":{"post":{"tags":["account-resource"],"summary":"changePassword","operationId":"changePasswordUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"passwordChangeDto","description":"passwordChangeDto","required":true,"schema":{"$ref":"#/definitions/PasswordChangeDTO"}}],"responses":{"200":{"description":"OK"},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/account/reset-password/finish":{"post":{"tags":["account-resource"],"summary":"finishPasswordReset","operationId":"finishPasswordResetUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"keyAndPassword","description":"keyAndPassword","required":true,"schema":{"$ref":"#/definitions/KeyAndPasswordVM"}}],"responses":{"200":{"description":"OK"},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/account/reset-password/init":{"post":{"tags":["account-resource"],"summary":"requestPasswordReset","operationId":"requestPasswordResetUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"mail","description":"mail","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/activate":{"get":{"tags":["account-resource"],"summary":"activateAccount","operationId":"activateAccountUsingGET","produces":["*/*"],"parameters":[{"name":"key","in":"query","description":"key","required":true,"type":"string"}],"responses":{"200":{"description":"OK"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/authenticate":{"get":{"tags":["account-resource"],"summary":"isAuthenticated","operationId":"isAuthenticatedUsingGET","produces":["*/*"],"responses":{"200":{"description":"OK","schema":{"type":"string"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false},"post":{"tags":["user-jwt-controller"],"summary":"authorize","operationId":"authorizeUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"loginVM","description":"loginVM","required":true,"schema":{"$ref":"#/definitions/LoginVM"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/JWTToken"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/register":{"post":{"tags":["account-resource"],"summary":"registerAccount","operationId":"registerAccountUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"managedUserVM","description":"managedUserVM","required":true,"schema":{"$ref":"#/definitions/ManagedUserVM"}}],"responses":{"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/search/page-details":{"post":{"tags":["search-resource"],"summary":"searchPageDetails","operationId":"searchPageDetailsUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"query","description":"query","required":true,"schema":{"$ref":"#/definitions/SearchInputDTO"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/SearchResultsDTO"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/users":{"get":{"tags":["user-resource"],"summary":"getAllUsers","operationId":"getAllUsersUsingGET","produces":["*/*"],"parameters":[{"name":"page","in":"query","description":"Page number of the requested page","required":false,"type":"integer","format":"int32"},{"name":"size","in":"query","description":"Size of a page","required":false,"type":"integer","format":"int32"},{"name":"sort","in":"query","description":"Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.","required":false,"type":"array","items":{"type":"string"},"collectionFormat":"multi"}],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"$ref":"#/definitions/UserDTO"}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false},"post":{"tags":["user-resource"],"summary":"createUser","operationId":"createUserUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"userDTO","description":"userDTO","required":true,"schema":{"$ref":"#/definitions/UserDTO"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/User"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false},"put":{"tags":["user-resource"],"summary":"updateUser","operationId":"updateUserUsingPUT","consumes":["application/json"],"produces":["*/*"],"parameters":[{"in":"body","name":"userDTO","description":"userDTO","required":true,"schema":{"$ref":"#/definitions/UserDTO"}}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/UserDTO"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/users/authorities":{"get":{"tags":["user-resource"],"summary":"getAuthorities","operationId":"getAuthoritiesUsingGET","produces":["*/*"],"responses":{"200":{"description":"OK","schema":{"type":"array","items":{"type":"string"}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false}},"/api/users/{login:^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$}":{"get":{"tags":["user-resource"],"summary":"getUser","operationId":"getUserUsingGET","produces":["*/*"],"parameters":[{"name":"login","in":"path","description":"login","required":true,"type":"string"}],"responses":{"200":{"description":"OK","schema":{"$ref":"#/definitions/UserDTO"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}},"deprecated":false},"delete":{"tags":["user-resource"],"summary":"deleteUser","operationId":"deleteUserUsingDELETE","produces":["*/*"],"parameters":[{"name":"login","in":"path","description":"login","required":true,"type":"string"}],"responses":{"200":{"description":"OK"},"204":{"description":"No Content"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}},"deprecated":false}}},"definitions":{"ExerciseType":{"type":"object","title":"ExerciseType"},"FragmentDTO":{"type":"object","properties":{"firstLineNumber":{"type":"integer","format":"int32"},"fragment":{"type":"string"}},"title":"FragmentDTO"},"FrequencyDTOOfstring":{"type":"object","properties":{"key":{"type":"string"},"value":{"type":"integer","format":"int64"}},"title":"FrequencyDTOOfstring"},"GitFilesAggregationDTO":{"type":"object","properties":{"fileFormat":{"type":"array","items":{"$ref":"#/definitions/FrequencyDTOOfstring"}},"repositories":{"type":"array","items":{"$ref":"#/definitions/FrequencyDTOOfstring"}},"university":{"type":"array","items":{"$ref":"#/definitions/FrequencyDTOOfstring"}}},"title":"GitFilesAggregationDTO"},"GitFilesDTO":{"type":"object","properties":{"content":{"type":"string"},"fileExtension":{"type":"string"},"fileFormat":{"type":"string"},"fileName":{"type":"string"},"filePath":{"type":"string"},"fragment":{"$ref":"#/definitions/FragmentDTO"},"gitUrl":{"type":"string"},"repository":{"type":"string"},"subGroup":{"type":"string"},"url":{"type":"string"}},"title":"GitFilesDTO"},"GitFilesPageDetailsDTO":{"type":"object","properties":{"gitFiles":{"type":"array","items":{"$ref":"#/definitions/GitFilesDTO"}},"hitCount":{"type":"integer","format":"int64"}},"title":"GitFilesPageDetailsDTO"},"JWTToken":{"type":"object","properties":{"id_token":{"type":"string"}},"title":"JWTToken"},"KeyAndPasswordVM":{"type":"object","properties":{"key":{"type":"string"},"newPassword":{"type":"string"}},"title":"KeyAndPasswordVM"},"LoginVM":{"type":"object","required":["password","username"],"properties":{"password":{"type":"string","minLength":4,"maxLength":100},"rememberMe":{"type":"boolean"},"username":{"type":"string","minLength":1,"maxLength":50}},"title":"LoginVM"},"ManagedUserVM":{"type":"object","properties":{"activated":{"type":"boolean"},"authorities":{"type":"array","items":{"type":"string"}},"createdBy":{"type":"string"},"createdDate":{"type":"string","format":"date-time"},"email":{"type":"string","minLength":5,"maxLength":254},"firstName":{"type":"string","minLength":0,"maxLength":50},"id":{"type":"integer","format":"int64"},"imageUrl":{"type":"string","minLength":0,"maxLength":256},"langKey":{"type":"string","minLength":2,"maxLength":10},"lastModifiedBy":{"type":"string"},"lastModifiedDate":{"type":"string","format":"date-time"},"lastName":{"type":"string","minLength":0,"maxLength":50},"login":{"type":"string","minLength":1,"maxLength":50,"pattern":"^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$"},"password":{"type":"string","minLength":4,"maxLength":100}},"title":"ManagedUserVM"},"PasswordChangeDTO":{"type":"object","properties":{"currentPassword":{"type":"string"},"newPassword":{"type":"string"}},"title":"PasswordChangeDTO"},"Person":{"type":"object","properties":{"affiliation":{"type":"string"},"email":{"type":"string"},"name":{"type":"string"}},"title":"Person"},"SearchInputDTO":{"type":"object","properties":{"fulltextQuery":{"type":"string"},"metadataAuthor":{"type":"string"},"metadataKeywords":{"type":"string"},"metadataLicense":{"type":"string"},"metadataNaturalLanguage":{"type":"string"},"metadataProgrammingLanguage":{"type":"string"},"page":{"type":"integer","format":"int32"},"selectedFileFormat":{"type":"array","items":{"type":"string"}},"selectedRepository":{"type":"array","items":{"type":"string"}},"selectedUniversity":{"type":"array","items":{"type":"string"}}},"title":"SearchInputDTO"},"SearchResultDTO":{"type":"object","properties":{"contributor":{"type":"array","items":{"$ref":"#/definitions/Person"}},"creator":{"type":"array","items":{"$ref":"#/definitions/Person"}},"deprecated":{"type":"boolean"},"description":{"type":"string"},"difficulty":{"type":"string"},"educationLevel":{"type":"string"},"format":{"type":"string"},"identifier":{"type":"string"},"image":{"type":"string"},"keyword":{"type":"array","items":{"type":"string"}},"language":{"type":"array","items":{"type":"string"}},"license":{"type":"string"},"metadataVersion":{"type":"string"},"programmingLanguage":{"type":"array","items":{"type":"string"}},"publisher":{"type":"array","items":{"$ref":"#/definitions/Person"}},"repositoryURL":{"type":"string"},"requires":{"type":"string"},"source":{"type":"array","items":{"type":"string"}},"status":{"type":"string"},"structure":{"type":"string"},"timeRequired":{"type":"string"},"title":{"type":"string"},"type":{"$ref":"#/definitions/ExerciseType"},"version":{"type":"string"}},"title":"SearchResultDTO"},"SearchResultsDTO":{"type":"object","properties":{"hitCount":{"type":"integer","format":"int64"},"searchResult":{"type":"array","items":{"$ref":"#/definitions/SearchResultDTO"}}},"title":"SearchResultsDTO"},"User":{"type":"object","required":["activated","login"],"properties":{"activated":{"type":"boolean"},"email":{"type":"string","minLength":5,"maxLength":254},"firstName":{"type":"string","minLength":0,"maxLength":50},"id":{"type":"integer","format":"int64"},"imageUrl":{"type":"string","minLength":0,"maxLength":256},"langKey":{"type":"string","minLength":2,"maxLength":10},"lastName":{"type":"string","minLength":0,"maxLength":50},"login":{"type":"string","minLength":1,"maxLength":50,"pattern":"^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$"},"resetDate":{"type":"string","format":"date-time"}},"title":"User"},"UserDTO":{"type":"object","properties":{"activated":{"type":"boolean"},"authorities":{"type":"array","items":{"type":"string"}},"createdBy":{"type":"string"},"createdDate":{"type":"string","format":"date-time"},"email":{"type":"string","minLength":5,"maxLength":254},"firstName":{"type":"string","minLength":0,"maxLength":50},"id":{"type":"integer","format":"int64"},"imageUrl":{"type":"string","minLength":0,"maxLength":256},"langKey":{"type":"string","minLength":2,"maxLength":10},"lastModifiedBy":{"type":"string"},"lastModifiedDate":{"type":"string","format":"date-time"},"lastName":{"type":"string","minLength":0,"maxLength":50},"login":{"type":"string","minLength":1,"maxLength":50,"pattern":"^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$"}},"title":"UserDTO"}}}, - { - modelFolder: './src/main/resources/swagger-ts-generator/models', - enumTSFile: './src/main/resources/swagger-ts-generator/enums.ts' - // + optionally more configuration - } -); \ No newline at end of file + // Better read from URL http://localhost:8080/v2/api-docs + { + swagger: '2.0', + info: { + description: 'gitsearch API documentation', + version: '0.1.0', + title: 'gitsearch API', + contact: {}, + license: { name: 'unlicensed' }, + }, + host: 'localhost:8080', + basePath: '/', + tags: [ + { name: 'account-resource', description: 'Account Resource' }, + { name: 'git-files-resource', description: 'Git Files Resource' }, + { name: 'search-resource', description: 'Search Resource' }, + { name: 'user-jwt-controller', description: 'User JWT Controller' }, + { name: 'user-resource', description: 'User Resource' }, + ], + schemes: ['http', 'https'], + paths: { + '/api/_search/git-files/aggregation': { + get: { + tags: ['git-files-resource'], + summary: 'gitFilesAggregation', + operationId: 'gitFilesAggregationUsingGET', + produces: ['*/*'], + parameters: [{ name: 'query', in: 'query', description: 'query', required: true, type: 'string' }], + responses: { + 200: { description: 'OK', schema: { $ref: '#/definitions/GitFilesAggregationDTO' } }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/_search/git-files/page-details': { + get: { + tags: ['git-files-resource'], + summary: 'gitFilesPageDetails', + operationId: 'gitFilesPageDetailsUsingGET', + produces: ['*/*'], + parameters: [ + { name: 'fulltextQuery', in: 'query', description: 'fulltextQuery', required: true, type: 'string' }, + { name: 'metadataAuthor', in: 'query', description: 'metadataAuthor', required: true, type: 'string' }, + { name: 'metadataKeywords', in: 'query', description: 'metadataKeywords', required: true, type: 'string' }, + { name: 'metadataLicense', in: 'query', description: 'metadataLicense', required: true, type: 'string' }, + { name: 'metadataNaturalLanguage', in: 'query', description: 'metadataNaturalLanguage', required: true, type: 'string' }, + { + name: 'metadataProgrammingLanguage', + in: 'query', + description: 'metadataProgrammingLanguage', + required: true, + type: 'string', + }, + { name: 'page', in: 'query', description: 'page', required: true, type: 'integer', format: 'int32' }, + { name: 'pageSize', in: 'query', description: 'pageSize', required: true, type: 'integer', format: 'int32' }, + { + name: 'selectedFileFormat', + in: 'query', + description: 'selectedFileFormat', + required: true, + type: 'array', + items: { type: 'string' }, + collectionFormat: 'multi', + }, + { + name: 'selectedRepository', + in: 'query', + description: 'selectedRepository', + required: true, + type: 'array', + items: { type: 'string' }, + collectionFormat: 'multi', + }, + { + name: 'selectedUniversity', + in: 'query', + description: 'selectedUniversity', + required: true, + type: 'array', + items: { type: 'string' }, + collectionFormat: 'multi', + }, + ], + responses: { + 200: { description: 'OK', schema: { $ref: '#/definitions/GitFilesPageDetailsDTO' } }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/_search/users/{query}': { + get: { + tags: ['user-resource'], + summary: 'search', + operationId: 'searchUsingGET', + produces: ['*/*'], + parameters: [{ name: 'query', in: 'path', description: 'query', required: true, type: 'string' }], + responses: { + 200: { description: 'OK', schema: { type: 'array', items: { $ref: '#/definitions/User' } } }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/account': { + get: { + tags: ['account-resource'], + summary: 'getAccount', + operationId: 'getAccountUsingGET', + produces: ['*/*'], + responses: { + 200: { description: 'OK', schema: { $ref: '#/definitions/UserDTO' } }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + post: { + tags: ['account-resource'], + summary: 'saveAccount', + operationId: 'saveAccountUsingPOST', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [{ in: 'body', name: 'userDTO', description: 'userDTO', required: true, schema: { $ref: '#/definitions/UserDTO' } }], + responses: { + 200: { description: 'OK' }, + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/account/change-password': { + post: { + tags: ['account-resource'], + summary: 'changePassword', + operationId: 'changePasswordUsingPOST', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [ + { + in: 'body', + name: 'passwordChangeDto', + description: 'passwordChangeDto', + required: true, + schema: { $ref: '#/definitions/PasswordChangeDTO' }, + }, + ], + responses: { + 200: { description: 'OK' }, + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/account/reset-password/finish': { + post: { + tags: ['account-resource'], + summary: 'finishPasswordReset', + operationId: 'finishPasswordResetUsingPOST', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [ + { + in: 'body', + name: 'keyAndPassword', + description: 'keyAndPassword', + required: true, + schema: { $ref: '#/definitions/KeyAndPasswordVM' }, + }, + ], + responses: { + 200: { description: 'OK' }, + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/account/reset-password/init': { + post: { + tags: ['account-resource'], + summary: 'requestPasswordReset', + operationId: 'requestPasswordResetUsingPOST', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [{ in: 'body', name: 'mail', description: 'mail', required: true, schema: { type: 'string' } }], + responses: { + 200: { description: 'OK' }, + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/activate': { + get: { + tags: ['account-resource'], + summary: 'activateAccount', + operationId: 'activateAccountUsingGET', + produces: ['*/*'], + parameters: [{ name: 'key', in: 'query', description: 'key', required: true, type: 'string' }], + responses: { + 200: { description: 'OK' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/authenticate': { + get: { + tags: ['account-resource'], + summary: 'isAuthenticated', + operationId: 'isAuthenticatedUsingGET', + produces: ['*/*'], + responses: { + 200: { description: 'OK', schema: { type: 'string' } }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + post: { + tags: ['user-jwt-controller'], + summary: 'authorize', + operationId: 'authorizeUsingPOST', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [{ in: 'body', name: 'loginVM', description: 'loginVM', required: true, schema: { $ref: '#/definitions/LoginVM' } }], + responses: { + 200: { description: 'OK', schema: { $ref: '#/definitions/JWTToken' } }, + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/register': { + post: { + tags: ['account-resource'], + summary: 'registerAccount', + operationId: 'registerAccountUsingPOST', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [ + { + in: 'body', + name: 'managedUserVM', + description: 'managedUserVM', + required: true, + schema: { $ref: '#/definitions/ManagedUserVM' }, + }, + ], + responses: { + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/search/page-details': { + post: { + tags: ['search-resource'], + summary: 'searchPageDetails', + operationId: 'searchPageDetailsUsingPOST', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [ + { in: 'body', name: 'query', description: 'query', required: true, schema: { $ref: '#/definitions/SearchInputDTO' } }, + ], + responses: { + 200: { description: 'OK', schema: { $ref: '#/definitions/SearchResultsDTO' } }, + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/users': { + get: { + tags: ['user-resource'], + summary: 'getAllUsers', + operationId: 'getAllUsersUsingGET', + produces: ['*/*'], + parameters: [ + { + name: 'page', + in: 'query', + description: 'Page number of the requested page', + required: false, + type: 'integer', + format: 'int32', + }, + { name: 'size', in: 'query', description: 'Size of a page', required: false, type: 'integer', format: 'int32' }, + { + name: 'sort', + in: 'query', + description: + 'Sorting criteria in the format: property(,asc|desc). Default sort order is ascending. Multiple sort criteria are supported.', + required: false, + type: 'array', + items: { type: 'string' }, + collectionFormat: 'multi', + }, + ], + responses: { + 200: { description: 'OK', schema: { type: 'array', items: { $ref: '#/definitions/UserDTO' } } }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + post: { + tags: ['user-resource'], + summary: 'createUser', + operationId: 'createUserUsingPOST', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [{ in: 'body', name: 'userDTO', description: 'userDTO', required: true, schema: { $ref: '#/definitions/UserDTO' } }], + responses: { + 200: { description: 'OK', schema: { $ref: '#/definitions/User' } }, + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + put: { + tags: ['user-resource'], + summary: 'updateUser', + operationId: 'updateUserUsingPUT', + consumes: ['application/json'], + produces: ['*/*'], + parameters: [{ in: 'body', name: 'userDTO', description: 'userDTO', required: true, schema: { $ref: '#/definitions/UserDTO' } }], + responses: { + 200: { description: 'OK', schema: { $ref: '#/definitions/UserDTO' } }, + 201: { description: 'Created' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/users/authorities': { + get: { + tags: ['user-resource'], + summary: 'getAuthorities', + operationId: 'getAuthoritiesUsingGET', + produces: ['*/*'], + responses: { + 200: { description: 'OK', schema: { type: 'array', items: { type: 'string' } } }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + }, + '/api/users/{login:^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$}': { + get: { + tags: ['user-resource'], + summary: 'getUser', + operationId: 'getUserUsingGET', + produces: ['*/*'], + parameters: [{ name: 'login', in: 'path', description: 'login', required: true, type: 'string' }], + responses: { + 200: { description: 'OK', schema: { $ref: '#/definitions/UserDTO' } }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + 404: { description: 'Not Found' }, + }, + deprecated: false, + }, + delete: { + tags: ['user-resource'], + summary: 'deleteUser', + operationId: 'deleteUserUsingDELETE', + produces: ['*/*'], + parameters: [{ name: 'login', in: 'path', description: 'login', required: true, type: 'string' }], + responses: { + 200: { description: 'OK' }, + 204: { description: 'No Content' }, + 401: { description: 'Unauthorized' }, + 403: { description: 'Forbidden' }, + }, + deprecated: false, + }, + }, + }, + definitions: { + ExerciseType: { type: 'object', title: 'ExerciseType' }, + FragmentDTO: { + type: 'object', + properties: { firstLineNumber: { type: 'integer', format: 'int32' }, fragment: { type: 'string' } }, + title: 'FragmentDTO', + }, + FrequencyDTOOfstring: { + type: 'object', + properties: { key: { type: 'string' }, value: { type: 'integer', format: 'int64' } }, + title: 'FrequencyDTOOfstring', + }, + GitFilesAggregationDTO: { + type: 'object', + properties: { + fileFormat: { type: 'array', items: { $ref: '#/definitions/FrequencyDTOOfstring' } }, + repositories: { type: 'array', items: { $ref: '#/definitions/FrequencyDTOOfstring' } }, + university: { type: 'array', items: { $ref: '#/definitions/FrequencyDTOOfstring' } }, + }, + title: 'GitFilesAggregationDTO', + }, + GitFilesDTO: { + type: 'object', + properties: { + content: { type: 'string' }, + fileExtension: { type: 'string' }, + fileFormat: { type: 'string' }, + fileName: { type: 'string' }, + filePath: { type: 'string' }, + fragment: { $ref: '#/definitions/FragmentDTO' }, + gitUrl: { type: 'string' }, + repository: { type: 'string' }, + subGroup: { type: 'string' }, + url: { type: 'string' }, + }, + title: 'GitFilesDTO', + }, + GitFilesPageDetailsDTO: { + type: 'object', + properties: { + gitFiles: { type: 'array', items: { $ref: '#/definitions/GitFilesDTO' } }, + hitCount: { type: 'integer', format: 'int64' }, + }, + title: 'GitFilesPageDetailsDTO', + }, + JWTToken: { type: 'object', properties: { id_token: { type: 'string' } }, title: 'JWTToken' }, + KeyAndPasswordVM: { + type: 'object', + properties: { key: { type: 'string' }, newPassword: { type: 'string' } }, + title: 'KeyAndPasswordVM', + }, + LoginVM: { + type: 'object', + required: ['password', 'username'], + properties: { + password: { type: 'string', minLength: 4, maxLength: 100 }, + rememberMe: { type: 'boolean' }, + username: { type: 'string', minLength: 1, maxLength: 50 }, + }, + title: 'LoginVM', + }, + ManagedUserVM: { + type: 'object', + properties: { + activated: { type: 'boolean' }, + authorities: { type: 'array', items: { type: 'string' } }, + createdBy: { type: 'string' }, + createdDate: { type: 'string', format: 'date-time' }, + email: { type: 'string', minLength: 5, maxLength: 254 }, + firstName: { type: 'string', minLength: 0, maxLength: 50 }, + id: { type: 'integer', format: 'int64' }, + imageUrl: { type: 'string', minLength: 0, maxLength: 256 }, + langKey: { type: 'string', minLength: 2, maxLength: 10 }, + lastModifiedBy: { type: 'string' }, + lastModifiedDate: { type: 'string', format: 'date-time' }, + lastName: { type: 'string', minLength: 0, maxLength: 50 }, + login: { + type: 'string', + minLength: 1, + maxLength: 50, + pattern: '^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$', + }, + password: { type: 'string', minLength: 4, maxLength: 100 }, + }, + title: 'ManagedUserVM', + }, + PasswordChangeDTO: { + type: 'object', + properties: { currentPassword: { type: 'string' }, newPassword: { type: 'string' } }, + title: 'PasswordChangeDTO', + }, + Person: { + type: 'object', + properties: { affiliation: { type: 'string' }, email: { type: 'string' }, name: { type: 'string' } }, + title: 'Person', + }, + SearchInputDTO: { + type: 'object', + properties: { + fulltextQuery: { type: 'string' }, + metadataAuthor: { type: 'string' }, + metadataKeywords: { type: 'string' }, + metadataLicense: { type: 'string' }, + metadataNaturalLanguage: { type: 'string' }, + metadataProgrammingLanguage: { type: 'string' }, + page: { type: 'integer', format: 'int32' }, + selectedFileFormat: { type: 'array', items: { type: 'string' } }, + selectedRepository: { type: 'array', items: { type: 'string' } }, + selectedUniversity: { type: 'array', items: { type: 'string' } }, + }, + title: 'SearchInputDTO', + }, + SearchResultDTO: { + type: 'object', + properties: { + contributor: { type: 'array', items: { $ref: '#/definitions/Person' } }, + creator: { type: 'array', items: { $ref: '#/definitions/Person' } }, + deprecated: { type: 'boolean' }, + description: { type: 'string' }, + difficulty: { type: 'string' }, + educationLevel: { type: 'string' }, + format: { type: 'string' }, + identifier: { type: 'string' }, + image: { type: 'string' }, + keyword: { type: 'array', items: { type: 'string' } }, + language: { type: 'array', items: { type: 'string' } }, + license: { type: 'string' }, + metadataVersion: { type: 'string' }, + programmingLanguage: { type: 'array', items: { type: 'string' } }, + publisher: { type: 'array', items: { $ref: '#/definitions/Person' } }, + repositoryURL: { type: 'string' }, + requires: { type: 'string' }, + source: { type: 'array', items: { type: 'string' } }, + status: { type: 'string' }, + structure: { type: 'string' }, + timeRequired: { type: 'string' }, + title: { type: 'string' }, + type: { $ref: '#/definitions/ExerciseType' }, + version: { type: 'string' }, + }, + title: 'SearchResultDTO', + }, + SearchResultsDTO: { + type: 'object', + properties: { + hitCount: { type: 'integer', format: 'int64' }, + searchResult: { type: 'array', items: { $ref: '#/definitions/SearchResultDTO' } }, + }, + title: 'SearchResultsDTO', + }, + User: { + type: 'object', + required: ['activated', 'login'], + properties: { + activated: { type: 'boolean' }, + email: { type: 'string', minLength: 5, maxLength: 254 }, + firstName: { type: 'string', minLength: 0, maxLength: 50 }, + id: { type: 'integer', format: 'int64' }, + imageUrl: { type: 'string', minLength: 0, maxLength: 256 }, + langKey: { type: 'string', minLength: 2, maxLength: 10 }, + lastName: { type: 'string', minLength: 0, maxLength: 50 }, + login: { + type: 'string', + minLength: 1, + maxLength: 50, + pattern: '^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$', + }, + resetDate: { type: 'string', format: 'date-time' }, + }, + title: 'User', + }, + UserDTO: { + type: 'object', + properties: { + activated: { type: 'boolean' }, + authorities: { type: 'array', items: { type: 'string' } }, + createdBy: { type: 'string' }, + createdDate: { type: 'string', format: 'date-time' }, + email: { type: 'string', minLength: 5, maxLength: 254 }, + firstName: { type: 'string', minLength: 0, maxLength: 50 }, + id: { type: 'integer', format: 'int64' }, + imageUrl: { type: 'string', minLength: 0, maxLength: 256 }, + langKey: { type: 'string', minLength: 2, maxLength: 10 }, + lastModifiedBy: { type: 'string' }, + lastModifiedDate: { type: 'string', format: 'date-time' }, + lastName: { type: 'string', minLength: 0, maxLength: 50 }, + login: { + type: 'string', + minLength: 1, + maxLength: 50, + pattern: '^(?>[a-zA-Z0-9!$&*+=?^_`{|}~.-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*)|(?>[_.@A-Za-z0-9-]+)$', + }, + }, + title: 'UserDTO', + }, + }, + }, + { + modelFolder: './src/main/resources/swagger-ts-generator/models', + enumTSFile: './src/main/resources/swagger-ts-generator/enums.ts', + // + optionally more configuration + } +); diff --git a/src/main/resources/templates/mail/info/infoEmail.html b/src/main/resources/templates/mail/info/infoEmail.html index f0eb0fc29f2f9dc5ca41484333390da9b3a7c218..fed5a3df8b0afc3d24340d4f99c7a7ff88f75ae4 100644 --- a/src/main/resources/templates/mail/info/infoEmail.html +++ b/src/main/resources/templates/mail/info/infoEmail.html @@ -1,41 +1,47 @@ <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" th:lang="${#locale.language}" lang="en"> - <head> - <title th:text="#{email.info.title}">Sharing Platform Info Update</title> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> - <link rel="icon" th:href="@{|${baseUrl}/favicon.ico|}" /> - </head> - <body> - <p th:text="#{email.info.greeting(null == ${user.firstName}?'':${user.firstName}, ${user.lastName})}"> - Dear participant, - </p> - <p th:if="${#lists.isEmpty(watchListUpdates)}" th:text="#{email.info.noChangesOnWatchlist}">With this E-mail we inform you that there were no changes on your watchlists.</p> - <div th:if="${not #lists.isEmpty(watchListUpdates)}"> - <p th:text="#{email.info.textIntro}"> - you get this e-mail, because one of your automatic checks was triggered. - </p> - <p th:text="#{email.info.textWatchlist}"> - Some exercises on your watchlist were recently updated: - </p> - - <table><caption>Updated Exercises</caption><tr><th scope="col">Exercise Name</th><th scope="col">Watchlist</th></tr> - <tr th:each="wlUpdate: ${watchListUpdates}"> - <td><span th:text="${wlUpdate.key.metadata.title}"></span><span th:text="${#temporals.format(wlUpdate.key.project.last_activity_at,'dd MMMM yyyy')}">Exercise title</span></td> - <td th:text="${wlUpdate.value.name}">Exercise title</td> - </tr> - - </table> - </div> - <p> - <span th:text="#{email.info.textRegards}">Regards, </span> - <br/> - <em th:text="#{email.signature}">Your CodeAbility Sharing Platform Service Team.</em> - </p> - <br/><br/> - <p><span th:text="#{email.info.textClosing}"> - If you are not interested in getting this e-mail, please log in to the CodeAbility Sharing Platform, and reset your update triggers - </span> <a th:with="url=(@{|${baseUrl}|})" th:href="${url}" th:text="${url}">Link to the Sharing Plattform</a> - </p> - - </body> + <head> + <title th:text="#{email.info.title}">Sharing Platform Info Update</title> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> + <link rel="icon" th:href="@{|${baseUrl}/favicon.ico|}" /> + </head> + <body> + <p th:text="#{email.info.greeting(null == ${user.firstName}?'':${user.firstName}, ${user.lastName})}">Dear participant,</p> + <p th:if="${#lists.isEmpty(watchListUpdates)}" th:text="#{email.info.noChangesOnWatchlist}"> + With this E-mail we inform you that there were no changes on your watchlists. + </p> + <div th:if="${not #lists.isEmpty(watchListUpdates)}"> + <p th:text="#{email.info.textIntro}">you get this e-mail, because one of your automatic checks was triggered.</p> + <p th:text="#{email.info.textWatchlist}">Some exercises on your watchlist were recently updated:</p> + + <table> + <caption> + Updated Exercises + </caption> + <tr> + <th scope="col">Exercise Name</th> + <th scope="col">Watchlist</th> + </tr> + <tr th:each="wlUpdate: ${watchListUpdates}"> + <td> + <span th:text="${wlUpdate.key.metadata.title}"></span + ><span th:text="${#temporals.format(wlUpdate.key.project.last_activity_at,'dd MMMM yyyy')}">Exercise title</span> + </td> + <td th:text="${wlUpdate.value.name}">Exercise title</td> + </tr> + </table> + </div> + <p> + <span th:text="#{email.info.textRegards}">Regards, </span> + <br /> + <em th:text="#{email.signature}">Your CodeAbility Sharing Platform Service Team.</em> + </p> + <br /><br /> + <p> + <span th:text="#{email.info.textClosing}"> + If you are not interested in getting this e-mail, please log in to the CodeAbility Sharing Platform, and reset your update triggers + </span> + <a th:with="url=(@{|${baseUrl}|})" th:href="${url}" th:text="${url}">Link to the Sharing Plattform</a> + </p> + </body> </html> diff --git a/src/main/webapp/app/account/settings/settings.component.ts b/src/main/webapp/app/account/settings/settings.component.ts index eb5ece9fac16a702659aaa8195cae578c77a7a9d..dc307641770a1ae5609303a686f9342c8faf1a82 100644 --- a/src/main/webapp/app/account/settings/settings.component.ts +++ b/src/main/webapp/app/account/settings/settings.component.ts @@ -22,8 +22,12 @@ export class SettingsComponent implements OnInit { langKey: [undefined], }); - constructor(private accountService: AccountService, private testService: TestService, - private fb: FormBuilder, private translateService: TranslateService) {} + constructor( + private accountService: AccountService, + private testService: TestService, + private fb: FormBuilder, + private translateService: TranslateService + ) {} ngOnInit(): void { this.accountService.identity().subscribe(account => { diff --git a/src/main/webapp/app/app-routing.module.ts b/src/main/webapp/app/app-routing.module.ts index 498fc9eeaa517a9db33e98374b9e589dd9b6b1d6..23cbdeb57ee5b6f7e97fc266da731ef0a667e6d6 100644 --- a/src/main/webapp/app/app-routing.module.ts +++ b/src/main/webapp/app/app-routing.module.ts @@ -30,23 +30,23 @@ import { UserRouteAccessService } from 'app/core/auth/user-route-access.service' path: 'login', loadChildren: () => import('./login/login.module').then(m => m.LoginModule), }, - { - path: 'search', - loadChildren: () => import('app/search/search.module').then(m => m.SearchModule) - }, - { - path: 'bookmarks', - loadChildren: () => import('app/bookmarks/bookmarks.module').then(m => m.BookmarskModule) - }, - { - path: 'datapolicy', - component: DatapolicyComponent - }, - { - path: 'import', - loadChildren: () => import('app/exercise/import/exercise-import.module').then(m => m.ExerciseImportModule) - }, - pagesRoutes, + { + path: 'search', + loadChildren: () => import('app/search/search.module').then(m => m.SearchModule), + }, + { + path: 'bookmarks', + loadChildren: () => import('app/bookmarks/bookmarks.module').then(m => m.BookmarskModule), + }, + { + path: 'datapolicy', + component: DatapolicyComponent, + }, + { + path: 'import', + loadChildren: () => import('app/exercise/import/exercise-import.module').then(m => m.ExerciseImportModule), + }, + pagesRoutes, { path: '', loadChildren: () => import(`./entities/entity-routing.module`).then(m => m.EntityRoutingModule), diff --git a/src/main/webapp/app/bookmarks/bookmarks-delete-dialog.component.html b/src/main/webapp/app/bookmarks/bookmarks-delete-dialog.component.html index 067a07e8716e060b38ca5c008d1f840785eaad6b..2e656a601d5e0a0fe53cb8acc68713b73a732d75 100644 --- a/src/main/webapp/app/bookmarks/bookmarks-delete-dialog.component.html +++ b/src/main/webapp/app/bookmarks/bookmarks-delete-dialog.component.html @@ -1,25 +1,30 @@ <form *ngIf="userWatchList" name="deleteForm" (ngSubmit)="confirmDelete(userWatchList?.id!)"> - <div class="modal-header"> - <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> + <div class="modal-header"> + <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true" - (click)="cancel()">×</button> - </div> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="cancel()">×</button> + </div> - <div class="modal-body"> + <div class="modal-body"> <!-- TODO <jhi-alert-error></jhi-alert-error> --> - <p id="jhi-delete-userWatchList-heading" jhiTranslate="gitsearchApp.userWatchList.delete.question" [translateValues]="{ id: userWatchList.name }">Are you sure you want to delete this User Watch List?</p> - </div> + <p + id="jhi-delete-userWatchList-heading" + jhiTranslate="gitsearchApp.userWatchList.delete.question" + [translateValues]="{ id: userWatchList.name }" + > + Are you sure you want to delete this User Watch List? + </p> + </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button id="jhi-confirm-delete-userWatchList" type="submit" class="btn btn-danger"> - <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> - </button> - </div> + <button id="jhi-confirm-delete-userWatchList" type="submit" class="btn btn-danger"> + <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> + </button> + </div> </form> diff --git a/src/main/webapp/app/bookmarks/bookmarks-update.component.html b/src/main/webapp/app/bookmarks/bookmarks-update.component.html index 2aaa9b5be9aeefc4f6234bd8e9badf8f88c0bd2b..741275382c37fed6d5ec13d6df48e6c41e20deb6 100644 --- a/src/main/webapp/app/bookmarks/bookmarks-update.component.html +++ b/src/main/webapp/app/bookmarks/bookmarks-update.component.html @@ -1,45 +1,51 @@ <div class="row justify-content-center"> - <div class="col-8"> - <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> - <h2 id="jhi-user-watch-list-heading" jhiTranslate="gitsearchApp.userWatchList.home.createOrEditLabel">Create or edit a User Watch List</h2> + <div class="col-8"> + <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> + <h2 id="jhi-user-watch-list-heading" jhiTranslate="gitsearchApp.userWatchList.home.createOrEditLabel"> + Create or edit a User Watch List + </h2> - <div> - <jhi-alert-error></jhi-alert-error> - <!-- + <div> + <jhi-alert-error></jhi-alert-error> + <!-- <div class="form-group" [hidden]="!editForm.get('id')!.value"> <label for="id" jhiTranslate="global.field.id">ID</label> <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> </div> --> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.name" for="fields">Name</label> - <input type="text" class="form-control" name="name" id="field_name" - formControlName="name"/> - <div *ngIf="editForm.get('name')!.invalid && (editForm.get('name')!.dirty || editForm.get('name')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('name')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - <small class="form-text text-danger" - *ngIf="editForm.get('name')?.errors?.minlength" jhiTranslate="entity.validation.minlength" [translateValues]="{ min: 1 }"> - This field is required to be at least 1 characters. - </small> - </div> - </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.checkFrequency" for="field_checkFrequency">Check Frequency</label> - <ng-template #helpFulltext> {{ 'gitsearchApp.userWatchList.help.checkFrequency' | translate}}</ng-template> - <fa-icon style="padding: 10px 0px 0px 10px;" [ngbTooltip]="helpFulltext" container="body" [icon]="questionIcon"></fa-icon> - - <select class="form-control" name="checkFrequency" formControlName="checkFrequency" id="field_checkFrequency"> - <option value="NEVER">{{ 'gitsearchApp.CheckFrequency.NEVER' | translate }}</option> - <option value="DAILY">{{ 'gitsearchApp.CheckFrequency.DAILY' | translate }}</option> - <option value="WEEKLY">{{ 'gitsearchApp.CheckFrequency.WEEKLY' | translate }}</option> - <option value="MONTHLY">{{ 'gitsearchApp.CheckFrequency.MONTHLY' | translate }}</option> - </select> - </div> - -<!-- + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.name" for="fields">Name</label> + <input type="text" class="form-control" name="name" id="field_name" formControlName="name" /> + <div *ngIf="editForm.get('name')!.invalid && (editForm.get('name')!.dirty || editForm.get('name')!.touched)"> + <small class="form-text text-danger" *ngIf="editForm.get('name')?.errors?.required" jhiTranslate="entity.validation.required"> + This field is required. + </small> + <small + class="form-text text-danger" + *ngIf="editForm.get('name')?.errors?.minlength" + jhiTranslate="entity.validation.minlength" + [translateValues]="{ min: 1 }" + > + This field is required to be at least 1 characters. + </small> + </div> + </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.checkFrequency" for="field_checkFrequency" + >Check Frequency</label + > + <ng-template #helpFulltext> {{ 'gitsearchApp.userWatchList.help.checkFrequency' | translate }}</ng-template> + <fa-icon style="padding: 10px 0px 0px 10px" [ngbTooltip]="helpFulltext" container="body" [icon]="questionIcon"></fa-icon> + + <select class="form-control" name="checkFrequency" formControlName="checkFrequency" id="field_checkFrequency"> + <option value="NEVER">{{ 'gitsearchApp.CheckFrequency.NEVER' | translate }}</option> + <option value="DAILY">{{ 'gitsearchApp.CheckFrequency.DAILY' | translate }}</option> + <option value="WEEKLY">{{ 'gitsearchApp.CheckFrequency.WEEKLY' | translate }}</option> + <option value="MONTHLY">{{ 'gitsearchApp.CheckFrequency.MONTHLY' | translate }}</option> + </select> + </div> + + <!-- <div class="form-group"> <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.userId" for="field_userId">User Id</label> <select class="form-control" id="field_userId" name="userId" formControlName="userId"> @@ -53,18 +59,18 @@ This field is required. </small> </div> - --> - </div> + --> + </div> - <div> - <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div> + <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> - <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> - </button> - </div> - </form> - </div> + <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> + <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> + </button> + </div> + </form> + </div> </div> diff --git a/src/main/webapp/app/bookmarks/bookmarks.component.html b/src/main/webapp/app/bookmarks/bookmarks.component.html index 5c7cb836d232fe555a479ae595612082eec9dd1b..bb7588a78307ca68c6d105e5f25e1d941e8407a3 100644 --- a/src/main/webapp/app/bookmarks/bookmarks.component.html +++ b/src/main/webapp/app/bookmarks/bookmarks.component.html @@ -1,114 +1,121 @@ -<div class="row" infiniteScroll [infiniteScrollDistance]="2" - [infiniteScrollThrottle]="50" (scrolled)="onScroll()"> +<div class="row" infiniteScroll [infiniteScrollDistance]="2" [infiniteScrollThrottle]="50" (scrolled)="onScroll()"> + <div class="col-12 col-md-5 col-lg-4 col-xl-3"> + <div class="bookmarklist-container"> + <h2 id="page-heading"> + <span jhiTranslate="gitsearchApp.userWatchList.home.title">User Watch Lists</span> + </h2> - <div class="col-12 col-md-5 col-lg-4 col-xl-3"> - <div class="bookmarklist-container"> - <h2 id="page-heading"> - <span jhiTranslate="gitsearchApp.userWatchList.home.title">User - Watch Lists</span> - </h2> + <div class="table-responsive" id="entities"> + <div class="col-sm-12"> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input + type="text" + class="form-control" + [(ngModel)]="currentSearch" + id="currentSearch" + name="currentSearch" + placeholder="{{ 'gitsearchApp.userWatchList.home.search' | translate }}" + /> - <div class="table-responsive" id="entities"> - <div class="col-sm-12"> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" - [(ngModel)]="currentSearch" id="currentSearch" - name="currentSearch" - placeholder="{{ 'gitsearchApp.userWatchList.home.search' | translate }}"> + <button class="input-group-append btn btn-info" (click)="search(currentSearch)"> + <fa-icon icon="search"></fa-icon> + </button> - <button class="input-group-append btn btn-info" - (click)="search(currentSearch)"> - <fa-icon icon="search"></fa-icon> - </button> - - <button class="input-group-append btn btn-danger" - (click)="search('')" *ngIf="currentSearch"> - <fa-icon icon="trash-alt"></fa-icon> - </button> - </div> - </form> - </div> - <table class="table table-striped" aria-describedby="page-heading"> - <thead> - <tr jhiSort [(predicate)]="predicate" [(ascending)]="ascending" - > - <!-- TODO + <button class="input-group-append btn btn-danger" (click)="search('')" *ngIf="currentSearch"> + <fa-icon icon="trash-alt"></fa-icon> + </button> + </div> + </form> + </div> + <table class="table table-striped" aria-describedby="page-heading"> + <thead> + <tr jhiSort [(predicate)]="predicate" [(ascending)]="ascending"> + <!-- TODO [callback]="reset.bind(this)"> --> - <th scope="col" jhiSortBy="name"><span - jhiTranslate="gitsearchApp.userWatchList.name">Name</span> <fa-icon - icon="sort"></fa-icon></th> - <th scope="col"></th> - </tr> - </thead> - <tbody infinite-scroll (scrolled)="loadPage(page + 1)" - [infiniteScrollDisabled]="page >= links['last']" - [infiniteScrollDistance]="0"> - <tr *ngFor="let userWatchList of userWatchLists ;trackBy: trackId"> - <td class="{{isSelected(userWatchList)?'selected':''}}" - (click)="view(userWatchList)" style="cursor: pointer;">{{ - userWatchList.name }}</td> - <td class="text-right"> - <div class="btn-group"> - <button type="submit" - style="border-width: 0px; background-color: transparent;" - [routerLink]="['/bookmarks', userWatchList.id, 'edit']"> - <fa-icon icon="pencil-alt"></fa-icon> - </button> - - <button type="submit" (click)="delete(userWatchList)" - [disabled]="userWatchLists.length == 1" - style="border-width: 0px; background-color: transparent;" - title="{{ (userWatchLists.length == 1)?'The last entry cannot be deleted':'' }}"> - <fa-icon icon="times"></fa-icon> - </button> - </div> - </td> - </tr> - </tbody> - </table> - </div> - <span *ngIf="getCommonActions().length > 0"> - <p style="text-align: left; margin-top: 20px;"> - <strong jhiTranslate="gitsearchApp.userWatchList.export"></strong> - </p> <a *ngFor="let action of getCommonActions()" - class="btn btn-outline-secondary" role="button" aria-pressed="true" - style="float: left; margin-right: 5px; margin-top: 5px;" - (click)="startAction(action)">{{action.commandName}}</a> - </span> - <button id="jh-create-entity" - class="btn btn-primary jh-create-entity create-user-watch-list" - [routerLink]="['/bookmarks/new']"> - <fa-icon icon="plus"></fa-icon> - <span class="hidden-sm-down" - jhiTranslate="gitsearchApp.userWatchList.home.createLabel"> - Create a new User Watch List </span> - </button> + <th scope="col" jhiSortBy="name"> + <span jhiTranslate="gitsearchApp.userWatchList.name">Name</span> <fa-icon icon="sort"></fa-icon> + </th> + <th scope="col"></th> + </tr> + </thead> + <tbody + infinite-scroll + (scrolled)="loadPage(page + 1)" + [infiniteScrollDisabled]="page >= links['last']" + [infiniteScrollDistance]="0" + > + <tr *ngFor="let userWatchList of userWatchLists; trackBy: trackId"> + <td class="{{ isSelected(userWatchList) ? 'selected' : '' }}" (click)="view(userWatchList)" style="cursor: pointer"> + {{ userWatchList.name }} + </td> + <td class="text-right"> + <div class="btn-group"> + <button + type="submit" + style="border-width: 0px; background-color: transparent" + [routerLink]="['/bookmarks', userWatchList.id, 'edit']" + > + <fa-icon icon="pencil-alt"></fa-icon> + </button> - </div> - </div> - <!-- + <button + type="submit" + (click)="delete(userWatchList)" + [disabled]="userWatchLists.length == 1" + style="border-width: 0px; background-color: transparent" + title="{{ userWatchLists.length == 1 ? 'The last entry cannot be deleted' : '' }}" + > + <fa-icon icon="times"></fa-icon> + </button> + </div> + </td> + </tr> + </tbody> + </table> + </div> + <span *ngIf="getCommonActions().length > 0"> + <p style="text-align: left; margin-top: 20px"> + <strong jhiTranslate="gitsearchApp.userWatchList.export"></strong> + </p> + <a + *ngFor="let action of getCommonActions()" + class="btn btn-outline-secondary" + role="button" + aria-pressed="true" + style="float: left; margin-right: 5px; margin-top: 5px" + (click)="startAction(action)" + >{{ action.commandName }}</a + > + </span> + <button id="jh-create-entity" class="btn btn-primary jh-create-entity create-user-watch-list" [routerLink]="['/bookmarks/new']"> + <fa-icon icon="plus"></fa-icon> + <span class="hidden-sm-down" jhiTranslate="gitsearchApp.userWatchList.home.createLabel"> Create a new User Watch List </span> + </button> + </div> + </div> + <!-- <jhi-alert-error></jhi-alert-error> <jhi-alert></jhi-alert> --> - <div class="col-12 col-md-7 col-lg-8 col-xl-9"> - - - <div *ngIf="results.length === 0"> - <span jhiTranslate="search.noResults">No results found</span> - </div> - <div *ngIf="hitCount !== 0"> - <span>{{ 'search.numberResults' | translate:{'length': - hitCount} }}</span> - </div> - <div class="row"> - <jhi-exercise-card *ngFor="let result of results" - class="card-container col-12 col-lg-6 col-xl-4" [exercise]="result" - (exerciseSelectionEvent)="selectExercise($event)"> - </jhi-exercise-card> - </div> - </div> + <div class="col-12 col-md-7 col-lg-8 col-xl-9"> + <div *ngIf="results.length === 0"> + <span jhiTranslate="search.noResults">No results found</span> + </div> + <div *ngIf="hitCount !== 0"> + <span>{{ 'search.numberResults' | translate: { length: hitCount } }}</span> + </div> + <div class="row"> + <jhi-exercise-card + *ngFor="let result of results" + class="card-container col-12 col-lg-6 col-xl-4" + [exercise]="result" + (exerciseSelectionEvent)="selectExercise($event)" + > + </jhi-exercise-card> + </div> + </div> </div> <jhi-exercise-details [exercise]="selectedResult" (exerciseChangedEvent)="selectExercise($event)"></jhi-exercise-details> diff --git a/src/main/webapp/app/bookmarks/bookmarks.component.ts b/src/main/webapp/app/bookmarks/bookmarks.component.ts index 95faf1cb4108141cf3d108b173c7b7c979250e91..e359fc2b9329044c4dd12ac5ce8ca71e94330c7f 100644 --- a/src/main/webapp/app/bookmarks/bookmarks.component.ts +++ b/src/main/webapp/app/bookmarks/bookmarks.component.ts @@ -243,9 +243,9 @@ export class BookmarkComponent implements OnInit, OnDestroy { } } - isSelected(userWatchList: IUserWatchList):boolean { - if(this.watchlistManager.getCurrentWatchList()) - return userWatchList.id === this.watchlistManager.getCurrentWatchList()!.userWatchList.id + isSelected(userWatchList: IUserWatchList): boolean { + if (this.watchlistManager.getCurrentWatchList()) + return userWatchList.id === this.watchlistManager.getCurrentWatchList()!.userWatchList.id; else return false; } @@ -262,7 +262,7 @@ export class BookmarkComponent implements OnInit, OnDestroy { getCommonActions(): PluginActionInfo[] { const result = lodash .chain(this.results) - .map(function (ex: Exercise):PluginActionInfo[] { + .map(function (ex: Exercise): PluginActionInfo[] { return ex.originalResult.supportedActions; }) .flatten() @@ -275,12 +275,14 @@ export class BookmarkComponent implements OnInit, OnDestroy { startAction(action: PluginActionInfo): void { const selectedExercises = lodash .chain(this.results) - .map(function (ex: Exercise):SearchResultDTO { + .map(function (ex: Exercise): SearchResultDTO { return ex.originalResult; }) - .filter((sr: SearchResultDTO) => sr.supportedActions.some(function(a: PluginActionInfo): boolean { - return equalPluginActionInfo(a, action); - })); + .filter((sr: SearchResultDTO) => + sr.supportedActions.some(function (a: PluginActionInfo): boolean { + return equalPluginActionInfo(a, action); + }) + ); const basketInfo: ShoppingBasketInfo = { plugin: action.plugin, action: action.action, diff --git a/src/main/webapp/app/bookmarks/bookmarks.module.ts b/src/main/webapp/app/bookmarks/bookmarks.module.ts index c458c0f306587d0ee2178758aff24ed6e538971f..54d6b06d3fc7c229f7316964785e23a88f25e924 100644 --- a/src/main/webapp/app/bookmarks/bookmarks.module.ts +++ b/src/main/webapp/app/bookmarks/bookmarks.module.ts @@ -1,7 +1,7 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; import { ExerciseModule } from 'app/exercise/exercise.module'; -import { FontAwesomeModule } from '@fortawesome/angular-fontawesome' +import { FontAwesomeModule } from '@fortawesome/angular-fontawesome'; import { SharedModule } from 'app/shared/shared.module'; import { BookmarksDeleteDialogComponent } from './bookmarks-delete-dialog.component'; diff --git a/src/main/webapp/app/config/font-awesome-icons.ts b/src/main/webapp/app/config/font-awesome-icons.ts index 25915ce2a15a6c49edff6d3ffd3b1ab598619de5..6a8ca8690c0308ac3ef39a36b36daafd2fcb244f 100644 --- a/src/main/webapp/app/config/font-awesome-icons.ts +++ b/src/main/webapp/app/config/font-awesome-icons.ts @@ -43,7 +43,6 @@ import { // jhipster-needle-add-icon-import } from '@fortawesome/free-solid-svg-icons'; - export const fontAwesomeIcons = [ faArrowLeft, faAsterisk, diff --git a/src/main/webapp/app/core/application/applicationInfo.service.ts b/src/main/webapp/app/core/application/applicationInfo.service.ts index b3db07d951d0d265858dc2dd51a16560a3e95af0..d89b6d1bc966bbe3a8e301bf952e352fb0095ea2 100644 --- a/src/main/webapp/app/core/application/applicationInfo.service.ts +++ b/src/main/webapp/app/core/application/applicationInfo.service.ts @@ -18,7 +18,7 @@ export class ApplicationInfoService { } public loadOerLink(): Observable<string> { - return this.http.get(this.applicationConfigService.getEndpointFor( 'api/applicationInfo/oerLinkInfo'), { responseType: 'text' }); + return this.http.get(this.applicationConfigService.getEndpointFor('api/applicationInfo/oerLinkInfo'), { responseType: 'text' }); } public getDeploymentInfo(): DeploymentInfo { @@ -31,10 +31,8 @@ export class ApplicationInfoService { } return this.cachedDeploymentInfo; } - - private loadDeploymentInfo(): Observable<DeploymentInfo> { + + private loadDeploymentInfo(): Observable<DeploymentInfo> { return this.http.get<DeploymentInfo>(SERVER_API_URL + 'api/applicationInfo/deploymentInfo'); } - - } diff --git a/src/main/webapp/app/core/auth/account.service.ts b/src/main/webapp/app/core/auth/account.service.ts index 2ed9c3a38f1196cfae7fca648f5cc1ae43ffa38e..d07388d73a68afad2de85de11d0f32301383e634 100644 --- a/src/main/webapp/app/core/auth/account.service.ts +++ b/src/main/webapp/app/core/auth/account.service.ts @@ -77,7 +77,7 @@ export class AccountService { } getImageUrl(): string { - return (this.userIdentity && this.userIdentity.imageUrl) ? this.userIdentity.imageUrl : ''; + return this.userIdentity && this.userIdentity.imageUrl ? this.userIdentity.imageUrl : ''; } private fetch(): Observable<Account> { diff --git a/src/main/webapp/app/core/auth/auth-jwt.service.ts b/src/main/webapp/app/core/auth/auth-jwt.service.ts index bb02f5b0508d9fd1008426b3a545424b5c2dc63e..fe4112568fe189f6e6eff0018a20a8029d311320 100644 --- a/src/main/webapp/app/core/auth/auth-jwt.service.ts +++ b/src/main/webapp/app/core/auth/auth-jwt.service.ts @@ -33,12 +33,11 @@ export class AuthServerProvider { } refreshToken(tokenX: string): Observable<void> { - const tokenParam = new HttpParams().set('token', tokenX); + const tokenParam = new HttpParams().set('token', tokenX); return this.http - .post<JwtToken>(SERVER_API_URL + 'api/refreshToken', tokenParam ) + .post<JwtToken>(SERVER_API_URL + 'api/refreshToken', tokenParam) .pipe(map(response => this.authenticateSuccess(response, false))); - } - + } logout(): Observable<void> { return new Observable(observer => { diff --git a/src/main/webapp/app/core/auth/oauth2-config.model.ts b/src/main/webapp/app/core/auth/oauth2-config.model.ts index 2f30e6945df8281773738850647f75ba28be27e0..de718993dfe20d6cb1a72183122abb2a6d7774be 100644 --- a/src/main/webapp/app/core/auth/oauth2-config.model.ts +++ b/src/main/webapp/app/core/auth/oauth2-config.model.ts @@ -1,7 +1,3 @@ export class OAuth2Config { - constructor( - public registrationId: string, - public clientURL: string, - public scopes: string, - ) {} + constructor(public registrationId: string, public clientURL: string, public scopes: string) {} } diff --git a/src/main/webapp/app/core/auth/oauth2-config.service.ts b/src/main/webapp/app/core/auth/oauth2-config.service.ts index ab069ed192ed60dabfcee62a94e5698723103ee5..a9ad5024ec7114c653d4a345ad3f47b679d99d1d 100644 --- a/src/main/webapp/app/core/auth/oauth2-config.service.ts +++ b/src/main/webapp/app/core/auth/oauth2-config.service.ts @@ -1,17 +1,14 @@ import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { OAuth2Config} from './oauth2-config.model'; +import { OAuth2Config } from './oauth2-config.model'; import { Observable } from 'rxjs'; import { ApplicationConfigService } from 'app/core/config/application-config.service'; @Injectable({ - providedIn: 'root' + providedIn: 'root', }) export class OAuth2ConfigService { - - constructor( - private http: HttpClient, - private applicationConfigService: ApplicationConfigService ) { } + constructor(private http: HttpClient, private applicationConfigService: ApplicationConfigService) {} get(clientId: string): Observable<OAuth2Config> { return this.http.get<OAuth2Config>(this.applicationConfigService.getEndpointFor('oauth2/oauth2Config') + `/${clientId}`); @@ -19,7 +16,5 @@ export class OAuth2ConfigService { getAllConfigs(): Observable<OAuth2Config[]> { return this.http.get<OAuth2Config[]>(this.applicationConfigService.getEndpointFor('oauth2Config/allConfigs')); - -} - + } } diff --git a/src/main/webapp/app/editorialPages/editorialPages.module.ts b/src/main/webapp/app/editorialPages/editorialPages.module.ts index 8a7528eba22b0f761e6561cd2b2dcc15e0a71045..859d46565afb1376e319d29ed34d9b308772f262 100644 --- a/src/main/webapp/app/editorialPages/editorialPages.module.ts +++ b/src/main/webapp/app/editorialPages/editorialPages.module.ts @@ -5,20 +5,19 @@ import { PagesMarkDownViewerComponent } from 'app/editorialPages/markDownViewer/ import { SharedLibsModule } from '../shared/shared-libs.module'; import { MarkdownModule, MarkedOptions, MarkedRenderer } from 'ngx-markdown'; import { Observable } from 'rxjs'; -import {AppInjector} from '../app.module'; +import { AppInjector } from '../app.module'; import { PagesComponent } from './pages.component'; export class MyRenderer extends MarkedRenderer { public attachmentResourceURL; - private applicationConfigService: ApplicationConfigService - + private applicationConfigService: ApplicationConfigService; + constructor() { super(); this.applicationConfigService = AppInjector.get(ApplicationConfigService); - this.attachmentResourceURL = this.applicationConfigService.getEndpointFor('api/pages/attachment') - } - + this.attachmentResourceURL = this.applicationConfigService.getEndpointFor('api/pages/attachment'); + } image(href: string | null, title: string | null, text: string): string { const analyzedHref = href; @@ -47,7 +46,7 @@ export class MyRenderer extends MarkedRenderer { getAttachmentURL(path: string, http: HttpClient): Observable<string> { const parameters = new HttpParams().set('path', path); - return http.get(this.attachmentResourceURL, { params: parameters, responseType: 'text' }); + return http.get(this.attachmentResourceURL, { params: parameters, responseType: 'text' }); } } diff --git a/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.html b/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.html index 4e4c009de75286abd3c2339897bbc9bc55129d2f..2433e9e540d600bda7bfc8c82f1e04b296d4300b 100644 --- a/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.html +++ b/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.html @@ -1,3 +1,11 @@ <div *ngIf="page"> - <markdown #pageMarkDown katex emoji ngPreserveWhitespaces [katexOptions]="katexOptions" [data]="page.content" (ready)="fixLinksToGoViaRouter()"></markdown> + <markdown + #pageMarkDown + katex + emoji + ngPreserveWhitespaces + [katexOptions]="katexOptions" + [data]="page.content" + (ready)="fixLinksToGoViaRouter()" + ></markdown> </div> diff --git a/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.scss b/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.scss index 139597f9cb07c5d48bed18984ec4747f4b4f3438..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644 --- a/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.scss +++ b/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.scss @@ -1,2 +0,0 @@ - - diff --git a/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.ts b/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.ts index 6fbf059a4fb0e39e9f4430f3dfbd3fe99818dddd..5cc604a08566bef203977aafc842e283a5cd2dc7 100644 --- a/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.ts +++ b/src/main/webapp/app/editorialPages/markDownViewer/markDownViewer.component.ts @@ -2,115 +2,118 @@ import { Component, OnInit, OnChanges, OnDestroy, Input, SimpleChanges, ViewChil import { MarkdownService } from 'ngx-markdown'; import { KatexOptions, errorKatexNotLoaded, MarkdownComponent } from 'ngx-markdown'; import { TranslateService } from '@ngx-translate/core'; -import { PagesService, EditorialPage } from 'app/shared/service/pages-service' +import { PagesService, EditorialPage } from 'app/shared/service/pages-service'; import { Router } from '@angular/router'; - declare let katex: any; // Magic - @Component({ - selector: 'jhi-pages-markdown-viewer', - templateUrl: './markDownViewer.component.html', - styleUrls: ['./markDownViewer.component.scss'], + selector: 'jhi-pages-markdown-viewer', + templateUrl: './markDownViewer.component.html', + styleUrls: ['./markDownViewer.component.scss'], }) export class PagesMarkDownViewerComponent implements OnInit, OnChanges, OnDestroy { - @Input() path: string; - - page: EditorialPage; - - // see https://github.com/jfcere/ngx-markdown/issues/125 - private listenObj: any; - - @ViewChild('pageMarkDown', {static: false}) - private pageMarkDown: MarkdownComponent | null; - - public katexOptions: KatexOptions = { - displayMode: true, - throwOnError: false, - errorColor: '#cc0000', + @Input() path: string; + + page: EditorialPage; + + // see https://github.com/jfcere/ngx-markdown/issues/125 + private listenObj: any; + + @ViewChild('pageMarkDown', { static: false }) + private pageMarkDown: MarkdownComponent | null; + + public katexOptions: KatexOptions = { + displayMode: true, + throwOnError: false, + errorColor: '#cc0000', + }; + + constructor( + private translateService: TranslateService, + private pagesService: PagesService, + private markdownService: MarkdownService, + private renderer: Renderer2, + private router: Router + ) { + this.path = ''; + this.page = { + path: 'page content loading', + content: '', }; + this.pageMarkDown = null; + this.translateService.onLangChange.subscribe(() => { + this.reloadContent(); + }); + } - constructor(private translateService: TranslateService, private pagesService: PagesService, - private markdownService: MarkdownService, private renderer: Renderer2, private router: Router) { - this.path = ''; - this.page = { - path: 'page content loading', - content: '', - } - this.pageMarkDown = null; - - this.translateService.onLangChange.subscribe(() => { - this.reloadContent(); - }); - - } + ngOnInit(): void { + this.markdownService.renderKatex = (html: string, options?: KatexOptions) => this.renderKatex(html, options); - ngOnInit(): void { - this.markdownService.renderKatex = (html: string, options?: KatexOptions) => this.renderKatex(html, options); - - this.reloadContent(); - } + this.reloadContent(); + } - // eslint-disable-next-line - ngOnChanges(changes: SimpleChanges): void { - this.reloadContent(); - } - - - ngOnDestroy(): void { + // eslint-disable-next-line + ngOnChanges(changes: SimpleChanges): void { + this.reloadContent(); + } + + ngOnDestroy(): void { if (this.listenObj) { this.listenObj(); } } - private reloadContent():void { - const lang = this.translateService.currentLang; - if (this.path) - this.pagesService.getPage(lang + this.path).subscribe( - pageContent => { this.page = pageContent; }, - e => { this.page.content = "Die Seite " + this.path + " konnte nicht geladen werden." - console.error(`Page ${this.path} not loaded: ${e.message as string}`) } - ) - } - - /** helper function for special latex rendering with katex */ - private renderKatex(html: string, options?: KatexOptions): string { - if (typeof katex === 'undefined' || typeof katex.renderToString === 'undefined') { - throw new Error(errorKatexNotLoaded); + private reloadContent(): void { + const lang = this.translateService.currentLang; + if (this.path) + this.pagesService.getPage(lang + this.path).subscribe( + pageContent => { + this.page = pageContent; + }, + e => { + this.page.content = 'Die Seite ' + this.path + ' konnte nicht geladen werden.'; + console.error(`Page ${this.path} not loaded: ${e.message as string}`); } - const reDollar = /\$([^\s][^$]*?[^\s])\$/gm; - const html2 = html.replace(reDollar, (_, tex) => this.renderSanitizedLatex(tex, options)); - const reMath = /<code class="language-math">((.|\n|\r])*?)<\/code>/gi; - return html2.replace(reMath, (_, tex) => this.renderSanitizedLatex(tex, options)); - } + ); + } - /** wrapper to sanitize latex before rendering with latex */ - private renderSanitizedLatex(latex: string, options?: KatexOptions): string { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return katex.renderToString(this.replaceConfusingCharKatex(latex), options); + /** helper function for special latex rendering with katex */ + private renderKatex(html: string, options?: KatexOptions): string { + if (typeof katex === 'undefined' || typeof katex.renderToString === 'undefined') { + throw new Error(errorKatexNotLoaded); } + const reDollar = /\$([^\s][^$]*?[^\s])\$/gm; + const html2 = html.replace(reDollar, (_, tex) => this.renderSanitizedLatex(tex, options)); + const reMath = /<code class="language-math">((.|\n|\r])*?)<\/code>/gi; + return html2.replace(reMath, (_, tex) => this.renderSanitizedLatex(tex, options)); + } - /** these html entities must be reverted, in order to work with katex :-( */ - private replaceConfusingCharKatex(html: string): string { - return html - .replace(/&/gm, '&') - .replace(/</gm, '<') - .replace(/>/gm, '>') - .replace(/·/gm, '·') - .replace(/ /gm, '·') - .replace(/( \\ )+/gm, ' \\\\ '); - } - - - public fixLinksToGoViaRouter():void { + /** wrapper to sanitize latex before rendering with latex */ + private renderSanitizedLatex(latex: string, options?: KatexOptions): string { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return katex.renderToString(this.replaceConfusingCharKatex(latex), options); + } + + /** these html entities must be reverted, in order to work with katex :-( */ + private replaceConfusingCharKatex(html: string): string { + return html + .replace(/&/gm, '&') + .replace(/</gm, '<') + .replace(/>/gm, '>') + .replace(/·/gm, '·') + .replace(/ /gm, '·') + .replace(/( \\ )+/gm, ' \\\\ '); + } + + public fixLinksToGoViaRouter(): void { // because MarkdownComponent isn't 'compiled' the links don't use the angular router, // so I'll catch the link click events here and pass them to the router... if (this.pageMarkDown) { this.listenObj = this.renderer.listen(this.pageMarkDown.element.nativeElement, 'click', (e: Event) => { if (e.target && (e.target as any).tagName === 'A') { - const el = (e.target as HTMLElement); + const el = e.target as HTMLElement; const linkURL = el.getAttribute && el.getAttribute('href'); if (linkURL && linkURL.startsWith('/pages')) { e.preventDefault(); @@ -120,5 +123,4 @@ export class PagesMarkDownViewerComponent implements OnInit, OnChanges, OnDestro }); } } - } diff --git a/src/main/webapp/app/editorialPages/pages.component.html b/src/main/webapp/app/editorialPages/pages.component.html index ce36c7f22d04126a65544ffa64d5ca51c4d2a466..33ce41562f2f04dcf6c6767157837b21c3470366 100644 --- a/src/main/webapp/app/editorialPages/pages.component.html +++ b/src/main/webapp/app/editorialPages/pages.component.html @@ -1,7 +1,5 @@ <div class="row"> - <div class="col-md-12"> - <jhi-pages-markdown-viewer [path]="pagePath" ></jhi-pages-markdown-viewer> - - </div> + <div class="col-md-12"> + <jhi-pages-markdown-viewer [path]="pagePath"></jhi-pages-markdown-viewer> + </div> </div> - diff --git a/src/main/webapp/app/editorialPages/pages.component.ts b/src/main/webapp/app/editorialPages/pages.component.ts index 6c72a0468fb2881cea9007c78e0080da931cd097..eb5fef03452e3aa576fc85cf8cc7d8bbda7a3c3a 100644 --- a/src/main/webapp/app/editorialPages/pages.component.ts +++ b/src/main/webapp/app/editorialPages/pages.component.ts @@ -7,18 +7,13 @@ import { ActivatedRoute } from '@angular/router'; templateUrl: './pages.component.html', }) export class PagesComponent implements OnInit { - - pagePath = "/testPage"; - + pagePath = '/testPage'; - constructor(private activatedRoute: ActivatedRoute - ) { - } + constructor(private activatedRoute: ActivatedRoute) {} ngOnInit(): void { this.activatedRoute.data.subscribe(({ pagePath }) => { this.pagePath = pagePath; }); } - } diff --git a/src/main/webapp/app/editorialPages/pages.route.ts b/src/main/webapp/app/editorialPages/pages.route.ts index 09e0e161e2084c45bd1fce97017342e0166c44aa..66c4a9631cebc5bf56db62bfad3144a652dfe796 100644 --- a/src/main/webapp/app/editorialPages/pages.route.ts +++ b/src/main/webapp/app/editorialPages/pages.route.ts @@ -5,7 +5,6 @@ import { PagesComponent } from './pages.component'; @Injectable({ providedIn: 'root' }) export class PagesResolve implements Resolve<String> { - resolve(route: ActivatedRouteSnapshot): Observable<String> | Observable<never> { // first is "/pages" chop off // second is "/de" (language"): chop off diff --git a/src/main/webapp/app/entities/likes/likes-delete-dialog.component.html b/src/main/webapp/app/entities/likes/likes-delete-dialog.component.html index 9a21cc29e4cd8e4b27891e4b88bfe1ba5e9b9869..057141200ff7c3f224ba18b636228c8619787e63 100644 --- a/src/main/webapp/app/entities/likes/likes-delete-dialog.component.html +++ b/src/main/webapp/app/entities/likes/likes-delete-dialog.component.html @@ -1,24 +1,25 @@ <form *ngIf="likes" name="deleteForm" (ngSubmit)="confirmDelete(likes?.id!)"> - <div class="modal-header"> - <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> + <div class="modal-header"> + <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true" - (click)="cancel()">×</button> - </div> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="cancel()">×</button> + </div> - <div class="modal-body"> - <jhi-alert-error></jhi-alert-error> + <div class="modal-body"> + <jhi-alert-error></jhi-alert-error> - <p id="jhi-delete-likes-heading" jhiTranslate="gitsearchApp.likes.delete.question" [translateValues]="{ id: likes.id }">Are you sure you want to delete this Likes?</p> - </div> + <p id="jhi-delete-likes-heading" jhiTranslate="gitsearchApp.likes.delete.question" [translateValues]="{ id: likes.id }"> + Are you sure you want to delete this Likes? + </p> + </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button id="jhi-confirm-delete-likes" type="submit" class="btn btn-danger"> - <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> - </button> - </div> + <button id="jhi-confirm-delete-likes" type="submit" class="btn btn-danger"> + <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> + </button> + </div> </form> diff --git a/src/main/webapp/app/entities/likes/likes-detail.component.html b/src/main/webapp/app/entities/likes/likes-detail.component.html index b10516a120770418f90581b87a0112bd6237d4f4..5b67069539adf21081af70cd2fdad0b53ea2e9db 100644 --- a/src/main/webapp/app/entities/likes/likes-detail.component.html +++ b/src/main/webapp/app/entities/likes/likes-detail.component.html @@ -1,38 +1,34 @@ <div class="row justify-content-center"> - <div class="col-8"> - <div *ngIf="likes"> - <h2><span jhiTranslate="gitsearchApp.likes.detail.title">Likes</span> {{ likes.id }}</h2> + <div class="col-8"> + <div *ngIf="likes"> + <h2><span jhiTranslate="gitsearchApp.likes.detail.title">Likes</span> {{ likes.id }}</h2> - <hr> + <hr /> - <jhi-alert-error></jhi-alert-error> + <jhi-alert-error></jhi-alert-error> - <dl class="row-md jh-entity-details"> - <dt><span jhiTranslate="gitsearchApp.likes.date">Date</span></dt> - <dd> - <span>{{ likes.date }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.likes.userID">User ID</span></dt> - <dd> - <span>{{ likes.userID }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.likes.exerciseID">Exercise ID</span></dt> - <dd> - <span>{{ likes.exerciseID }}</span> - </dd> - </dl> + <dl class="row-md jh-entity-details"> + <dt><span jhiTranslate="gitsearchApp.likes.date">Date</span></dt> + <dd> + <span>{{ likes.date }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.likes.userID">User ID</span></dt> + <dd> + <span>{{ likes.userID }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.likes.exerciseID">Exercise ID</span></dt> + <dd> + <span>{{ likes.exerciseID }}</span> + </dd> + </dl> - <button type="submit" - (click)="previousState()" - class="btn btn-info"> - <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> - </button> + <button type="submit" (click)="previousState()" class="btn btn-info"> + <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> + </button> - <button type="button" - [routerLink]="['/likes', likes.id, 'edit']" - class="btn btn-primary"> - <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> - </button> - </div> + <button type="button" [routerLink]="['/likes', likes.id, 'edit']" class="btn btn-primary"> + <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> + </button> </div> + </div> </div> diff --git a/src/main/webapp/app/entities/likes/likes-update.component.html b/src/main/webapp/app/entities/likes/likes-update.component.html index 73de972a16f42e18cba9e931d814482647580322..44d42457a97327ef5898e45e3458af7466812001 100644 --- a/src/main/webapp/app/entities/likes/likes-update.component.html +++ b/src/main/webapp/app/entities/likes/likes-update.component.html @@ -1,70 +1,76 @@ <div class="row justify-content-center"> - <div class="col-8"> - <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> - <h2 id="jhi-likes-heading" jhiTranslate="gitsearchApp.likes.home.createOrEditLabel">Create or edit a Likes</h2> + <div class="col-8"> + <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> + <h2 id="jhi-likes-heading" jhiTranslate="gitsearchApp.likes.home.createOrEditLabel">Create or edit a Likes</h2> - <div> - <jhi-alert-error></jhi-alert-error> + <div> + <jhi-alert-error></jhi-alert-error> - <div class="form-group" [hidden]="!editForm.get('id')!.value"> - <label for="id" jhiTranslate="global.field.id">ID</label> - <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> - </div> + <div class="form-group" [hidden]="!editForm.get('id')!.value"> + <label for="id" jhiTranslate="global.field.id">ID</label> + <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.likes.date" for="field_date">Date</label> - <div class="input-group"> - <input id="field_date" type="text" class="form-control" name="date" ngbDatepicker #dateDp="ngbDatepicker" formControlName="date"/> - <span class="input-group-append"> - <button type="button" class="btn btn-secondary" (click)="dateDp.toggle()"><fa-icon icon="calendar-alt"></fa-icon></button> - </span> - </div> - <div *ngIf="editForm.get('date')!.invalid && (editForm.get('date')!.dirty || editForm.get('date')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('date')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.likes.date" for="field_date">Date</label> + <div class="input-group"> + <input + id="field_date" + type="text" + class="form-control" + name="date" + ngbDatepicker + #dateDp="ngbDatepicker" + formControlName="date" + /> + <span class="input-group-append"> + <button type="button" class="btn btn-secondary" (click)="dateDp.toggle()"><fa-icon icon="calendar-alt"></fa-icon></button> + </span> + </div> + <div *ngIf="editForm.get('date')!.invalid && (editForm.get('date')!.dirty || editForm.get('date')!.touched)"> + <small class="form-text text-danger" *ngIf="editForm.get('date')?.errors?.required" jhiTranslate="entity.validation.required"> + This field is required. + </small> + </div> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.likes.userID" for="field_userID">User ID</label> - <input type="number" class="form-control" name="userID" id="field_userID" - formControlName="userID"/> - <div *ngIf="editForm.get('userID')!.invalid && (editForm.get('userID')!.dirty || editForm.get('userID')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('userID')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - <small class="form-text text-danger" - [hidden]="!editForm.get('userID')?.errors?.number" jhiTranslate="entity.validation.number"> - This field should be a number. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.likes.userID" for="field_userID">User ID</label> + <input type="number" class="form-control" name="userID" id="field_userID" formControlName="userID" /> + <div *ngIf="editForm.get('userID')!.invalid && (editForm.get('userID')!.dirty || editForm.get('userID')!.touched)"> + <small class="form-text text-danger" *ngIf="editForm.get('userID')?.errors?.required" jhiTranslate="entity.validation.required"> + This field is required. + </small> + <small class="form-text text-danger" [hidden]="!editForm.get('userID')?.errors?.number" jhiTranslate="entity.validation.number"> + This field should be a number. + </small> + </div> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.likes.exerciseID" for="field_exerciseID">Exercise ID</label> - <input type="text" class="form-control" name="exerciseID" id="field_exerciseID" - formControlName="exerciseID"/> - <div *ngIf="editForm.get('exerciseID')!.invalid && (editForm.get('exerciseID')!.dirty || editForm.get('exerciseID')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('exerciseID')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - </div> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.likes.exerciseID" for="field_exerciseID">Exercise ID</label> + <input type="text" class="form-control" name="exerciseID" id="field_exerciseID" formControlName="exerciseID" /> + <div *ngIf="editForm.get('exerciseID')!.invalid && (editForm.get('exerciseID')!.dirty || editForm.get('exerciseID')!.touched)"> + <small + class="form-text text-danger" + *ngIf="editForm.get('exerciseID')?.errors?.required" + jhiTranslate="entity.validation.required" + > + This field is required. + </small> + </div> + </div> + </div> - <div> - <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div> + <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> - <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> - </button> - </div> - </form> - </div> + <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> + <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> + </button> + </div> + </form> + </div> </div> diff --git a/src/main/webapp/app/entities/saved-searches/saved-searches-delete-dialog.component.html b/src/main/webapp/app/entities/saved-searches/saved-searches-delete-dialog.component.html index 33e96682eff44003b9e73b0ca484a1063fad18a0..6c302fd9b004b17ad6df744eac9dd4980db4e73b 100644 --- a/src/main/webapp/app/entities/saved-searches/saved-searches-delete-dialog.component.html +++ b/src/main/webapp/app/entities/saved-searches/saved-searches-delete-dialog.component.html @@ -1,24 +1,29 @@ <form *ngIf="savedSearches" name="deleteForm" (ngSubmit)="confirmDelete(savedSearches?.id!)"> - <div class="modal-header"> - <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> + <div class="modal-header"> + <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true" - (click)="cancel()">×</button> - </div> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="cancel()">×</button> + </div> - <div class="modal-body"> - <jhi-alert-error></jhi-alert-error> + <div class="modal-body"> + <jhi-alert-error></jhi-alert-error> - <p id="jhi-delete-savedSearches-heading" jhiTranslate="gitsearchApp.savedSearches.delete.question" [translateValues]="{ id: savedSearches.id }">Are you sure you want to delete this Saved Searches?</p> - </div> + <p + id="jhi-delete-savedSearches-heading" + jhiTranslate="gitsearchApp.savedSearches.delete.question" + [translateValues]="{ id: savedSearches.id }" + > + Are you sure you want to delete this Saved Searches? + </p> + </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button id="jhi-confirm-delete-savedSearches" type="submit" class="btn btn-danger"> - <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> - </button> - </div> + <button id="jhi-confirm-delete-savedSearches" type="submit" class="btn btn-danger"> + <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> + </button> + </div> </form> diff --git a/src/main/webapp/app/entities/saved-searches/saved-searches-detail.component.html b/src/main/webapp/app/entities/saved-searches/saved-searches-detail.component.html index de96f38c4cb830cb4e7709082ed799650ce5408a..82f354e0392f0ba45be1c0307dd280a7b64e94fd 100644 --- a/src/main/webapp/app/entities/saved-searches/saved-searches-detail.component.html +++ b/src/main/webapp/app/entities/saved-searches/saved-searches-detail.component.html @@ -1,38 +1,34 @@ <div class="row justify-content-center"> - <div class="col-8"> - <div *ngIf="savedSearches"> - <h2><span jhiTranslate="gitsearchApp.savedSearches.detail.title">Saved Searches</span> {{ savedSearches.id }}</h2> + <div class="col-8"> + <div *ngIf="savedSearches"> + <h2><span jhiTranslate="gitsearchApp.savedSearches.detail.title">Saved Searches</span> {{ savedSearches.id }}</h2> - <hr> + <hr /> - <jhi-alert-error></jhi-alert-error> + <jhi-alert-error></jhi-alert-error> - <dl class="row-md jh-entity-details"> - <dt><span jhiTranslate="gitsearchApp.savedSearches.name">Name</span></dt> - <dd> - <span>{{ savedSearches.name }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.savedSearches.jsonQuery">Json Query</span></dt> - <dd> - <span>{{ savedSearches.jsonQuery }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.savedSearches.userId">User Id</span></dt> - <dd> - {{ savedSearches.userLogin }} - </dd> - </dl> + <dl class="row-md jh-entity-details"> + <dt><span jhiTranslate="gitsearchApp.savedSearches.name">Name</span></dt> + <dd> + <span>{{ savedSearches.name }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.savedSearches.jsonQuery">Json Query</span></dt> + <dd> + <span>{{ savedSearches.jsonQuery }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.savedSearches.userId">User Id</span></dt> + <dd> + {{ savedSearches.userLogin }} + </dd> + </dl> - <button type="submit" - (click)="previousState()" - class="btn btn-info"> - <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> - </button> + <button type="submit" (click)="previousState()" class="btn btn-info"> + <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> + </button> - <button type="button" - [routerLink]="['/saved-searches', savedSearches.id, 'edit']" - class="btn btn-primary"> - <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> - </button> - </div> + <button type="button" [routerLink]="['/saved-searches', savedSearches.id, 'edit']" class="btn btn-primary"> + <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> + </button> </div> + </div> </div> diff --git a/src/main/webapp/app/entities/saved-searches/saved-searches-update.component.html b/src/main/webapp/app/entities/saved-searches/saved-searches-update.component.html index 6c4746b96041fc3ffc4d2d72a30b07cc1619a1a2..9d4784133dcef4efbd8bb9bae94847ce87dde8b9 100644 --- a/src/main/webapp/app/entities/saved-searches/saved-searches-update.component.html +++ b/src/main/webapp/app/entities/saved-searches/saved-searches-update.component.html @@ -1,68 +1,73 @@ <div class="row justify-content-center"> - <div class="col-8"> - <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> - <h2 id="jhi-saved-searches-heading" jhiTranslate="gitsearchApp.savedSearches.home.createOrEditLabel">Create or edit a Saved Searches</h2> + <div class="col-8"> + <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> + <h2 id="jhi-saved-searches-heading" jhiTranslate="gitsearchApp.savedSearches.home.createOrEditLabel"> + Create or edit a Saved Searches + </h2> - <div> - <jhi-alert-error></jhi-alert-error> + <div> + <jhi-alert-error></jhi-alert-error> - <div class="form-group" [hidden]="!editForm.get('id')!.value"> - <label for="id" jhiTranslate="global.field.id">ID</label> - <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> - </div> + <div class="form-group" [hidden]="!editForm.get('id')!.value"> + <label for="id" jhiTranslate="global.field.id">ID</label> + <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.savedSearches.name" for="field_name">Name</label> - <input type="text" class="form-control" name="name" id="field_name" - formControlName="name"/> - <div *ngIf="editForm.get('name')!.invalid && (editForm.get('name')!.dirty || editForm.get('name')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('name')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - <small class="form-text text-danger" - *ngIf="editForm.get('name')?.errors?.minlength" jhiTranslate="entity.validation.minlength" [translateValues]="{ min: 1 }"> - This field is required to be at least 1 characters. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.savedSearches.name" for="field_name">Name</label> + <input type="text" class="form-control" name="name" id="field_name" formControlName="name" /> + <div *ngIf="editForm.get('name')!.invalid && (editForm.get('name')!.dirty || editForm.get('name')!.touched)"> + <small class="form-text text-danger" *ngIf="editForm.get('name')?.errors?.required" jhiTranslate="entity.validation.required"> + This field is required. + </small> + <small + class="form-text text-danger" + *ngIf="editForm.get('name')?.errors?.minlength" + jhiTranslate="entity.validation.minlength" + [translateValues]="{ min: 1 }" + > + This field is required to be at least 1 characters. + </small> + </div> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.savedSearches.jsonQuery" for="field_jsonQuery">Json Query</label> - <input type="text" class="form-control" name="jsonQuery" id="field_jsonQuery" - formControlName="jsonQuery"/> - <div *ngIf="editForm.get('jsonQuery')!.invalid && (editForm.get('jsonQuery')!.dirty || editForm.get('jsonQuery')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('jsonQuery')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.savedSearches.jsonQuery" for="field_jsonQuery">Json Query</label> + <input type="text" class="form-control" name="jsonQuery" id="field_jsonQuery" formControlName="jsonQuery" /> + <div *ngIf="editForm.get('jsonQuery')!.invalid && (editForm.get('jsonQuery')!.dirty || editForm.get('jsonQuery')!.touched)"> + <small + class="form-text text-danger" + *ngIf="editForm.get('jsonQuery')?.errors?.required" + jhiTranslate="entity.validation.required" + > + This field is required. + </small> + </div> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.savedSearches.userId" for="field_userId">User Id</label> - <select class="form-control" id="field_userId" name="userId" formControlName="userId"> - <option *ngIf="!editForm.get('userId')!.value" [ngValue]="null" selected></option> - <option [ngValue]="userOption.id" *ngFor="let userOption of users; trackBy: trackById">{{ userOption.login }}</option> - </select> - </div> - <div *ngIf="editForm.get('userId')!.invalid && (editForm.get('userId')!.dirty || editForm.get('userId')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('userId')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.savedSearches.userId" for="field_userId">User Id</label> + <select class="form-control" id="field_userId" name="userId" formControlName="userId"> + <option *ngIf="!editForm.get('userId')!.value" [ngValue]="null" selected></option> + <option [ngValue]="userOption.id" *ngFor="let userOption of users; trackBy: trackById">{{ userOption.login }}</option> + </select> + </div> + <div *ngIf="editForm.get('userId')!.invalid && (editForm.get('userId')!.dirty || editForm.get('userId')!.touched)"> + <small class="form-text text-danger" *ngIf="editForm.get('userId')?.errors?.required" jhiTranslate="entity.validation.required"> + This field is required. + </small> + </div> + </div> - <div> - <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div> + <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> - <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> - </button> - </div> - </form> - </div> + <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> + <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> + </button> + </div> + </form> + </div> </div> diff --git a/src/main/webapp/app/entities/statistics/statistics-delete-dialog.component.html b/src/main/webapp/app/entities/statistics/statistics-delete-dialog.component.html index b6a356dce7d0c3fa9c903e02491b63d2ced0c588..00596e3a9932ed07219d7e6aa56b8fea12ec6706 100644 --- a/src/main/webapp/app/entities/statistics/statistics-delete-dialog.component.html +++ b/src/main/webapp/app/entities/statistics/statistics-delete-dialog.component.html @@ -1,24 +1,25 @@ <form *ngIf="statistics" name="deleteForm" (ngSubmit)="confirmDelete(statistics?.id!)"> - <div class="modal-header"> - <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> + <div class="modal-header"> + <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true" - (click)="cancel()">×</button> - </div> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="cancel()">×</button> + </div> - <div class="modal-body"> - <jhi-alert-error></jhi-alert-error> + <div class="modal-body"> + <jhi-alert-error></jhi-alert-error> - <p id="jhi-delete-statistics-heading" jhiTranslate="gitsearchApp.statistics.delete.question" [translateValues]="{ id: statistics.id }">Are you sure you want to delete this Statistics?</p> - </div> + <p id="jhi-delete-statistics-heading" jhiTranslate="gitsearchApp.statistics.delete.question" [translateValues]="{ id: statistics.id }"> + Are you sure you want to delete this Statistics? + </p> + </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button id="jhi-confirm-delete-statistics" type="submit" class="btn btn-danger"> - <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> - </button> - </div> + <button id="jhi-confirm-delete-statistics" type="submit" class="btn btn-danger"> + <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> + </button> + </div> </form> diff --git a/src/main/webapp/app/entities/statistics/statistics-delete-dialog.component.ts b/src/main/webapp/app/entities/statistics/statistics-delete-dialog.component.ts index c01041bf064b9425ee274c846739562b51dfe16b..caf38dc3db2f8a834275ac9ded8eb4dccba2bdf9 100644 --- a/src/main/webapp/app/entities/statistics/statistics-delete-dialog.component.ts +++ b/src/main/webapp/app/entities/statistics/statistics-delete-dialog.component.ts @@ -11,11 +11,7 @@ import { StatisticsService } from './statistics.service'; export class StatisticsDeleteDialogComponent { statistics?: IStatistics; - constructor( - protected statisticsService: StatisticsService, - public activeModal: NgbActiveModal, - protected eventManager: EventManager - ) {} + constructor(protected statisticsService: StatisticsService, public activeModal: NgbActiveModal, protected eventManager: EventManager) {} cancel(): void { this.activeModal.dismiss(); diff --git a/src/main/webapp/app/entities/statistics/statistics-detail.component.html b/src/main/webapp/app/entities/statistics/statistics-detail.component.html index a8d3c44402eb9f6a2b109d67da4921fbf9a4f5f9..b6e337c8daae3c73a69708b5d89d1cae1ce58996 100644 --- a/src/main/webapp/app/entities/statistics/statistics-detail.component.html +++ b/src/main/webapp/app/entities/statistics/statistics-detail.component.html @@ -1,38 +1,34 @@ <div class="row justify-content-center"> - <div class="col-8"> - <div *ngIf="statistics"> - <h2><span jhiTranslate="gitsearchApp.statistics.detail.title">Statistics</span> {{ statistics.id }}</h2> + <div class="col-8"> + <div *ngIf="statistics"> + <h2><span jhiTranslate="gitsearchApp.statistics.detail.title">Statistics</span> {{ statistics.id }}</h2> - <hr> + <hr /> - <jhi-alert-error></jhi-alert-error> + <jhi-alert-error></jhi-alert-error> - <dl class="row-md jh-entity-details"> - <dt><span jhiTranslate="gitsearchApp.statistics.views">Views</span></dt> - <dd> - <span>{{ statistics.views }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.statistics.downloads">Downloads</span></dt> - <dd> - <span>{{ statistics.downloads }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.statistics.exerciseID">Exercise ID</span></dt> - <dd> - <span>{{ statistics.exerciseID }}</span> - </dd> - </dl> + <dl class="row-md jh-entity-details"> + <dt><span jhiTranslate="gitsearchApp.statistics.views">Views</span></dt> + <dd> + <span>{{ statistics.views }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.statistics.downloads">Downloads</span></dt> + <dd> + <span>{{ statistics.downloads }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.statistics.exerciseID">Exercise ID</span></dt> + <dd> + <span>{{ statistics.exerciseID }}</span> + </dd> + </dl> - <button type="submit" - (click)="previousState()" - class="btn btn-info"> - <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> - </button> + <button type="submit" (click)="previousState()" class="btn btn-info"> + <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> + </button> - <button type="button" - [routerLink]="['/statistics', statistics.id, 'edit']" - class="btn btn-primary"> - <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> - </button> - </div> + <button type="button" [routerLink]="['/statistics', statistics.id, 'edit']" class="btn btn-primary"> + <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> + </button> </div> + </div> </div> diff --git a/src/main/webapp/app/entities/statistics/statistics-update.component.html b/src/main/webapp/app/entities/statistics/statistics-update.component.html index 08aa08dc4e23383fdb33cb5a1943f9f7b0c732ef..8d2b1da27f464393646a90b522c3e45c9d81b647 100644 --- a/src/main/webapp/app/entities/statistics/statistics-update.component.html +++ b/src/main/webapp/app/entities/statistics/statistics-update.component.html @@ -1,54 +1,57 @@ <div class="row justify-content-center"> - <div class="col-8"> - <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> - <h2 id="jhi-statistics-heading" jhiTranslate="gitsearchApp.statistics.home.createOrEditLabel">Create or edit a Statistics</h2> + <div class="col-8"> + <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> + <h2 id="jhi-statistics-heading" jhiTranslate="gitsearchApp.statistics.home.createOrEditLabel">Create or edit a Statistics</h2> - <div> - <jhi-alert-error></jhi-alert-error> + <div> + <jhi-alert-error></jhi-alert-error> - <div class="form-group" [hidden]="!editForm.get('id')!.value"> - <label for="id" jhiTranslate="global.field.id">ID</label> - <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> - </div> + <div class="form-group" [hidden]="!editForm.get('id')!.value"> + <label for="id" jhiTranslate="global.field.id">ID</label> + <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.statistics.views" for="field_views">Views</label> - <input type="number" class="form-control" name="views" id="field_views" - formControlName="views"/> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.statistics.views" for="field_views">Views</label> + <input type="number" class="form-control" name="views" id="field_views" formControlName="views" /> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.statistics.downloads" for="field_downloads">Downloads</label> - <input type="number" class="form-control" name="downloads" id="field_downloads" - formControlName="downloads"/> - <div *ngIf="editForm.get('downloads')!.invalid && (editForm.get('downloads')!.dirty || editForm.get('downloads')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('downloads')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - <small class="form-text text-danger" - [hidden]="!editForm.get('downloads')?.errors?.number" jhiTranslate="entity.validation.number"> - This field should be a number. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.statistics.downloads" for="field_downloads">Downloads</label> + <input type="number" class="form-control" name="downloads" id="field_downloads" formControlName="downloads" /> + <div *ngIf="editForm.get('downloads')!.invalid && (editForm.get('downloads')!.dirty || editForm.get('downloads')!.touched)"> + <small + class="form-text text-danger" + *ngIf="editForm.get('downloads')?.errors?.required" + jhiTranslate="entity.validation.required" + > + This field is required. + </small> + <small + class="form-text text-danger" + [hidden]="!editForm.get('downloads')?.errors?.number" + jhiTranslate="entity.validation.number" + > + This field should be a number. + </small> + </div> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.statistics.exerciseID" for="field_exerciseID">Exercise ID</label> - <input type="number" class="form-control" name="exerciseID" id="field_exerciseID" - formControlName="exerciseID"/> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.statistics.exerciseID" for="field_exerciseID">Exercise ID</label> + <input type="number" class="form-control" name="exerciseID" id="field_exerciseID" formControlName="exerciseID" /> + </div> + </div> - <div> - <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div> + <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> - <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> - </button> - </div> - </form> - </div> + <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> + <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> + </button> + </div> + </form> + </div> </div> diff --git a/src/main/webapp/app/entities/statistics/statistics.component.ts b/src/main/webapp/app/entities/statistics/statistics.component.ts index 0d17097be393e26891b1998b2c41cd43edc7977a..6d318601fd1dac72ee302a55820e7a3976ef3801 100644 --- a/src/main/webapp/app/entities/statistics/statistics.component.ts +++ b/src/main/webapp/app/entities/statistics/statistics.component.ts @@ -52,10 +52,10 @@ export class StatisticsComponent implements OnInit, OnDestroy { this.statisticsService .search({ query: this.currentSearch, -// TODO -// page: this.page, -// size: this.itemsPerPage, -// sort: this.sort(), + // TODO + // page: this.page, + // size: this.itemsPerPage, + // sort: this.sort(), }) .subscribe((res: HttpResponse<IStatistics[]>) => this.paginateStatistics(res.body, res.headers)); return; diff --git a/src/main/webapp/app/entities/statistics/statistics.service.ts b/src/main/webapp/app/entities/statistics/statistics.service.ts index e3bb01f7cf355f47bf8de598ed6651bd7ce1fc0b..dded10df8a7577d1385060a6aecb2a3195989500 100644 --- a/src/main/webapp/app/entities/statistics/statistics.service.ts +++ b/src/main/webapp/app/entities/statistics/statistics.service.ts @@ -3,7 +3,7 @@ import { Injectable } from '@angular/core'; import { ApplicationConfigService } from 'app/core/config/application-config.service'; import { IStatistics } from 'app/shared/model/statistics.model'; import { createRequestOption } from 'app/core/request/request-util'; -import { Search } from 'app/core/request/request.model' +import { Search } from 'app/core/request/request.model'; import { Observable } from 'rxjs'; type EntityResponseType = HttpResponse<IStatistics>; diff --git a/src/main/webapp/app/entities/user-watch-list/user-watch-list-delete-dialog.component.html b/src/main/webapp/app/entities/user-watch-list/user-watch-list-delete-dialog.component.html index 5fe08adc23a768b99b9ae19df4dcc844debed868..8c6d9a5f1b40ebe64e5a0c0ae1f7c3eb1caeda43 100644 --- a/src/main/webapp/app/entities/user-watch-list/user-watch-list-delete-dialog.component.html +++ b/src/main/webapp/app/entities/user-watch-list/user-watch-list-delete-dialog.component.html @@ -1,24 +1,29 @@ <form *ngIf="userWatchList" name="deleteForm" (ngSubmit)="confirmDelete(userWatchList?.id!)"> - <div class="modal-header"> - <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> + <div class="modal-header"> + <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true" - (click)="cancel()">×</button> - </div> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="cancel()">×</button> + </div> - <div class="modal-body"> - <jhi-alert-error></jhi-alert-error> + <div class="modal-body"> + <jhi-alert-error></jhi-alert-error> - <p id="jhi-delete-userWatchList-heading" jhiTranslate="gitsearchApp.userWatchList.delete.question" [translateValues]="{ id: userWatchList.id }">Are you sure you want to delete this User Watch List?</p> - </div> + <p + id="jhi-delete-userWatchList-heading" + jhiTranslate="gitsearchApp.userWatchList.delete.question" + [translateValues]="{ id: userWatchList.id }" + > + Are you sure you want to delete this User Watch List? + </p> + </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button id="jhi-confirm-delete-userWatchList" type="submit" class="btn btn-danger"> - <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> - </button> - </div> + <button id="jhi-confirm-delete-userWatchList" type="submit" class="btn btn-danger"> + <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> + </button> + </div> </form> diff --git a/src/main/webapp/app/entities/user-watch-list/user-watch-list-detail.component.html b/src/main/webapp/app/entities/user-watch-list/user-watch-list-detail.component.html index 5efdd0448d4a6b2fb4c517515d7863ebeffbf381..73211c20d60cb0039b96a03c8a6649178de61157 100644 --- a/src/main/webapp/app/entities/user-watch-list/user-watch-list-detail.component.html +++ b/src/main/webapp/app/entities/user-watch-list/user-watch-list-detail.component.html @@ -1,38 +1,34 @@ <div class="row justify-content-center"> - <div class="col-8"> - <div *ngIf="userWatchList"> - <h2><span jhiTranslate="gitsearchApp.userWatchList.detail.title">User Watch List</span> {{ userWatchList.id }}</h2> + <div class="col-8"> + <div *ngIf="userWatchList"> + <h2><span jhiTranslate="gitsearchApp.userWatchList.detail.title">User Watch List</span> {{ userWatchList.id }}</h2> - <hr> + <hr /> - <jhi-alert-error></jhi-alert-error> + <jhi-alert-error></jhi-alert-error> - <dl class="row-md jh-entity-details"> - <dt><span jhiTranslate="gitsearchApp.userWatchList.name">Name</span></dt> - <dd> - <span>{{ userWatchList.name }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.userWatchList.checkFrequency">Check Frequency</span></dt> - <dd> - <span jhiTranslate="{{ 'gitsearchApp.CheckFrequency.' + userWatchList.checkFrequency }}">{{ userWatchList.checkFrequency }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.userWatchList.userId">User Id</span></dt> - <dd> - {{ userWatchList.userLogin }} - </dd> - </dl> + <dl class="row-md jh-entity-details"> + <dt><span jhiTranslate="gitsearchApp.userWatchList.name">Name</span></dt> + <dd> + <span>{{ userWatchList.name }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.userWatchList.checkFrequency">Check Frequency</span></dt> + <dd> + <span jhiTranslate="{{ 'gitsearchApp.CheckFrequency.' + userWatchList.checkFrequency }}">{{ userWatchList.checkFrequency }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.userWatchList.userId">User Id</span></dt> + <dd> + {{ userWatchList.userLogin }} + </dd> + </dl> - <button type="submit" - (click)="previousState()" - class="btn btn-info"> - <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> - </button> + <button type="submit" (click)="previousState()" class="btn btn-info"> + <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> + </button> - <button type="button" - [routerLink]="['/user-watch-list', userWatchList.id, 'edit']" - class="btn btn-primary"> - <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> - </button> - </div> + <button type="button" [routerLink]="['/user-watch-list', userWatchList.id, 'edit']" class="btn btn-primary"> + <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> + </button> </div> + </div> </div> diff --git a/src/main/webapp/app/entities/user-watch-list/user-watch-list-update.component.html b/src/main/webapp/app/entities/user-watch-list/user-watch-list-update.component.html index 598ef6aba086b352a92a3ca9f8fb0b464b229958..dc1151622e1fca79aa626f03bb6f93840907414a 100644 --- a/src/main/webapp/app/entities/user-watch-list/user-watch-list-update.component.html +++ b/src/main/webapp/app/entities/user-watch-list/user-watch-list-update.component.html @@ -1,72 +1,84 @@ <div class="row justify-content-center"> - <div class="col-8"> - <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> - <h2 id="jhi-user-watch-list-heading" jhiTranslate="gitsearchApp.userWatchList.home.createOrEditLabel">Create or edit a User Watch List</h2> + <div class="col-8"> + <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> + <h2 id="jhi-user-watch-list-heading" jhiTranslate="gitsearchApp.userWatchList.home.createOrEditLabel"> + Create or edit a User Watch List + </h2> - <div> - <jhi-alert-error></jhi-alert-error> + <div> + <jhi-alert-error></jhi-alert-error> - <div class="form-group" [hidden]="!editForm.get('id')!.value"> - <label for="id" jhiTranslate="global.field.id">ID</label> - <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> - </div> + <div class="form-group" [hidden]="!editForm.get('id')!.value"> + <label for="id" jhiTranslate="global.field.id">ID</label> + <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.name" for="field_name">Name</label> - <input type="text" class="form-control" name="name" id="field_name" - formControlName="name"/> - <div *ngIf="editForm.get('name')!.invalid && (editForm.get('name')!.dirty || editForm.get('name')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('name')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - <small class="form-text text-danger" - *ngIf="editForm.get('name')?.errors?.minlength" jhiTranslate="entity.validation.minlength" [translateValues]="{ min: 1 }"> - This field is required to be at least 1 characters. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.name" for="field_name">Name</label> + <input type="text" class="form-control" name="name" id="field_name" formControlName="name" /> + <div *ngIf="editForm.get('name')!.invalid && (editForm.get('name')!.dirty || editForm.get('name')!.touched)"> + <small class="form-text text-danger" *ngIf="editForm.get('name')?.errors?.required" jhiTranslate="entity.validation.required"> + This field is required. + </small> + <small + class="form-text text-danger" + *ngIf="editForm.get('name')?.errors?.minlength" + jhiTranslate="entity.validation.minlength" + [translateValues]="{ min: 1 }" + > + This field is required to be at least 1 characters. + </small> + </div> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.checkFrequency" for="field_checkFrequency">Check Frequency</label> - <select class="form-control" name="checkFrequency" formControlName="checkFrequency" id="field_checkFrequency"> - <option value="NEVER">{{ 'gitsearchApp.CheckFrequency.NEVER' | translate }}</option> - <option value="DAILY">{{ 'gitsearchApp.CheckFrequency.DAILY' | translate }}</option> - <option value="WEEKLY">{{ 'gitsearchApp.CheckFrequency.WEEKLY' | translate }}</option> - <option value="MONTHLY">{{ 'gitsearchApp.CheckFrequency.MONTHLY' | translate }}</option> - </select> - <div *ngIf="editForm.get('checkFrequency')!.invalid && (editForm.get('checkFrequency')!.dirty || editForm.get('checkFrequency')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('checkFrequency')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.checkFrequency" for="field_checkFrequency" + >Check Frequency</label + > + <select class="form-control" name="checkFrequency" formControlName="checkFrequency" id="field_checkFrequency"> + <option value="NEVER">{{ 'gitsearchApp.CheckFrequency.NEVER' | translate }}</option> + <option value="DAILY">{{ 'gitsearchApp.CheckFrequency.DAILY' | translate }}</option> + <option value="WEEKLY">{{ 'gitsearchApp.CheckFrequency.WEEKLY' | translate }}</option> + <option value="MONTHLY">{{ 'gitsearchApp.CheckFrequency.MONTHLY' | translate }}</option> + </select> + <div + *ngIf=" + editForm.get('checkFrequency')!.invalid && (editForm.get('checkFrequency')!.dirty || editForm.get('checkFrequency')!.touched) + " + > + <small + class="form-text text-danger" + *ngIf="editForm.get('checkFrequency')?.errors?.required" + jhiTranslate="entity.validation.required" + > + This field is required. + </small> + </div> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.userId" for="field_userId">User Id</label> - <select class="form-control" id="field_userId" name="userId" formControlName="userId"> - <option *ngIf="!editForm.get('userId')!.value" [ngValue]="null" selected></option> - <option [ngValue]="userOption.id" *ngFor="let userOption of users; trackBy: trackById">{{ userOption.login }}</option> - </select> - </div> - <div *ngIf="editForm.get('userId')!.invalid && (editForm.get('userId')!.dirty || editForm.get('userId')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('userId')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.userWatchList.userId" for="field_userId">User Id</label> + <select class="form-control" id="field_userId" name="userId" formControlName="userId"> + <option *ngIf="!editForm.get('userId')!.value" [ngValue]="null" selected></option> + <option [ngValue]="userOption.id" *ngFor="let userOption of users; trackBy: trackById">{{ userOption.login }}</option> + </select> + </div> + <div *ngIf="editForm.get('userId')!.invalid && (editForm.get('userId')!.dirty || editForm.get('userId')!.touched)"> + <small class="form-text text-danger" *ngIf="editForm.get('userId')?.errors?.required" jhiTranslate="entity.validation.required"> + This field is required. + </small> + </div> + </div> - <div> - <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div> + <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> - <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> - </button> - </div> - </form> - </div> + <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> + <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> + </button> + </div> + </form> + </div> </div> diff --git a/src/main/webapp/app/entities/user-watch-list/user-watch-list.component.ts b/src/main/webapp/app/entities/user-watch-list/user-watch-list.component.ts index 57b905ecedb772250f10dbda84295c36f6931ea9..695f2fd4ca5357ec0dcdaaaa283266d6e3c6526f 100644 --- a/src/main/webapp/app/entities/user-watch-list/user-watch-list.component.ts +++ b/src/main/webapp/app/entities/user-watch-list/user-watch-list.component.ts @@ -53,10 +53,10 @@ export class UserWatchListComponent implements OnInit, OnDestroy { this.userWatchListService .search({ query: this.currentSearch, -// TODO -// page: this.page, -// size: this.itemsPerPage, -// sort: this.sort(), + // TODO + // page: this.page, + // size: this.itemsPerPage, + // sort: this.sort(), }) .subscribe((res: HttpResponse<IUserWatchList[]>) => this.paginateUserWatchLists(res.body, res.headers)); return; diff --git a/src/main/webapp/app/entities/user-watch-list/user-watch-list.service.ts b/src/main/webapp/app/entities/user-watch-list/user-watch-list.service.ts index b6c4bb0965febd288f6b8acc788748067d299748..a31de781b536978a8601ebed348205851e0ebb0d 100644 --- a/src/main/webapp/app/entities/user-watch-list/user-watch-list.service.ts +++ b/src/main/webapp/app/entities/user-watch-list/user-watch-list.service.ts @@ -43,7 +43,7 @@ export class UserWatchListService { } findExercises(watchlist: IUserWatchList, page: number): Observable<SearchResultsDTO> { - return this.http.post<SearchResultsDTO>(`${this.currentUserResourceUrl}/${watchlist.id || ""}`, page); + return this.http.post<SearchResultsDTO>(`${this.currentUserResourceUrl}/${watchlist.id || ''}`, page); } query(req?: any): Observable<EntityArrayResponseType> { diff --git a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-delete-dialog.component.html b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-delete-dialog.component.html index 5291dd5985601755667033efaa8f452dc55c90bb..6433b2b0e7394e92e277e6a1eff3445eade739ea 100644 --- a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-delete-dialog.component.html +++ b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-delete-dialog.component.html @@ -1,24 +1,29 @@ <form *ngIf="watchListEntry" name="deleteForm" (ngSubmit)="confirmDelete(watchListEntry?.id!)"> - <div class="modal-header"> - <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> + <div class="modal-header"> + <h4 class="modal-title" jhiTranslate="entity.delete.title">Confirm delete operation</h4> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true" - (click)="cancel()">×</button> - </div> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="cancel()">×</button> + </div> - <div class="modal-body"> - <jhi-alert-error></jhi-alert-error> + <div class="modal-body"> + <jhi-alert-error></jhi-alert-error> - <p id="jhi-delete-watchListEntry-heading" jhiTranslate="gitsearchApp.watchListEntry.delete.question" [translateValues]="{ id: watchListEntry.id }">Are you sure you want to delete this Watch List Entry?</p> - </div> + <p + id="jhi-delete-watchListEntry-heading" + jhiTranslate="gitsearchApp.watchListEntry.delete.question" + [translateValues]="{ id: watchListEntry.id }" + > + Are you sure you want to delete this Watch List Entry? + </p> + </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="cancel()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button id="jhi-confirm-delete-watchListEntry" type="submit" class="btn btn-danger"> - <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> - </button> - </div> + <button id="jhi-confirm-delete-watchListEntry" type="submit" class="btn btn-danger"> + <fa-icon icon="times"></fa-icon> <span jhiTranslate="entity.action.delete">Delete</span> + </button> + </div> </form> diff --git a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-detail.component.html b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-detail.component.html index 5c09ba7fdffad0e3df09bf560dcf7ffd6e528bef..a982c77a56389057f99f88949f5c67736aebbb58 100644 --- a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-detail.component.html +++ b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-detail.component.html @@ -1,40 +1,36 @@ <div class="row justify-content-center"> - <div class="col-8"> - <div *ngIf="watchListEntry"> - <h2><span jhiTranslate="gitsearchApp.watchListEntry.detail.title">Watch List Entry</span> {{ watchListEntry.id }}</h2> + <div class="col-8"> + <div *ngIf="watchListEntry"> + <h2><span jhiTranslate="gitsearchApp.watchListEntry.detail.title">Watch List Entry</span> {{ watchListEntry.id }}</h2> - <hr> + <hr /> - <jhi-alert-error></jhi-alert-error> + <jhi-alert-error></jhi-alert-error> - <dl class="row-md jh-entity-details"> - <dt><span jhiTranslate="gitsearchApp.watchListEntry.exerciseId">Exercise Id</span></dt> - <dd> - <span>{{ watchListEntry.exerciseId }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.watchListEntry.exerciseName">Exercise Name</span></dt> - <dd> - <span>{{ watchListEntry.exerciseName }}</span> - </dd> - <dt><span jhiTranslate="gitsearchApp.watchListEntry.watchlistId">Watchlist Id</span></dt> - <dd> - <div *ngIf="watchListEntry.watchlistId"> - <a [routerLink]="['/user-watch-list', watchListEntry.watchlistId, 'view']">{{ watchListEntry.watchlistId }}</a> - </div> - </dd> - </dl> + <dl class="row-md jh-entity-details"> + <dt><span jhiTranslate="gitsearchApp.watchListEntry.exerciseId">Exercise Id</span></dt> + <dd> + <span>{{ watchListEntry.exerciseId }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.watchListEntry.exerciseName">Exercise Name</span></dt> + <dd> + <span>{{ watchListEntry.exerciseName }}</span> + </dd> + <dt><span jhiTranslate="gitsearchApp.watchListEntry.watchlistId">Watchlist Id</span></dt> + <dd> + <div *ngIf="watchListEntry.watchlistId"> + <a [routerLink]="['/user-watch-list', watchListEntry.watchlistId, 'view']">{{ watchListEntry.watchlistId }}</a> + </div> + </dd> + </dl> - <button type="submit" - (click)="previousState()" - class="btn btn-info"> - <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> - </button> + <button type="submit" (click)="previousState()" class="btn btn-info"> + <fa-icon icon="arrow-left"></fa-icon> <span jhiTranslate="entity.action.back">Back</span> + </button> - <button type="button" - [routerLink]="['/watch-list-entry', watchListEntry.id, 'edit']" - class="btn btn-primary"> - <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> - </button> - </div> + <button type="button" [routerLink]="['/watch-list-entry', watchListEntry.id, 'edit']" class="btn btn-primary"> + <fa-icon icon="pencil-alt"></fa-icon> <span jhiTranslate="entity.action.edit">Edit</span> + </button> </div> + </div> </div> diff --git a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-detail.component.ts b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-detail.component.ts index ce5eb5a02c4f2c63f9229c2211699a151efb9843..7b2b72b679f9cc079fe3b9c689a973fc420f190c 100644 --- a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-detail.component.ts +++ b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-detail.component.ts @@ -4,20 +4,20 @@ import { ActivatedRoute } from '@angular/router'; import { IWatchListEntry } from 'app/shared/model/watch-list-entry.model'; @Component({ - selector: 'jhi-watch-list-entry-detail', - templateUrl: './watch-list-entry-detail.component.html', + selector: 'jhi-watch-list-entry-detail', + templateUrl: './watch-list-entry-detail.component.html', }) export class WatchListEntryDetailComponent implements OnInit { - watchListEntry: IWatchListEntry | null = null; + watchListEntry: IWatchListEntry | null = null; - constructor(protected activatedRoute: ActivatedRoute) { } + constructor(protected activatedRoute: ActivatedRoute) {} - ngOnInit(): void { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - this.activatedRoute.data.subscribe(({ watchListEntry }) => (this.watchListEntry = watchListEntry)); - } + ngOnInit(): void { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + this.activatedRoute.data.subscribe(({ watchListEntry }) => (this.watchListEntry = watchListEntry)); + } - previousState(): void { - window.history.back(); - } + previousState(): void { + window.history.back(); + } } diff --git a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-update.component.html b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-update.component.html index f8f8f4d2fdb9e9532245422f1b508a3eee50ee05..d8e342f8358edd9b89fc53bc60a04547b5f2f9bb 100644 --- a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-update.component.html +++ b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry-update.component.html @@ -1,58 +1,70 @@ <div class="row justify-content-center"> - <div class="col-8"> - <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> - <h2 id="jhi-watch-list-entry-heading" jhiTranslate="gitsearchApp.watchListEntry.home.createOrEditLabel">Create or edit a Watch List Entry</h2> + <div class="col-8"> + <form name="editForm" role="form" novalidate (ngSubmit)="save()" [formGroup]="editForm"> + <h2 id="jhi-watch-list-entry-heading" jhiTranslate="gitsearchApp.watchListEntry.home.createOrEditLabel"> + Create or edit a Watch List Entry + </h2> - <div> - <jhi-alert-error></jhi-alert-error> + <div> + <jhi-alert-error></jhi-alert-error> - <div class="form-group" [hidden]="!editForm.get('id')!.value"> - <label for="id" jhiTranslate="global.field.id">ID</label> - <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> - </div> + <div class="form-group" [hidden]="!editForm.get('id')!.value"> + <label for="id" jhiTranslate="global.field.id">ID</label> + <input type="text" class="form-control" id="id" name="id" formControlName="id" readonly /> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.watchListEntry.exerciseId" for="field_exerciseId">Exercise Id</label> - <input type="text" class="form-control" name="exerciseId" id="field_exerciseId" - formControlName="exerciseId"/> - <div *ngIf="editForm.get('exerciseId')!.invalid && (editForm.get('exerciseId')!.dirty || editForm.get('exerciseId')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('exerciseId')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.watchListEntry.exerciseId" for="field_exerciseId">Exercise Id</label> + <input type="text" class="form-control" name="exerciseId" id="field_exerciseId" formControlName="exerciseId" /> + <div *ngIf="editForm.get('exerciseId')!.invalid && (editForm.get('exerciseId')!.dirty || editForm.get('exerciseId')!.touched)"> + <small + class="form-text text-danger" + *ngIf="editForm.get('exerciseId')?.errors?.required" + jhiTranslate="entity.validation.required" + > + This field is required. + </small> + </div> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.watchListEntry.exerciseName" for="field_exerciseName">Exercise Name</label> - <input type="text" class="form-control" name="exerciseName" id="field_exerciseName" - formControlName="exerciseName"/> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.watchListEntry.exerciseName" for="field_exerciseName" + >Exercise Name</label + > + <input type="text" class="form-control" name="exerciseName" id="field_exerciseName" formControlName="exerciseName" /> + </div> - <div class="form-group"> - <label class="form-control-label" jhiTranslate="gitsearchApp.watchListEntry.watchlistId" for="field_watchlistId">Watchlist Id</label> - <select class="form-control" id="field_watchlistId" name="watchlistId" formControlName="watchlistId"> - <option *ngIf="!editForm.get('watchlistId')!.value" [ngValue]="null" selected></option> - <option [ngValue]="userWatchListOption.id" *ngFor="let userWatchListOption of userwatchlists; trackBy: trackById">{{ userWatchListOption.id }}</option> - </select> - </div> - <div *ngIf="editForm.get('watchlistId')!.invalid && (editForm.get('watchlistId')!.dirty || editForm.get('watchlistId')!.touched)"> - <small class="form-text text-danger" - *ngIf="editForm.get('watchlistId')?.errors?.required" jhiTranslate="entity.validation.required"> - This field is required. - </small> - </div> - </div> + <div class="form-group"> + <label class="form-control-label" jhiTranslate="gitsearchApp.watchListEntry.watchlistId" for="field_watchlistId" + >Watchlist Id</label + > + <select class="form-control" id="field_watchlistId" name="watchlistId" formControlName="watchlistId"> + <option *ngIf="!editForm.get('watchlistId')!.value" [ngValue]="null" selected></option> + <option [ngValue]="userWatchListOption.id" *ngFor="let userWatchListOption of userwatchlists; trackBy: trackById"> + {{ userWatchListOption.id }} + </option> + </select> + </div> + <div *ngIf="editForm.get('watchlistId')!.invalid && (editForm.get('watchlistId')!.dirty || editForm.get('watchlistId')!.touched)"> + <small + class="form-text text-danger" + *ngIf="editForm.get('watchlistId')?.errors?.required" + jhiTranslate="entity.validation.required" + > + This field is required. + </small> + </div> + </div> - <div> - <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> - <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> - </button> + <div> + <button type="button" id="cancel-save" class="btn btn-secondary" (click)="previousState()"> + <fa-icon icon="ban"></fa-icon> <span jhiTranslate="entity.action.cancel">Cancel</span> + </button> - <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> - <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> - </button> - </div> - </form> - </div> + <button type="submit" id="save-entity" [disabled]="editForm.invalid || isSaving" class="btn btn-primary"> + <fa-icon icon="save"></fa-icon> <span jhiTranslate="entity.action.save">Save</span> + </button> + </div> + </form> + </div> </div> diff --git a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry.component.ts b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry.component.ts index 120fb622846db2e3fec3850b4beb856501e67001..0bba35ae7d7c8c3aedf9e37961de8541d96340c2 100644 --- a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry.component.ts +++ b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry.component.ts @@ -52,10 +52,10 @@ export class WatchListEntryComponent implements OnInit, OnDestroy { this.watchListEntryService .search({ query: this.currentSearch, -// TODO -// page: this.page, -// size: this.itemsPerPage, -// sort: this.sort(), + // TODO + // page: this.page, + // size: this.itemsPerPage, + // sort: this.sort(), }) .subscribe((res: HttpResponse<IWatchListEntry[]>) => this.paginateWatchListEntries(res.body, res.headers)); return; diff --git a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry.service.ts b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry.service.ts index 202a4926aae752bfa5faaf7ea4f4f717592e206d..bba77969bdcffa8a344f12cae394f6a8d591d547 100644 --- a/src/main/webapp/app/entities/watch-list-entry/watch-list-entry.service.ts +++ b/src/main/webapp/app/entities/watch-list-entry/watch-list-entry.service.ts @@ -3,7 +3,7 @@ import { HttpClient, HttpResponse } from '@angular/common/http'; import { Observable } from 'rxjs'; import { ApplicationConfigService } from 'app/core/config/application-config.service'; -import { createRequestOption, } from 'app/core/request/request-util'; +import { createRequestOption } from 'app/core/request/request-util'; import { Search } from 'app/core/request/request.model'; import { IWatchListEntry } from 'app/shared/model/watch-list-entry.model'; diff --git a/src/main/webapp/app/exercise/bookmarkInfo/bookmarkInfo.component.html b/src/main/webapp/app/exercise/bookmarkInfo/bookmarkInfo.component.html index fe23333054fc5e78dba3659d28f575b97778d1fd..3309134759c28351efa26f038fc20d940314dca9 100644 --- a/src/main/webapp/app/exercise/bookmarkInfo/bookmarkInfo.component.html +++ b/src/main/webapp/app/exercise/bookmarkInfo/bookmarkInfo.component.html @@ -1,11 +1,12 @@ <div *ngIf="getMyWatchLists() && getCurrentWatchList()" ngbDropdown> -<span jhiTranslate="gitsearchApp.userWatchList.currentList">Selected Bookmarkliste</span> <A [routerLink]="['/bookmarks']" style="font-weight: bold; cursor: pointer;">{{getCurrentWatchList()?getCurrentWatchList()!.userWatchList.name:'undefined'}}</A> -<!-- + <span jhiTranslate="gitsearchApp.userWatchList.currentList">Selected Bookmarkliste</span> + <A [routerLink]="['/bookmarks']" style="font-weight: bold; cursor: pointer">{{ + getCurrentWatchList() ? getCurrentWatchList()!.userWatchList.name : 'undefined' + }}</A> + <!-- <button class="btn btn-outline-primary mr-2" id="dropdownManual" ngbDropdownToggle ngbDropdownAnchor>{{'gitsearchApp.userWatchList.selectedList'|translate}}<br/>{{getCurrentWatchList()?getCurrentWatchList()!.userWatchList.name:'undefined'}}</button> <div ngbDropdownMenu aria-labelledby="dropdownManual" > <button ngbDropdownItem *ngFor="let watchList of getMyWatchLists()" (click)="setCurrentWatchList(watchList.name)">{{watchList.name}}</button> </div> --> </div> - - diff --git a/src/main/webapp/app/exercise/exercise-card/exercise-card.component.html b/src/main/webapp/app/exercise/exercise-card/exercise-card.component.html index 019bd8ff95296a3375e6a461946f1d8de3f5feb7..7be3107986e08ba1c84e12acb641efc651ee7e2e 100644 --- a/src/main/webapp/app/exercise/exercise-card/exercise-card.component.html +++ b/src/main/webapp/app/exercise/exercise-card/exercise-card.component.html @@ -1,47 +1,71 @@ -<div *ngIf="exercise" style="height: 100%;"> - <div class="card"> - <div class="card-body" style="display: flex; flex-direction: column;"> - <img class="card-img-top" src="{{exercise.imageURL}}" (error)="correctImageURL($event)" alt="exercise image" - style="width: auto; max-width: 100%; max-height: 70px; margin-left: auto; margin-right: auto; margin-bottom: 20px; margin-top: 5px; box-shadow: 3px;"> - <h5 class="card-title">{{exercise.title}}</h5> - <p class="card-text" style="text-align: left;">{{exercise.description}}</p> +<div *ngIf="exercise" style="height: 100%"> + <div class="card"> + <div class="card-body" style="display: flex; flex-direction: column"> + <img + class="card-img-top" + src="{{ exercise.imageURL }}" + (error)="correctImageURL($event)" + alt="exercise image" + style=" + width: auto; + max-width: 100%; + max-height: 70px; + margin-left: auto; + margin-right: auto; + margin-bottom: 20px; + margin-top: 5px; + box-shadow: 3px; + " + /> + <h5 class="card-title">{{ exercise.title }}</h5> + <p class="card-text" style="text-align: left">{{ exercise.description }}</p> - <div style="margin-top: auto; width: 100%; padding-left: 30px; padding-right: 30px;"> - <!-- card rating--> - <div style="margin-bottom: 20px;"> - <div style="float: left;"> - <p class="card-text" jhiTranslate="exercise.details.rating"></p> - </div> - <div class="star-container"> - <span class="star" - *ngFor="let starNumber of [1,2,3,4,5]" - [ngClass]="{'star-marked': exercise.rating >= starNumber, - 'star-unmarked': exercise.rating < starNumber}"> - </span> - </div> - </div> <!-- card rating end--> - - <!-- card bookmark--> - <div style="float: left; width: 100%;"> - <div style="float: left;"> - <p class="card-text" jhiTranslate="exercise.details.bookmark"></p> - </div> - <div class="form-check" style="float: right; padding-right: 10px;" > - <input class="form-check-input" type="checkbox" [checked]="isOnCurrentWatchlist(exercise)" id="card-defaultCheck1" (change)="handleForCurrentWatchlist(exercise)"> - <label class="form-check-label" for="card-defaultCheck1"></label> - </div> - </div> <!-- card bookmark end--> + <div style="margin-top: auto; width: 100%; padding-left: 30px; padding-right: 30px"> + <!-- card rating--> + <div style="margin-bottom: 20px"> + <div style="float: left"> + <p class="card-text" jhiTranslate="exercise.details.rating"></p> + </div> + <div class="star-container"> + <span + class="star" + *ngFor="let starNumber of [1, 2, 3, 4, 5]" + [ngClass]="{ 'star-marked': exercise.rating >= starNumber, 'star-unmarked': exercise.rating < starNumber }" + > + </span> + </div> + </div> + <!-- card rating end--> - <!-- Button to Open the Modal --> - <button type="button" - class="btn btn-outline-secondary" - style="margin-top: 20px;" - data-toggle="modal" - data-target="#myModal" - (click)="selectExercise()" - jhiTranslate="exercise.more"> - </button> - </div> + <!-- card bookmark--> + <div style="float: left; width: 100%"> + <div style="float: left"> + <p class="card-text" jhiTranslate="exercise.details.bookmark"></p> + </div> + <div class="form-check" style="float: right; padding-right: 10px"> + <input + class="form-check-input" + type="checkbox" + [checked]="isOnCurrentWatchlist(exercise)" + id="card-defaultCheck1" + (change)="handleForCurrentWatchlist(exercise)" + /> + <label class="form-check-label" for="card-defaultCheck1"></label> + </div> </div> + <!-- card bookmark end--> + + <!-- Button to Open the Modal --> + <button + type="button" + class="btn btn-outline-secondary" + style="margin-top: 20px" + data-toggle="modal" + data-target="#myModal" + (click)="selectExercise()" + jhiTranslate="exercise.more" + ></button> + </div> </div> + </div> </div> diff --git a/src/main/webapp/app/exercise/exercise-details/exercise-details.component.html b/src/main/webapp/app/exercise/exercise-details/exercise-details.component.html index ae06c29c5605e8a18b34e426f30bc8db59f9d2b1..3d752d774268e3d6272360a1e97facd0f75873b6 100644 --- a/src/main/webapp/app/exercise/exercise-details/exercise-details.component.html +++ b/src/main/webapp/app/exercise/exercise-details/exercise-details.component.html @@ -1,218 +1,255 @@ <div *ngIf="exercise"> - <div class="modal fade" id="myModal"> - <div class="modal-dialog modal-lg modal-dialog-centered"> - <div class="modal-content"> - <ng-template #helpComingSoon> {{ 'exercise.comingSoon' | translate}}</ng-template> - - <!-- Modal Header --> - <div class="modal-header"> - <img class="card-img-top col-3" src="{{exercise.imageURL}}" alt="exercise image" - (error)="correctImageURL($event)" style="height: auto; float: left;"> - <h4 class="modal-title">{{exercise.title}}</h4> - <button type="button" class="close" data-dismiss="modal">×</button> + <div class="modal fade" id="myModal"> + <div class="modal-dialog modal-lg modal-dialog-centered"> + <div class="modal-content"> + <ng-template #helpComingSoon> {{ 'exercise.comingSoon' | translate }}</ng-template> + + <!-- Modal Header --> + <div class="modal-header"> + <img + class="card-img-top col-3" + src="{{ exercise.imageURL }}" + alt="exercise image" + (error)="correctImageURL($event)" + style="height: auto; float: left" + /> + <h4 class="modal-title">{{ exercise.title }}</h4> + <button type="button" class="close" data-dismiss="modal">×</button> + </div> + + <!-- Modal body --> + <div class="modal-body"> + <div class="container-fluid"> + <div *ngIf="exercise.description" class="row"> + <p style="padding-bottom: 15px; text-align: justify">{{ exercise.description }}</p> + </div> + <div class="row"> + <div class="col-6 col-md-4" style="margin-bottom: 15px"> + <p style="text-align: left"><strong jhiTranslate="exercise.details.details"></strong></p> + <hr /> + + <!-- modal rating--> + <div *ngIf="exercise.rating" style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px"> + <div style="float: left"> + <p class="card-text" jhiTranslate="exercise.details.rating"></p> + </div> + <div class="star-container"> + <span + class="star" + *ngFor="let starNumber of [1, 2, 3, 4, 5]" + [ngClass]="{ 'star-marked': exercise.rating >= starNumber, 'star-unmarked': exercise.rating < starNumber }" + > + </span> + </div> + </div> + <!-- modal rating end--> + + <div *ngIf="!exercise.userHasLiked" style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px"> + <div style="float: left"> + <div> + <button + [ngbTooltip]="helpForLike" + style="padding: 0%; font-size: 1.2" + *ngIf="isAuthenticated()" + type="button" + class="btn" + (click)="likeAction()" + [disabled]="!isAuthenticated()" + > + <fa-icon [icon]="['far', 'heart']"></fa-icon> + </button> + <span [ngbTooltip]="helpForLikeNotLoggedIn"> + <button + style="padding: 0%; font-size: 1.2" + *ngIf="!isAuthenticated()" + type="button" + class="btn" + (click)="likeAction()" + [disabled]="true" + > + <fa-icon [icon]="['far', 'heart']"></fa-icon> + </button> + </span> + </div> + </div> + <div class="star-container"> + <span> + {{ exercise.numberOfLikes }} + </span> + </div> + + <ng-template #helpForLike> {{ 'exercise.details.like' | translate }}</ng-template> + <ng-template #helpForLikeNotLoggedIn> {{ 'exercise.details.likeLogin' | translate }} </ng-template> + </div> + <!-- modal views end--> + + <div *ngIf="exercise.userHasLiked" style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px"> + <div style="float: left"> + <div> + <button + [ngbTooltip]="helpForUnLike" + style="padding: 0%; font-size: 1.2" + *ngIf="exercise.userHasLiked" + type="button" + class="btn" + (click)="unlikeAction()" + [disabled]="!isAuthenticated()" + > + <fa-icon class="rediconcolor" icon="heart"></fa-icon> + </button> + </div> + </div> + <div class="star-container"> + <span> + {{ exercise.numberOfLikes }} + </span> + </div> + <ng-template #helpForUnLike> {{ 'exercise.details.unlike' | translate }} </ng-template> </div> - <!-- Modal body --> - <div class="modal-body"> - <div class="container-fluid"> - <div *ngIf="exercise.description" class="row"> - <p style="padding-bottom: 15px; text-align: justify;">{{exercise.description}}</p> - </div> - <div class="row"> - <div class="col-6 col-md-4" style="margin-bottom: 15px;"> - <p style="text-align: left;"><strong jhiTranslate="exercise.details.details"></strong> - </p> - <hr> - - <!-- modal rating--> - <div *ngIf="exercise.rating" - style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px;"> - <div style="float: left;"> - <p class="card-text" jhiTranslate="exercise.details.rating"></p> - </div> - <div class="star-container"> - <span class="star" *ngFor="let starNumber of [1,2,3,4,5]" [ngClass]="{'star-marked': exercise.rating >= starNumber, - 'star-unmarked': exercise.rating < starNumber}"> - </span> - </div> - </div> <!-- modal rating end--> - - - - <div *ngIf="!exercise.userHasLiked" - style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px;"> - <div style="float: left;"> - <div> - <button [ngbTooltip]="helpForLike" style="padding: 0%; font-size: 1.2;" - *ngIf="isAuthenticated()" type="button" class="btn" - (click)="likeAction()" [disabled]="!isAuthenticated()"> - <fa-icon [icon]="['far', 'heart']"></fa-icon> - </button> - <span [ngbTooltip]="helpForLikeNotLoggedIn"> - <button style="padding: 0%; font-size: 1.2;" *ngIf="!isAuthenticated()" - type="button" class="btn" (click)="likeAction()" [disabled]="true"> - <fa-icon [icon]="['far', 'heart']"></fa-icon> - </button> - </span> - </div> - - </div> - <div class="star-container"> - <span> - {{exercise.numberOfLikes}} - </span> - </div> - - <ng-template #helpForLike> {{ 'exercise.details.like' | translate}}</ng-template> - <ng-template #helpForLikeNotLoggedIn> {{ 'exercise.details.likeLogin' | translate}} - </ng-template> - </div> <!-- modal views end--> - - <div *ngIf="exercise.userHasLiked" - style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px;"> - <div style="float: left;"> - <div> - <button [ngbTooltip]="helpForUnLike" style="padding: 0%; font-size: 1.2;" - *ngIf="exercise.userHasLiked" type="button" class="btn" - (click)="unlikeAction()" [disabled]="!isAuthenticated()"> - <fa-icon class="rediconcolor" icon='heart'></fa-icon> - </button> - </div> - - </div> - <div class="star-container"> - <span> - {{exercise.numberOfLikes}} - </span> - </div> - <ng-template #helpForUnLike> {{ 'exercise.details.unlike' | translate}} - </ng-template> - - </div> - - <div *ngIf="exercise.views" - style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px;"> - <div style="float: left;"> - <div> - <fa-icon icon="eye"></fa-icon> - </div> - <!-- <div class="onhoverIconDisplay"><p class="card-text" jhiTranslate="exercise.details.views"></p></div> --> - - </div> - <div class="star-container"> - <span> - {{exercise.views}} - </span> - </div> - </div> <!-- modal views end--> - - <div *ngIf="exercise.downloads >= 0" - style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px;"> - <div style="float: left;"> - <fa-icon icon="download"></fa-icon> - </div> - <div class="star-container"> - <span> - {{exercise.downloads}} - </span> - </div> - </div> <!-- modal views end--> - - <div *ngIf="exercise.numberOfWatchlistEntries >= 0" - style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px;"> - <div style="float: left;"> - <fa-icon icon="star"></fa-icon> - </div> - <div class="star-container"> - <span> - {{exercise.numberOfWatchlistEntries}} - </span> - </div> - </div> - - <!-- modal bookmark--> - <div style="float: left; width: 100%; padding-top: 15px; margin-bottom: 25px;"> - <div style="float: left;"> - <p class="card-text" jhiTranslate="exercise.details.bookmark"></p> - </div> - <div class="form-check" style="float: right; padding-right: 10px;" - placement="right"> - <input class="form-check-input" type="checkbox" - [checked]="isOnCurrentWatchlist(exercise)" - (change)="handleForCurrentWatchlist(exercise)" value="" - id="modal-defaultCheck1"> - <label class="form-check-label" for="modal-defaultCheck1"></label> - </div> - </div> <!-- modal bookmark end--> - - <div *ngIf="exercise.originalResult.file.parentId" - style="float: left; width: 100%; padding-top: 15px; margin-bottom: 25px;"> - <ng-template #helpToParent data-container="body"> {{ 'exercise.help.toParent' | - translate}}</ng-template> - <fa-icon style="padding: 5px 0px 0px 5px;float:left;" [ngbTooltip]="helpToParent" - container="body" [icon]="treeIcon" - (click)="toParent(exercise.originalResult.file.parentId)"></fa-icon> - </div> - - <button *ngIf="hasChildren()" type="button" - class="btn btn-outline-secondary" - (click)="searchChildren(exercise.originalResult.exerciseId)" data-dismiss="modal" - style="display: block; margin-bottom: 5px;" - jhiTranslate="exercise.details.allExercises"> - </button> - <button type="button" class="btn btn-outline-secondary" style="display: block;" - (click)="openLink(exercise.gitlabURL)" - jhiTranslate="exercise.details.git"> - </button> - - <button type="button" - class="btn btn-outline-secondary" - style="margin-top: 20px;" - data-toggle="modal" - data-target="#mdModal" - (click)="selectREADME()" - >README - </button> - - </div> - - <jhi-exercise-metadata class="col-12 col-md-8" [exercise]="exercise"> - </jhi-exercise-metadata> - - <div class="col-6 col-md-4"></div> - <div class="col-12 col-md-8"> - <p style="text-align: left; margin-top: 20px;"><strong - jhiTranslate="exercise.export.export"></strong> - </p> - <hr> - <a *ngFor="let action of exercise.originalResult.supportedActions" - class="btn btn-outline-secondary" role="button" aria-pressed="true" - style="float: left; margin-right: 5px; margin-top: 5px;" - (click)="startAction(action, exercise)">{{action.commandName}}</a> - <div [ngbTooltip]="helpComingSoon" placement="bottom"> - <button *ngIf="hasChildren()" type="button" - class="btn btn-outline-secondary" - style="float: left; margin-right: 5px; margin-top: 5px;" - jhiTranslate="exercise.export.latex" - title="{{ 'exercise.comingSoon' | translate}}" disabled> - </button> - </div> - - <a class="btn btn-outline-secondary" role="button" aria-pressed="true" - style="float: left; margin-right: 5px; margin-top: 5px;" (click)="download()" - jhiTranslate="exercise.export.download"></a> - </div> - </div> + <div *ngIf="exercise.views" style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px"> + <div style="float: left"> + <div> + <fa-icon icon="eye"></fa-icon> </div> + <!-- <div class="onhoverIconDisplay"><p class="card-text" jhiTranslate="exercise.details.views"></p></div> --> + </div> + <div class="star-container"> + <span> + {{ exercise.views }} + </span> + </div> + </div> + <!-- modal views end--> + + <div *ngIf="exercise.downloads >= 0" style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px"> + <div style="float: left"> + <fa-icon icon="download"></fa-icon> + </div> + <div class="star-container"> + <span> + {{ exercise.downloads }} + </span> + </div> + </div> + <!-- modal views end--> + + <div *ngIf="exercise.numberOfWatchlistEntries >= 0" style="float: left; width: 100%; margin-bottom: 5px; padding-top: 15px"> + <div style="float: left"> + <fa-icon icon="star"></fa-icon> + </div> + <div class="star-container"> + <span> + {{ exercise.numberOfWatchlistEntries }} + </span> + </div> + </div> + + <!-- modal bookmark--> + <div style="float: left; width: 100%; padding-top: 15px; margin-bottom: 25px"> + <div style="float: left"> + <p class="card-text" jhiTranslate="exercise.details.bookmark"></p> + </div> + <div class="form-check" style="float: right; padding-right: 10px" placement="right"> + <input + class="form-check-input" + type="checkbox" + [checked]="isOnCurrentWatchlist(exercise)" + (change)="handleForCurrentWatchlist(exercise)" + value="" + id="modal-defaultCheck1" + /> + <label class="form-check-label" for="modal-defaultCheck1"></label> + </div> + </div> + <!-- modal bookmark end--> + + <div *ngIf="exercise.originalResult.file.parentId" style="float: left; width: 100%; padding-top: 15px; margin-bottom: 25px"> + <ng-template #helpToParent data-container="body"> {{ 'exercise.help.toParent' | translate }}</ng-template> + <fa-icon + style="padding: 5px 0px 0px 5px; float: left" + [ngbTooltip]="helpToParent" + container="body" + [icon]="treeIcon" + (click)="toParent(exercise.originalResult.file.parentId)" + ></fa-icon> </div> - <!-- Modal footer --> - <div class="modal-footer"> - <button type="button" class="btn btn-outline-secondary" data-dismiss="modal" - jhiTranslate="exercise.close"></button> + <button + *ngIf="hasChildren()" + type="button" + class="btn btn-outline-secondary" + (click)="searchChildren(exercise.originalResult.exerciseId)" + data-dismiss="modal" + style="display: block; margin-bottom: 5px" + jhiTranslate="exercise.details.allExercises" + ></button> + <button + type="button" + class="btn btn-outline-secondary" + style="display: block" + (click)="openLink(exercise.gitlabURL)" + jhiTranslate="exercise.details.git" + ></button> + + <button + type="button" + class="btn btn-outline-secondary" + style="margin-top: 20px" + data-toggle="modal" + data-target="#mdModal" + (click)="selectREADME()" + > + README + </button> + </div> + + <jhi-exercise-metadata class="col-12 col-md-8" [exercise]="exercise"> </jhi-exercise-metadata> + + <div class="col-6 col-md-4"></div> + <div class="col-12 col-md-8"> + <p style="text-align: left; margin-top: 20px"><strong jhiTranslate="exercise.export.export"></strong></p> + <hr /> + <a + *ngFor="let action of exercise.originalResult.supportedActions" + class="btn btn-outline-secondary" + role="button" + aria-pressed="true" + style="float: left; margin-right: 5px; margin-top: 5px" + (click)="startAction(action, exercise)" + >{{ action.commandName }}</a + > + <div [ngbTooltip]="helpComingSoon" placement="bottom"> + <button + *ngIf="hasChildren()" + type="button" + class="btn btn-outline-secondary" + style="float: left; margin-right: 5px; margin-top: 5px" + jhiTranslate="exercise.export.latex" + title="{{ 'exercise.comingSoon' | translate }}" + disabled + ></button> </div> + + <a + class="btn btn-outline-secondary" + role="button" + aria-pressed="true" + style="float: left; margin-right: 5px; margin-top: 5px" + (click)="download()" + jhiTranslate="exercise.export.download" + ></a> + </div> </div> + </div> + </div> + + <!-- Modal footer --> + <div class="modal-footer"> + <button type="button" class="btn btn-outline-secondary" data-dismiss="modal" jhiTranslate="exercise.close"></button> </div> + </div> </div> - <jhi-markdown-viewer [exercise]="exercise"></jhi-markdown-viewer> + </div> + <jhi-markdown-viewer [exercise]="exercise"></jhi-markdown-viewer> </div> diff --git a/src/main/webapp/app/exercise/exercise-details/exercise-details.component.ts b/src/main/webapp/app/exercise/exercise-details/exercise-details.component.ts index f07d993e8550b6414049313f63b5a8a65b51187c..f8a29a1e718e329de864504836345e0e95f937b3 100644 --- a/src/main/webapp/app/exercise/exercise-details/exercise-details.component.ts +++ b/src/main/webapp/app/exercise/exercise-details/exercise-details.component.ts @@ -23,7 +23,7 @@ import { Subscription } from 'rxjs'; export class ExerciseDetailsComponent implements OnInit, OnDestroy { @Input() exercise: Exercise | undefined; @Output() exerciseChangedEvent = new EventEmitter<Exercise>(); - + markDownExercise: Exercise | undefined; account: Account | null = null; @@ -88,7 +88,7 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy { exportProject(exerciseId: string) { return this.searchService.exportProject(exerciseId).subscribe( (response: HttpResponse<Blob>) => { - this.jhiAlertService.addAlert({type:'success', translationKey: 'artemisApp.programmingExercise.export.successMessage'}) + this.jhiAlertService.addAlert({ type: 'success', translationKey: 'artemisApp.programmingExercise.export.successMessage' }); // success('artemisApp.programmingExercise.export.successMessage'); if (response.body) { const zipFile = new Blob([response.body], { type: 'application/zip' }); diff --git a/src/main/webapp/app/exercise/exercise-details/exercise-metadata/exercise-metadata-item/exercise-metadata-item.component.html b/src/main/webapp/app/exercise/exercise-details/exercise-metadata/exercise-metadata-item/exercise-metadata-item.component.html index f62d93fdffe797773696acdae9ba0ecd65c73985..a011a60be17191dac2eba65825c3e9e34f0d8213 100644 --- a/src/main/webapp/app/exercise/exercise-details/exercise-metadata/exercise-metadata-item/exercise-metadata-item.component.html +++ b/src/main/webapp/app/exercise/exercise-details/exercise-metadata/exercise-metadata-item/exercise-metadata-item.component.html @@ -1,26 +1,18 @@ -<div *ngIf="value && value.length > 0" - class="row exercise-metadata-item"> - <ng-container *ngIf="isArray(value)"> - <div *ngIf="value.length === 1" - class="col-5 exercise-metadata-item-description"> - {{description + '.singular' | translate }} - </div> - <div *ngIf="value.length > 1" - class="col-5 exercise-metadata-item-description"> - {{description + '.plural' | translate }} - </div> - <div *ngIf="treatAsHTML" - class="col-7 exercise-metadata-item-value" - [innerHTML]="arrayToString(value)"> - </div> - <div *ngIf="!treatAsHTML" - class="col-7 exercise-metadata-item-value"> - {{arrayToString(value)}} - </div> - </ng-container> - <ng-container *ngIf="!isArray(value)"> - <div jhiTranslate="{{description}}" - class="col-5 exercise-metadata-item-description"></div> - <div class="col-7 exercise-metadata-item-value">{{value}}</div> - </ng-container> +<div *ngIf="value && value.length > 0" class="row exercise-metadata-item"> + <ng-container *ngIf="isArray(value)"> + <div *ngIf="value.length === 1" class="col-5 exercise-metadata-item-description"> + {{ description + '.singular' | translate }} + </div> + <div *ngIf="value.length > 1" class="col-5 exercise-metadata-item-description"> + {{ description + '.plural' | translate }} + </div> + <div *ngIf="treatAsHTML" class="col-7 exercise-metadata-item-value" [innerHTML]="arrayToString(value)"></div> + <div *ngIf="!treatAsHTML" class="col-7 exercise-metadata-item-value"> + {{ arrayToString(value) }} + </div> + </ng-container> + <ng-container *ngIf="!isArray(value)"> + <div jhiTranslate="{{ description }}" class="col-5 exercise-metadata-item-description"></div> + <div class="col-7 exercise-metadata-item-value">{{ value }}</div> + </ng-container> </div> diff --git a/src/main/webapp/app/exercise/exercise-details/exercise-metadata/exercise-metadata.component.html b/src/main/webapp/app/exercise/exercise-details/exercise-metadata/exercise-metadata.component.html index 68a342c1dd5b2818bfd91f64ba8c35d5e55cc5a2..7bfc4827280eee0b9275b4d0bac765935aab0f8e 100644 --- a/src/main/webapp/app/exercise/exercise-details/exercise-metadata/exercise-metadata.component.html +++ b/src/main/webapp/app/exercise/exercise-details/exercise-metadata/exercise-metadata.component.html @@ -1,179 +1,128 @@ <div *ngIf="exercise"> - <p style="text-align: left;"> - <strong jhiTranslate="exercise.metadata.metadata"></strong> - </p> - <hr> - - <ng-container *ngIf="exercise.creator"> - <jhi-exercise-metadata-item - *ngIf="isAuthenticated()" - [description]="'exercise.metadata.creator'" - [value]="exercise.creator.map(getPersonDetailsWithEmail)" - [treatAsHTML]="true"> - </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - *ngIf="!isAuthenticated()" - [description]="'exercise.metadata.creator'" - [value]="exercise.creator.map(getPersonDetails)" - [treatAsHTML]="true"> - </jhi-exercise-metadata-item> - </ng-container> - - <ng-container *ngIf="exercise.contributor"> - <jhi-exercise-metadata-item - *ngIf="isAuthenticated()" - [description]="'exercise.metadata.contributor'" - [value]="exercise.contributor.map(getPersonDetailsWithEmail)" - [treatAsHTML]="true"> - </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - *ngIf="!isAuthenticated()" - [description]="'exercise.metadata.contributor'" - [value]="exercise.contributor.map(getPersonDetails)" - [treatAsHTML]="true"> - </jhi-exercise-metadata-item> - </ng-container> - - <ng-container *ngIf="exercise.publisher"> - <jhi-exercise-metadata-item - *ngIf="isAuthenticated()" - [description]="'exercise.metadata.publisher'" - [value]="exercise.publisher.map(getPersonDetailsWithEmail)" - [treatAsHTML]="true"> - </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - *ngIf="!isAuthenticated()" - [description]="'exercise.metadata.publisher'" - [value]="exercise.publisher.map(getPersonDetails)" - [treatAsHTML]="true"> - </jhi-exercise-metadata-item> - </ng-container> + <p style="text-align: left"> + <strong jhiTranslate="exercise.metadata.metadata"></strong> + </p> + <hr /> + <ng-container *ngIf="exercise.creator"> <jhi-exercise-metadata-item - [description]="'exercise.metadata.keyword'" - [value]="exercise.keyword"> + *ngIf="isAuthenticated()" + [description]="'exercise.metadata.creator'" + [value]="exercise.creator.map(getPersonDetailsWithEmail)" + [treatAsHTML]="true" + > </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.format'" - [value]="exercise.format"> + *ngIf="!isAuthenticated()" + [description]="'exercise.metadata.creator'" + [value]="exercise.creator.map(getPersonDetails)" + [treatAsHTML]="true" + > </jhi-exercise-metadata-item> + </ng-container> + <ng-container *ngIf="exercise.contributor"> <jhi-exercise-metadata-item - [description]="'exercise.metadata.programmingLanguage'" - [value]="exercise.programmingLanguage"> + *ngIf="isAuthenticated()" + [description]="'exercise.metadata.contributor'" + [value]="exercise.contributor.map(getPersonDetailsWithEmail)" + [treatAsHTML]="true" + > </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.language'" - [value]="exercise.language"> + *ngIf="!isAuthenticated()" + [description]="'exercise.metadata.contributor'" + [value]="exercise.contributor.map(getPersonDetails)" + [treatAsHTML]="true" + > </jhi-exercise-metadata-item> + </ng-container> + <ng-container *ngIf="exercise.publisher"> <jhi-exercise-metadata-item - [description]="'exercise.metadata.requires'" - [value]="exercise.requires"> + *ngIf="isAuthenticated()" + [description]="'exercise.metadata.publisher'" + [value]="exercise.publisher.map(getPersonDetailsWithEmail)" + [treatAsHTML]="true" + > </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.license'" - [value]="exercise.license"> + *ngIf="!isAuthenticated()" + [description]="'exercise.metadata.publisher'" + [value]="exercise.publisher.map(getPersonDetails)" + [treatAsHTML]="true" + > </jhi-exercise-metadata-item> + </ng-container> - <jhi-exercise-metadata-item - *ngIf="exercise.difficulty" - [description]="'exercise.metadata.difficulty'" - [value]="'exercise.metadata.' + exercise.difficulty | translate"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.keyword'" [value]="exercise.keyword"> </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.timeRequired'" - [value]="exercise.timeRequired"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.format'" [value]="exercise.format"> </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.educationalLevel'" - [value]="exercise.educationalLevel"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.programmingLanguage'" [value]="exercise.programmingLanguage"> + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.learningResourceType'" - [value]="exercise.learningResourceType"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.language'" [value]="exercise.language"> </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - *ngIf="exercise.structure" - [description]="'exercise.metadata.structure'" - [value]="'exercise.metadata.' + exercise.structure | translate"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.requires'" [value]="exercise.requires"> </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - *ngIf="exercise.status" - [description]="'exercise.metadata.status'" - [value]="exercise.status"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.license'" [value]="exercise.license"> </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.lastUpdate'" - [value]="exercise.lastUpdate.toLocaleString()"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item + *ngIf="exercise.difficulty" + [description]="'exercise.metadata.difficulty'" + [value]="'exercise.metadata.' + exercise.difficulty | translate" + > + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.version'" - [value]="exercise.version"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.timeRequired'" [value]="exercise.timeRequired"> + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.assesses'" - [value]="exercise.assesses"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.educationalLevel'" [value]="exercise.educationalLevel"> + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.audience'" - [value]="exercise.audience"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.learningResourceType'" [value]="exercise.learningResourceType"> + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.educationalAlignment'" - [value]="exercise.educationalAlignment"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item + *ngIf="exercise.structure" + [description]="'exercise.metadata.structure'" + [value]="'exercise.metadata.' + exercise.structure | translate" + > + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.educationalFramework'" - [value]="exercise.educationalFramework"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item *ngIf="exercise.status" [description]="'exercise.metadata.status'" [value]="exercise.status"> + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.educationalUse'" - [value]="exercise.educationalUse"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.lastUpdate'" [value]="exercise.lastUpdate.toLocaleString()"> + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.identifier'" - [value]="exercise.identifier"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.version'" [value]="exercise.version"> </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.interactivityType'" - [value]="exercise.interactivityType"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.assesses'" [value]="exercise.assesses"> </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.isBasedOn'" - [value]="exercise.isBasedOn"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.audience'" [value]="exercise.audience"> </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.subject'" - [value]="exercise.subject"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.educationalAlignment'" [value]="exercise.educationalAlignment"> + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.teaches'" - [value]="exercise.teaches"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.educationalFramework'" [value]="exercise.educationalFramework"> + </jhi-exercise-metadata-item> - <jhi-exercise-metadata-item - [description]="'exercise.metadata.typicalAgeRange'" - [value]="exercise.typicalAgeRange"> - </jhi-exercise-metadata-item> + <jhi-exercise-metadata-item [description]="'exercise.metadata.educationalUse'" [value]="exercise.educationalUse"> + </jhi-exercise-metadata-item> + + <jhi-exercise-metadata-item [description]="'exercise.metadata.identifier'" [value]="exercise.identifier"> </jhi-exercise-metadata-item> + + <jhi-exercise-metadata-item [description]="'exercise.metadata.interactivityType'" [value]="exercise.interactivityType"> + </jhi-exercise-metadata-item> + + <jhi-exercise-metadata-item [description]="'exercise.metadata.isBasedOn'" [value]="exercise.isBasedOn"> </jhi-exercise-metadata-item> + + <jhi-exercise-metadata-item [description]="'exercise.metadata.subject'" [value]="exercise.subject"> </jhi-exercise-metadata-item> + + <jhi-exercise-metadata-item [description]="'exercise.metadata.teaches'" [value]="exercise.teaches"> </jhi-exercise-metadata-item> + + <jhi-exercise-metadata-item [description]="'exercise.metadata.typicalAgeRange'" [value]="exercise.typicalAgeRange"> + </jhi-exercise-metadata-item> </div> diff --git a/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.html b/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.html index 39a080fe2c57f8d546f0c83148493ce0774a9f3d..22919c75d91fe2ea39614a7c7d52088a2af71d94 100644 --- a/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.html +++ b/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.html @@ -1,25 +1,28 @@ <div *ngIf="exercise"> - <div class="modal fade" id="mdModal"> - <div class="modal-dialog modal-xxl modal-dialog-centered"> - <div class="modal-content"> - <!-- Modal Header --> - <div class="modal-header">{{filename}} (<a href="{{exercise.originalResult.project.url + '/-/blob/master/'+ filename}}" jhiTranslate="exercise.details.git" target="gitlab">show in GitLab</a>) - <button type="button" class="close" data-dismiss="modal">×</button> - </div> - - <!-- Modal body --> - <div class="modal-body"> - <markdown katex emoji ngPreserveWhitespaces [katexOptions]="katexOptions" [data]="getContentAndSetBaseURL()" > - </markdown> - </div> + <div class="modal fade" id="mdModal"> + <div class="modal-dialog modal-xxl modal-dialog-centered"> + <div class="modal-content"> + <!-- Modal Header --> + <div class="modal-header"> + {{ filename }} (<a + href="{{ exercise.originalResult.project.url + '/-/blob/master/' + filename }}" + jhiTranslate="exercise.details.git" + target="gitlab" + >show in GitLab</a + >) + <button type="button" class="close" data-dismiss="modal">×</button> + </div> - <!-- Modal footer --> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-dismiss="modal" - jhiTranslate="exercise.close"></button> - </div> + <!-- Modal body --> + <div class="modal-body"> + <markdown katex emoji ngPreserveWhitespaces [katexOptions]="katexOptions" [data]="getContentAndSetBaseURL()"> </markdown> + </div> - </div> + <!-- Modal footer --> + <div class="modal-footer"> + <button type="button" class="btn btn-secondary" data-dismiss="modal" jhiTranslate="exercise.close"></button> </div> + </div> </div> + </div> </div> diff --git a/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.scss b/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.scss index c9c9fdb22c347223623407e9c0d3f701eb5855c5..53efd8a57d8ee91cfb746c30c2eb15470010f7f9 100644 --- a/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.scss +++ b/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.scss @@ -1,6 +1,5 @@ @media (min-width: 992px) { - .modal-xxl - { + .modal-xxl { max-width: 1200px; } } diff --git a/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.ts b/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.ts index e86d0d34547a312994a5023d339e7580b88f499e..cbb7ea5ec64afed21351b88eaf00c1033cc9cd7e 100644 --- a/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.ts +++ b/src/main/webapp/app/exercise/markDownViewer/markDownViewer.component.ts @@ -15,15 +15,18 @@ declare let katex: any; // Magic }) export class MarkDownViewerComponent implements OnInit { @Input() // exercise: Exercise | undefined; - get exercise(): Exercise | undefined { return this.myExercise; } - set exercise(exercise: Exercise | undefined) { this.myExercise = exercise; - this.loadVisible(); - } - - /* + get exercise(): Exercise | undefined { + return this.myExercise; + } + set exercise(exercise: Exercise | undefined) { + this.myExercise = exercise; + this.loadVisible(); + } + + /* @Input() readMeVisibleEvent: Subject<any>; - */ + */ private myExercise: Exercise | undefined; public filename: string; public content: string; @@ -45,7 +48,7 @@ export class MarkDownViewerComponent implements OnInit { this.markdownService.renderKatex = (html: string, options?: KatexOptions) => this.renderKatex(html, options); // this.readMeVisibleEvent.subscribe(e => this.loadVisible()) } - + /** helper function for special latex rendering with katex */ private renderKatex(html: string, options?: KatexOptions): string { if (typeof katex === 'undefined' || typeof katex.renderToString === 'undefined') { diff --git a/src/main/webapp/app/exercise/service/exercise.service.ts b/src/main/webapp/app/exercise/service/exercise.service.ts index e47e93ed9efb04db57235ee413c0dcc147083114..52afc9e7c675ee4ec4938b3a57d38533eb4e3a73 100644 --- a/src/main/webapp/app/exercise/service/exercise.service.ts +++ b/src/main/webapp/app/exercise/service/exercise.service.ts @@ -89,7 +89,11 @@ export class ExerciseService { * Submits an ArtemisExerciseInfo object to server and triggers its import * @param exerciseInfo to submit and import */ - public submitExerciseInfoForImport(exerciseInfo: ArtemisExerciseInfo, exerciseToken: string, gitlabGroupId: number): Observable<ArtemisExerciseInfo> { + public submitExerciseInfoForImport( + exerciseInfo: ArtemisExerciseInfo, + exerciseToken: string, + gitlabGroupId: number + ): Observable<ArtemisExerciseInfo> { return this.http.post<ArtemisExerciseInfo>(`${this.exerciseUrl}import-exercise/${exerciseToken}/${gitlabGroupId}`, exerciseInfo); } } diff --git a/src/main/webapp/app/home/home.component.html b/src/main/webapp/app/home/home.component.html index 7a262629662d9ef04b270eaf52c19a4e808a79a4..b60126410d78a1fb20be70e911946cef1ec575d8 100644 --- a/src/main/webapp/app/home/home.component.html +++ b/src/main/webapp/app/home/home.component.html @@ -1,14 +1,15 @@ <div class="row"> - <div class="col-md-12"> - <jhi-pages-markdown-viewer class="home" [path]="pagesStartPath"></jhi-pages-markdown-viewer> + <div class="col-md-12"> + <jhi-pages-markdown-viewer class="home" [path]="pagesStartPath"></jhi-pages-markdown-viewer> - <div [ngSwitch]="account !== null"> - <div class="alert alert-success" *ngSwitchCase="true"> - <span id="home-logged-message" *ngIf="account" jhiTranslate="home.logged.message" - [translateValues]="{ username: account.login }">You are logged in as user "{{ account.login }}".</span> - </div> + <div [ngSwitch]="account !== null"> + <div class="alert alert-success" *ngSwitchCase="true"> + <span id="home-logged-message" *ngIf="account" jhiTranslate="home.logged.message" [translateValues]="{ username: account.login }" + >You are logged in as user "{{ account.login }}".</span + > + </div> + </div> - </div> - - <div><jhi-teaser-content ></jhi-teaser-content></div> + <div><jhi-teaser-content></jhi-teaser-content></div> + </div> </div> diff --git a/src/main/webapp/app/home/home.component.ts b/src/main/webapp/app/home/home.component.ts index ac8ecae13ef41983facbd0b009d335eda5fc4e62..07437ebc189cf033271978419bc0028907b624e5 100644 --- a/src/main/webapp/app/home/home.component.ts +++ b/src/main/webapp/app/home/home.component.ts @@ -13,7 +13,7 @@ import { Account } from 'app/core/auth/account.model'; }) export class HomeComponent implements OnInit, OnDestroy { account: Account | null = null; - pagesStartPath = "/start"; + pagesStartPath = '/start'; private readonly destroy$ = new Subject<void>(); diff --git a/src/main/webapp/app/home/home.module.ts b/src/main/webapp/app/home/home.module.ts index eef7851fbee782d59a41dc52fb5f18d0e90ec085..30de186e13f30754c223b0b7ab16df7e4ea30157 100644 --- a/src/main/webapp/app/home/home.module.ts +++ b/src/main/webapp/app/home/home.module.ts @@ -8,7 +8,6 @@ import { SharedModule } from 'app/shared/shared.module'; import { HOME_ROUTE } from './home.route'; import { HomeComponent } from './home.component'; - @NgModule({ imports: [SharedModule, RouterModule.forChild([HOME_ROUTE]), TagCloudModule, PagesModule], declarations: [HomeComponent, TeaserContentComponent], diff --git a/src/main/webapp/app/home/prism.scss b/src/main/webapp/app/home/prism.scss index cd17dbc8a68c555c8b3c168f142c23e07eab1698..c4a2416982f5c6c8802f05698e9b7efddb4af870 100644 --- a/src/main/webapp/app/home/prism.scss +++ b/src/main/webapp/app/home/prism.scss @@ -6,8 +6,8 @@ https://prismjs.com/download.html#themes=prism&languages=css */ * @author Lea Verou */ -::ng-deep code[class*="language-"], -::ng-deep pre[class*="language-"] { +::ng-deep code[class*='language-'], +::ng-deep pre[class*='language-'] { color: black; background: none; text-shadow: 0 1px white; @@ -30,41 +30,45 @@ https://prismjs.com/download.html#themes=prism&languages=css */ hyphens: none; } -::ng-deep pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, -::ng-deep code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { +::ng-deep pre[class*='language-']::-moz-selection, +pre[class*='language-'] ::-moz-selection, +::ng-deep code[class*='language-']::-moz-selection, +code[class*='language-'] ::-moz-selection { text-shadow: none; background: #b3d4fc; } -::ng-deep pre[class*="language-"]::selection, pre[class*="language-"] ::selection, -::ng-deep code[class*="language-"]::selection, code[class*="language-"] ::selection { +::ng-deep pre[class*='language-']::selection, +pre[class*='language-'] ::selection, +::ng-deep code[class*='language-']::selection, +code[class*='language-'] ::selection { text-shadow: none; background: #b3d4fc; } @media print { - ::ng-deep code[class*="language-"], - ::ng-deep pre[class*="language-"] { + ::ng-deep code[class*='language-'], + ::ng-deep pre[class*='language-'] { text-shadow: none; } } /* Code blocks */ -::ng-deep pre[class*="language-"] { +::ng-deep pre[class*='language-'] { padding: 1em; - margin: .5em 0; + margin: 0.5em 0; overflow: auto; } -::ng-deep :not(pre) > code[class*="language-"], -::ng-deep pre[class*="language-"] { +::ng-deep :not(pre) > code[class*='language-'], +::ng-deep pre[class*='language-'] { background: #f5f2f0; } /* Inline code */ -::ng-deep :not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; +::ng-deep :not(pre) > code[class*='language-'] { + padding: 0.1em; + border-radius: 0.3em; white-space: normal; } @@ -80,7 +84,7 @@ https://prismjs.com/download.html#themes=prism&languages=css */ } ::ng-deep .token.namespace { - opacity: .7; + opacity: 0.7; } ::ng-deep .token.property, @@ -109,7 +113,7 @@ https://prismjs.com/download.html#themes=prism&languages=css */ ::ng-deep .style .token.string { color: #9a6e3a; /* This background color was intended by the author of this theme. */ - background: hsla(0, 0%, 100%, .5); + background: hsla(0, 0%, 100%, 0.5); } ::ng-deep .token.atrule, @@ -120,7 +124,7 @@ https://prismjs.com/download.html#themes=prism&languages=css */ .token.function, .token.class-name { - color: #DD4A68; + color: #dd4a68; } .token.regex, @@ -140,4 +144,3 @@ https://prismjs.com/download.html#themes=prism&languages=css */ .token.entity { cursor: help; } - diff --git a/src/main/webapp/app/layouts/datapolicy/datapolicy.component.html b/src/main/webapp/app/layouts/datapolicy/datapolicy.component.html index 153ec3889d6df79dd5c264226a98192aab08d5b2..4cebf2fac1a494be6ef8c392d060d21a9e4f5650 100755 --- a/src/main/webapp/app/layouts/datapolicy/datapolicy.component.html +++ b/src/main/webapp/app/layouts/datapolicy/datapolicy.component.html @@ -1,162 +1,159 @@ <h3 jhitranslate="legal.privacy.title">Privacy Statement</h3> <div> - <p> - Das Institut der Informatik der Universität Insbruck - nimmt den Schutz von personenbezogenen Daten sehr ernst um die Privatssphäre der Nutzer von der Sharing Plattform bestmöglich - zu - schützen. Wir verarbeiten personenbezogene Daten, die der Nutzung unseres Dienstes erhoben werden, unter - Beachtung der geltenden datenschutzrechtlichen Bestimmungen, - insbesondere der <a href="https://eur-lex.europa.eu/legal-content/DE/ALL/?uri=CELEX%3A32016R0679" - target="_blank" rel="external noopener noreferrer">DSGVO</a> und dem - <a href="https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=bundesnormen&Gesetzesnummer=10001597" - target="_blank" rel="external noopener noreferrer">österreichischen Datenschutzgesetz</a>. - </p> - <p> - Nachfolgend informieren wir Sie über Art, Umfang und Zweck der Erhebung und Verwendung personenbezogener Daten. - Diese Informationen können jederzeit von unserer Webseite - abgerufen werden. - </p> - <p></p> - <ol type="a"> - <li> - <h4>Namen und die Kontaktdaten des Verantwortlichen:</h4> - Institut für Informatik, <br> - Universität Innsbruck<br> - Technikerstraße 21a, - A-6020 Innsbruck<br> - E-Mail: artemis-support-informatik _ @ _ uibk.ac.at - </li> + <p> + Das Institut der Informatik der Universität Insbruck nimmt den Schutz von personenbezogenen Daten sehr ernst um die Privatssphäre der + Nutzer von der Sharing Plattform bestmöglich zu schützen. Wir verarbeiten personenbezogene Daten, die der Nutzung unseres Dienstes + erhoben werden, unter Beachtung der geltenden datenschutzrechtlichen Bestimmungen, insbesondere der + <a href="https://eur-lex.europa.eu/legal-content/DE/ALL/?uri=CELEX%3A32016R0679" target="_blank" rel="external noopener noreferrer" + >DSGVO</a + > + und dem + <a + href="https://www.ris.bka.gv.at/GeltendeFassung.wxe?Abfrage=bundesnormen&Gesetzesnummer=10001597" + target="_blank" + rel="external noopener noreferrer" + >österreichischen Datenschutzgesetz</a + >. + </p> + <p> + Nachfolgend informieren wir Sie über Art, Umfang und Zweck der Erhebung und Verwendung personenbezogener Daten. Diese Informationen + können jederzeit von unserer Webseite abgerufen werden. + </p> + <p></p> + <ol type="a"> + <li> + <h4>Namen und die Kontaktdaten des Verantwortlichen:</h4> + Institut für Informatik, <br /> + Universität Innsbruck<br /> + Technikerstraße 21a, A-6020 Innsbruck<br /> + E-Mail: artemis-support-informatik _ @ _ uibk.ac.at + </li> + + <li> + <h4>Kontaktdaten des Datenschutzbeauftragten:</h4> + Firma x-tention<br /> + Römerstraße 80a, A-4600 Wels<br /> + Telefon: +43 7242 2155 65065<br /> + E-Mail: datenschutzbeauftragter _ @ _ uibk.ac.at<br /> + </li> + <li> + <h4>Zweck der Verarbeitung und Rechtsgrundlage</h4> + Die Anwendung Sharing Plattform dient der Unterstützung der Lehre durch die vereinfachte Verteilung von Lehrmaterialien an die am + <a href="https://codeability.uibk.ac.at/" target="_blank">CodeAbility Projekt</a> beteiligten Partner.<br /> + Die Verarbeitung, gründet sich in der Wahrnehmung einer Aufgabe, die im öffentlichen Interesse liegt, bzw. zur Erfüllung eines + Vertrages. Rechtsgrundlage dafür ist Art. 6 Abs. 1 lit a, e und f DSGVO iVm den §§ 3 und 76 Abs.3 Universitätsgeetz. Weiter kann sich + die Ãœbertragung aus dem Erfordernis gemeinsamer Studiengänge mit Partnern an anderen Standorten ergeben. + </li> + <li> + <h4>Erfasste personenbezogenen Daten</h4> + Im Rahmen der Nutzung von der Sharing Plattform werden folgende personenbezogene Daten erfasst: + <ul> <li> - <h4>Kontaktdaten des Datenschutzbeauftragten:</h4> - Firma x-tention<br> - Römerstraße 80a, A-4600 Wels<br> - Telefon: +43 7242 2155 65065<br> - E-Mail: datenschutzbeauftragter _ @ _ uibk.ac.at<br> + Im Rahmen des Logins bzw. der Registrierung: Vorname, Nachname, E-Mail-Adresse, Status (Student oder Lehrpersonal), und + eindeutiges Nutzerkennzeichen (einschliesslich zugeordneter Institution) </li> + <li>Im Rahmen der Nutzung, werden ebenfalls folgende Metriken gespeichert:</li> + <ul> + Welche Resourcen mit einem "gefällt mir" markiert wurden. + </ul> + <ul> + Welche Resourcen als "Lesezeichen" gespeichert wurden. + </ul> + <ul> + Welche Resourcen gesucht wurden. + </ul> <li> - <h4>Zweck der Verarbeitung und Rechtsgrundlage</h4> - Die Anwendung Sharing Plattform dient der Unterstützung der Lehre durch die vereinfachte Verteilung von Lehrmaterialien an die am - <a href="https://codeability.uibk.ac.at/" target="_blank">CodeAbility Projekt</a> beteiligten Partner.<br> - - Die Verarbeitung, gründet sich in der Wahrnehmung einer Aufgabe, - die im öffentlichen Interesse liegt, bzw. zur Erfüllung eines Vertrages. Rechtsgrundlage dafür ist Art. 6 - Abs. 1 lit a, e und f DSGVO iVm den §§ 3 und 76 Abs.3 Universitätsgeetz. - Weiter kann sich die Ãœbertragung aus dem Erfordernis gemeinsamer Studiengänge mit Partnern an anderen - Standorten ergeben. + Protokolldateien: + <ul> + <li>IP-Adresse des anfragenden Rechners</li> + <li>Datum und Uhrzeit des Zugriffs</li> + <li>Name, URL und übertragene Datenmenge der abgerufenen Datei</li> + <li>Zugriffsstatus (angeforderte Datei übertragen, nicht gefunden etc.)</li> + <li>Erkennungsdaten des verwendeten Browser- und Betriebssystems (sofern vom anfragenden Webbrowser übermittelt)</li> + <li> + Webseite, von der aus der Zugriff erfolgte (sofern vom anfragenden Webbrowser übermittelt) Die Verarbeitung der Daten in + dieser Logdatei kann wie folgt geschehen: + </li> + <li> + Die Logeinträge können kontinuierlich und automatisch ausgewertet werden, um Angriffe auf die Webserver erkennen und + entsprechend reagieren zu können. + </li> + <li>In Einzelfällen, d.h. bei gemeldeten Störungen, Fehlern und Sicherheitsvorfällen, kann eine manuelle Analyse erfolgen.</li> + </ul> </li> <li> - <h4>Erfasste personenbezogenen Daten</h4> - Im Rahmen der Nutzung von der Sharing Plattform werden folgende personenbezogene Daten erfasst: - <ul> - <li> - Im Rahmen des Logins bzw. der Registrierung: Vorname, Nachname, E-Mail-Adresse, Status (Student oder - Lehrpersonal), und eindeutiges Nutzerkennzeichen (einschliesslich zugeordneter Institution) - </li> - <li>Im Rahmen der Nutzung, werden ebenfalls folgende Metriken gespeichert: </li> - <ul>Welche Resourcen mit einem "gefällt mir" markiert wurden. </ul> - <ul>Welche Resourcen als "Lesezeichen" gespeichert wurden. </ul> - <ul>Welche Resourcen gesucht wurden.</ul> - <li>Protokolldateien: - <ul> - <li>IP-Adresse des anfragenden Rechners</li> - <li>Datum und Uhrzeit des Zugriffs</li> - <li>Name, URL und übertragene Datenmenge der abgerufenen Datei</li> - <li>Zugriffsstatus (angeforderte Datei übertragen, nicht gefunden etc.)</li> - <li>Erkennungsdaten des verwendeten Browser- und Betriebssystems (sofern vom anfragenden - Webbrowser übermittelt)</li> - <li>Webseite, von der aus der Zugriff erfolgte (sofern vom anfragenden Webbrowser übermittelt) - Die Verarbeitung der Daten in dieser Logdatei kann wie folgt geschehen:</li> - <li>Die Logeinträge können kontinuierlich und automatisch ausgewertet werden, um Angriffe auf - die Webserver erkennen und entsprechend reagieren zu können.</li> - <li>In Einzelfällen, d.h. bei gemeldeten Störungen, Fehlern und Sicherheitsvorfällen, kann eine - manuelle Analyse erfolgen.</li> - </ul> - </li> - <li>Logdateien: Für Fehleranalysen werden für eine begrenzte Zeit Ereignisse und zugehörige Daten in - Logfiles erfasst. Diese Daten können auch personenbezogene Daten enthalten.</li> - </ul> + Logdateien: Für Fehleranalysen werden für eine begrenzte Zeit Ereignisse und zugehörige Daten in Logfiles erfasst. Diese Daten + können auch personenbezogene Daten enthalten. </li> + </ul> + </li> + + <li> + <h4>Ãœbertragung von personenbezogenen Daten an ein Drittland</h4> + Eine Ãœbertragung an ein Drittland oder einen internationale Organisation ist nicht vorgesehen. + </li> + <li> + <h4>Dauer, für die die personenbezogenen Daten gespeichert werden</h4> + Nutzerdaten werden gelöscht sobald eine Löschung von dem Nutzer angefordert . + </li> + + <li> + <h4>Auskunftsrecht und Widerspruch</h4> + <p> + Ihnen stehen grundsätzlich die Rechte auf Auskunft, Berichtigung, Löschung, Einschränkung, Datenübertragbarkeit, Widerruf sowie + Widerspruch zu. Bei Fragen in diesem Zusammenhang stehen wir Ihnen gerne zur Verfügung. Wenn Sie der Meinung sind, dass die + Verarbeitung Ihrer personenbezogenen Daten gegen das Datenschutzrecht verstößt oder Ihre datenschutzrechtlichen Ansprüche sonst in + einer Weise verletzt worden sind, bitten wir Sie mit uns Kontakt aufzunehmen. So können wir Ihre Bedenken behandeln. Sie haben aber + auch das Recht sich an die zuständige Datenschutzbehörde zu wenden. + </p> + <h5>Näheres zum Recht auf Widerspruch</h5> + <p> + Sie haben gemäß Art. 21 Abs. 1 DSGVO das Recht, aus Gründen, die sich aus Ihrer besonderen Situation ergeben, jederzeit gegen die + Verarbeitung Sie betreffender personenbezogener Daten, die aufgrund von Art. 6 Abs. 1 Buchstaben e oder f DSGVO erfolgt, Widerspruch + einzulegen. Das Widerspruchsrecht kann daher geltend gemacht werden, wenn die Verarbeitung + </p> + <ul> <li> - <h4>Ãœbertragung von personenbezogenen Daten an ein Drittland</h4> - Eine Ãœbertragung an ein Drittland oder einen internationale Organisation ist nicht vorgesehen. + für die Wahrnehmung einer Aufgabe erforderlich ist, die im öffentlichen Interesse liegt oder in Ausübung öffentlicher Gewalt + erfolgt, die dem Verantwortlichen übertragen wurde oder </li> - <li> - <h4>Dauer, für die die personenbezogenen Daten gespeichert werden</h4> - Nutzerdaten werden gelöscht sobald eine Löschung von dem Nutzer angefordert . + zur Wahrung der berechtigten Interessen des Verantwortlichen oder eines Dritten erforderlich ist, sofern nicht Ihre Interessen + oder Grundrechte und Grundfreiheiten, die den Schutz personenbezogener Daten erfordern, überwiegen und </li> - <li> - <h4>Auskunftsrecht und Widerspruch</h4> - <p> - Ihnen stehen grundsätzlich die Rechte auf Auskunft, Berichtigung, Löschung, Einschränkung, - Datenübertragbarkeit, Widerruf sowie Widerspruch zu. - Bei Fragen in diesem Zusammenhang stehen wir Ihnen gerne zur Verfügung. Wenn Sie der Meinung sind, dass - die Verarbeitung Ihrer personenbezogenen Daten gegen das Datenschutzrecht verstößt oder Ihre - datenschutzrechtlichen Ansprüche sonst in einer Weise verletzt worden sind, bitten wir Sie mit uns - Kontakt aufzunehmen. So können wir Ihre Bedenken behandeln. - Sie haben aber auch das Recht sich an die zuständige Datenschutzbehörde zu wenden. - </p> - <h5>Näheres zum Recht auf Widerspruch</h5> - <p> - Sie haben gemäß Art. 21 Abs. 1 DSGVO das Recht, aus Gründen, die sich aus Ihrer besonderen Situation - ergeben, jederzeit - gegen die Verarbeitung Sie betreffender personenbezogener Daten, die aufgrund von Art. 6 Abs. 1 - Buchstaben e oder f DSGVO erfolgt, Widerspruch einzulegen. - Das Widerspruchsrecht kann daher geltend gemacht werden, wenn die Verarbeitung - </p> - <ul> - <li> - für die Wahrnehmung einer Aufgabe erforderlich ist, die im öffentlichen Interesse liegt oder in - Ausübung öffentlicher Gewalt erfolgt, die dem Verantwortlichen übertragen wurde oder - </li> - <li>zur Wahrung der berechtigten Interessen des Verantwortlichen oder eines Dritten erforderlich ist, - sofern nicht Ihre Interessen oder Grundrechte und Grundfreiheiten, die den Schutz personenbezogener - Daten erfordern, überwiegen und - </li> - <li>der Verantwortliche keine zwingenden schutzwürdigen Gründe für die Verarbeitung nachweisen kann, die - Ihre Interessen, Rechte und Freiheiten überwiegen bzw. die Verarbeitung keiner Geltendmachung, - Ausübung oder Verteidigung von Rechtsansprüchen dient. - </li> - </ul> - <p></p> - + der Verantwortliche keine zwingenden schutzwürdigen Gründe für die Verarbeitung nachweisen kann, die Ihre Interessen, Rechte und + Freiheiten überwiegen bzw. die Verarbeitung keiner Geltendmachung, Ausübung oder Verteidigung von Rechtsansprüchen dient. </li> - </ol> - + </ul> + <p></p> + </li> + </ol> - <h4>Cookies</h4> - <p> - Um den Funktionsumfang unseres Internetangebotes zu erweitern und die Nutzung für Sie komfortabler zu gestalten, - verwenden wir so genannte „Cookies". Mit Hilfe dieser - Cookies können bei dem Aufruf unserer Webseite Daten auf Ihrem Rechner gespeichert werden. Sie können das - Speichern von Cookies jedoch deaktivieren oder Ihren Browser so - einstellen, dass Cookies nur für die Dauer der jeweiligen Verbindung zum Internet gespeichert werden. Hierdurch - könnte allerdings der Funktionsumfang unseres Angebotes - eingeschränkt werden. - </p> - <p></p> + <h4>Cookies</h4> + <p> + Um den Funktionsumfang unseres Internetangebotes zu erweitern und die Nutzung für Sie komfortabler zu gestalten, verwenden wir so + genannte „Cookies". Mit Hilfe dieser Cookies können bei dem Aufruf unserer Webseite Daten auf Ihrem Rechner gespeichert werden. Sie + können das Speichern von Cookies jedoch deaktivieren oder Ihren Browser so einstellen, dass Cookies nur für die Dauer der jeweiligen + Verbindung zum Internet gespeichert werden. Hierdurch könnte allerdings der Funktionsumfang unseres Angebotes eingeschränkt werden. + </p> + <p></p> - <h4>E-Mail Kommunikation</h4> - <p> - Informationen, die Sie unverschlüsselt per E-Mail an uns senden, können möglicherweise auf dem Ãœbertragungsweg - von Dritten gelesen werden. Wir können in der Regel auch Ihre - Identität nicht überprüfen und wissen nicht, wer sich hinter einer E-Mail Adresse verbirgt. Eine rechtssichere - Kommunikation durch einfache E-Mail ist daher nicht - gewährleistet. - </p> - <p></p> + <h4>E-Mail Kommunikation</h4> + <p> + Informationen, die Sie unverschlüsselt per E-Mail an uns senden, können möglicherweise auf dem Ãœbertragungsweg von Dritten gelesen + werden. Wir können in der Regel auch Ihre Identität nicht überprüfen und wissen nicht, wer sich hinter einer E-Mail Adresse verbirgt. + Eine rechtssichere Kommunikation durch einfache E-Mail ist daher nicht gewährleistet. + </p> + <p></p> - <h4>Änderung der Datenschutzerklärung</h4> - <p> - Wir behalten uns vor, unsere Datenschutzerklärung gelegentlich anzupassen, damit sie stets den aktuellen - rechtlichen Anforderungen entspricht oder um Änderungen unserer - Leistungen in der Datenschutzerklärung umzusetzen. Wir empfehlen Ihnen, diese Datenschutzerklärung regelmäßig zu - lesen, um über den Schutz der von uns erfassten persönlichen - Daten auf dem Laufenden zu bleiben. Durch die fortgesetzte Nutzung der Sharing Plattform erklären Sie sich mit - dieser Datenschutzerklärung und deren Aktualisierung - einverstanden. - </p> -</div> \ No newline at end of file + <h4>Änderung der Datenschutzerklärung</h4> + <p> + Wir behalten uns vor, unsere Datenschutzerklärung gelegentlich anzupassen, damit sie stets den aktuellen rechtlichen Anforderungen + entspricht oder um Änderungen unserer Leistungen in der Datenschutzerklärung umzusetzen. Wir empfehlen Ihnen, diese Datenschutzerklärung + regelmäßig zu lesen, um über den Schutz der von uns erfassten persönlichen Daten auf dem Laufenden zu bleiben. Durch die fortgesetzte + Nutzung der Sharing Plattform erklären Sie sich mit dieser Datenschutzerklärung und deren Aktualisierung einverstanden. + </p> +</div> diff --git a/src/main/webapp/app/layouts/datapolicy/datapolicy.component.ts b/src/main/webapp/app/layouts/datapolicy/datapolicy.component.ts index 73dbc4beb6a1e9e06754636a7cac070c5f14dceb..7b390276231c2ebec8ae7ca3d804e66d0df761a3 100755 --- a/src/main/webapp/app/layouts/datapolicy/datapolicy.component.ts +++ b/src/main/webapp/app/layouts/datapolicy/datapolicy.component.ts @@ -3,9 +3,6 @@ import { Component } from '@angular/core'; @Component({ selector: 'jhi-datapolicy', templateUrl: './datapolicy.component.html', - styleUrls: ['./datapolicy.component.scss'] + styleUrls: ['./datapolicy.component.scss'], }) -export class DatapolicyComponent { - - -} +export class DatapolicyComponent {} diff --git a/src/main/webapp/app/layouts/footer/footer.component.html b/src/main/webapp/app/layouts/footer/footer.component.html index 691a2c457befbc64f0550358202a630faa8ce3d6..dd6fe9a143c5aa5ae3a373927fefb246ab87337f 100644 --- a/src/main/webapp/app/layouts/footer/footer.component.html +++ b/src/main/webapp/app/layouts/footer/footer.component.html @@ -1,28 +1,38 @@ <div class="footer"> - <div class="container-fluid"> - <div class="row"> - <div class="col-4"> - <div class="logo-container"> - <img style="padding-left: 25px; padding-top: 15px; float: left;" src="/content/img/logo-footer.png" alt="logoFooter" width="128" height="auto"> - </div> + <div class="container-fluid"> + <div class="row"> + <div class="col-4"> + <div class="logo-container"> + <img + style="padding-left: 25px; padding-top: 15px; float: left" + src="/content/img/logo-footer.png" + alt="logoFooter" + width="128" + height="auto" + /> + </div> + </div> + <div class="col-8"> + <div style="float: left; padding-top: 15px"> + <ul> + <li><a href="https://codeability.uibk.ac.at/" jhiTranslate="global.footer.about">About codeAbility</a></li> + </ul> + </div> + <div style="float: left; padding-top: 15px"> + <ul> + <li><a href="https://www.uibk.ac.at/informatik/" jhiTranslate="global.footer.imprint">Imprint</a></li> + </ul> + </div> + <div style="float: left; padding-top: 15px"> + <ul> + <li><a jhiTranslate="global.footer.privacy" routerLink="/datapolicy" routerLinkActive="active">Privacy</a></li> + </ul> + </div> + <div style="float: right; font-size: 50%; padding-top: 15px" *ngIf="applicationInfoService.getDeploymentInfo().branch"> + {{ applicationInfoService.getDeploymentInfo().branch }}/{{ applicationInfoService.getDeploymentInfo().commitId }} ({{ + applicationInfoService.getDeploymentInfo().deploymentDate + }}) </div> - <div class="col-8"> - <div style="float: left; padding-top: 15px;"> - <ul> - <li><a href="https://codeability.uibk.ac.at/" jhiTranslate="global.footer.about">About codeAbility</a></li> - </ul> - </div> - <div style="float: left; padding-top: 15px;"> - <ul> - <li><a href="https://www.uibk.ac.at/informatik/" jhiTranslate="global.footer.imprint">Imprint</a></li> - </ul> - </div> - <div style="float: left; padding-top: 15px;"> - <ul> - <li><a jhiTranslate="global.footer.privacy" routerLink="/datapolicy" routerLinkActive="active">Privacy</a></li> - </ul> - </div> - <div style="float: right; font-size: 50%;padding-top: 15px;" *ngIf="applicationInfoService.getDeploymentInfo().branch">{{applicationInfoService.getDeploymentInfo().branch}}/{{applicationInfoService.getDeploymentInfo().commitId}} ({{applicationInfoService.getDeploymentInfo().deploymentDate}})</div> </div> </div> </div> diff --git a/src/main/webapp/app/layouts/footer/footer.component.ts b/src/main/webapp/app/layouts/footer/footer.component.ts index 2a54d1bda5dc31c3227322f20b51d8c37e095c9d..c38de466f2896c137a9b63ee85c9905ab72df457 100644 --- a/src/main/webapp/app/layouts/footer/footer.component.ts +++ b/src/main/webapp/app/layouts/footer/footer.component.ts @@ -1,10 +1,10 @@ import { Component } from '@angular/core'; -import { ApplicationInfoService } from 'app/core/application/applicationInfo.service' +import { ApplicationInfoService } from 'app/core/application/applicationInfo.service'; @Component({ selector: 'jhi-footer', templateUrl: './footer.component.html', }) export class FooterComponent { - constructor(public applicationInfoService: ApplicationInfoService) {} + constructor(public applicationInfoService: ApplicationInfoService) {} } diff --git a/src/main/webapp/app/layouts/main/main.component.html b/src/main/webapp/app/layouts/main/main.component.html index 3d7c6a1e873d95d4242ad1adbb98436220045ef2..06cc464b6708cda9d42f0fbd7f60ff710042ec99 100644 --- a/src/main/webapp/app/layouts/main/main.component.html +++ b/src/main/webapp/app/layouts/main/main.component.html @@ -1,29 +1,27 @@ -<div style="display: flex; flex-direction: column; min-height: 100vh;"> +<div style="display: flex; flex-direction: column; min-height: 100vh"> + <!-- codeability bar --> + <div id="top-space"> + <img src="/content/img/logo-top.png" alt="codeAbility" width="168px" /> + </div> - <!-- codeability bar --> - <div id="top-space"> - <img src="/content/img/logo-top.png" alt="codeAbility" width="168px"> - </div> - -<div> + <div> <router-outlet name="navbar"></router-outlet> -</div> -<!-- TODO + </div> + <!-- TODO <div *ngFor="let m of getActiveMessages()"> <div class="alert alert-warning">{{m.message}}</div> </div> --> -<div class="container-fluid"> + <div class="container-fluid"> + <div class="pagewrapper"></div> - <div class="pagewrapper"></div> + <!-- Main content --> + <router-outlet></router-outlet> - <!-- Main content --> - <router-outlet></router-outlet> + <div class="pagewrapper"></div> - <div class="pagewrapper"></div> - - <jhi-page-ribbon></jhi-page-ribbon> - </div> + <jhi-page-ribbon></jhi-page-ribbon> + </div> - <jhi-footer style="margin-top:auto"></jhi-footer> + <jhi-footer style="margin-top: auto"></jhi-footer> </div> diff --git a/src/main/webapp/app/layouts/main/main.component.ts b/src/main/webapp/app/layouts/main/main.component.ts index f8156d27936370cd519ff0799674c0cb2c8d3af3..6d5b61eb02f03230301a58d98c12cdeaa64d38a0 100644 --- a/src/main/webapp/app/layouts/main/main.component.ts +++ b/src/main/webapp/app/layouts/main/main.component.ts @@ -8,7 +8,6 @@ import { AccountService } from 'app/core/auth/account.service'; import { AuthServerProvider } from 'app/core/auth/auth-jwt.service'; import { CookieService } from 'ngx-cookie-service'; - @Component({ selector: 'jhi-main', templateUrl: './main.component.html', @@ -62,7 +61,6 @@ export class MainComponent implements OnInit { } } - private getPageTitle(routeSnapshot: ActivatedRouteSnapshot): string { const title: string = routeSnapshot.data['pageTitle'] ?? ''; if (routeSnapshot.firstChild) { diff --git a/src/main/webapp/app/search-old/highlighting/highlighting.component.html b/src/main/webapp/app/search-old/highlighting/highlighting.component.html index 9b84493b8bee59a9e097d6079701799acb8e6d1d..d5d536c1ae5105bad0ca09dc3ce9993c7cccb273 100644 --- a/src/main/webapp/app/search-old/highlighting/highlighting.component.html +++ b/src/main/webapp/app/search-old/highlighting/highlighting.component.html @@ -1,15 +1,25 @@ <div style="margin: 10px"> - <table><caption>file content</caption> - <tbody> - <tr><th scope="col">line number</th><th scope="col"></th><th scope="col">code</th></tr> - <tr *ngFor="let line of lineByLine(); index as i"> - <td class="right lines" *ngIf="language"> <pre><code class="line-number"><a (click)="url(i)"> {{lineNumber(i)}}</a></code></pre></td> - <td class="right" *ngIf="!language"> <pre><code class="line-number"></code></pre></td> - <td> - <pre><code [innerHTML]="highlightCode(line)"></code></pre> - </td> - </tr> - </tbody> - </table> - + <table> + <caption> + file content + </caption> + <tbody> + <tr> + <th scope="col">line number</th> + <th scope="col"></th> + <th scope="col">code</th> + </tr> + <tr *ngFor="let line of lineByLine(); index as i"> + <td class="right lines" *ngIf="language"> + <pre><code class="line-number"><a (click)="url(i)"> {{lineNumber(i)}}</a></code></pre> + </td> + <td class="right" *ngIf="!language"> + <pre><code class="line-number"></code></pre> + </td> + <td> + <pre><code [innerHTML]="highlightCode(line)"></code></pre> + </td> + </tr> + </tbody> + </table> </div> diff --git a/src/main/webapp/app/search-old/search.component.html b/src/main/webapp/app/search-old/search.component.html index f47f591ab333520fc21381a5e49c799b9853ea31..49f6d8f1826e9bd081ed397d0122244825199dce 100644 --- a/src/main/webapp/app/search-old/search.component.html +++ b/src/main/webapp/app/search-old/search.component.html @@ -1,160 +1,175 @@ <div class="row"> - <div class="col-md-12"> - <h2 class="display-4" jhiTranslate="search.title">Welcome!</h2> + <div class="col-md-12"> + <h2 class="display-4" jhiTranslate="search.title">Welcome!</h2> - <span jhiTranslate="search.usage">The search mask allows you to search for full texts in the sharing platform based on various search criteria (e.g., full-text search, programming languages, keywords, etc.). Boolean operators can be used in the search mask for full texts. Apart from the full-text search, no further fields are to be specified.</span> + <span jhiTranslate="search.usage" + >The search mask allows you to search for full texts in the sharing platform based on various search criteria (e.g., full-text search, + programming languages, keywords, etc.). Boolean operators can be used in the search mask for full texts. Apart from the full-text + search, no further fields are to be specified.</span + > - <div [ngSwitch]="isAuthenticated()"> - <ng-container [queryParamGroup]="paramGroup"> - <div class="row"> - <div class="col-sm-12"> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="searchText" - placeholder="{{ 'search.filters.search' | translate }}"/> - </div> - </form> - </div> - </div> - - <div class="row"> - <div class="col-sm-3"> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="programmingLanguage" - placeholder="{{ 'search.filters.programmingLanguage' | translate }}"/> - </div> - </form> - </div> - <div class="col-sm-3"> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="keyword" - placeholder="{{ 'search.filters.keywords' | translate }}"/> - </div> - </form> - </div> - <div class="col-sm-3"> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="author" - placeholder="{{ 'search.filters.author' | translate }}"/> - </div> - </form> - </div> - <div class="col-sm-3"> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="license" - placeholder="{{ 'search.filters.license' | translate }}"/> - </div> - </form> - </div> - </div> - </ng-container> - - <div class="row"> - <div class="col-2"> - <ng-container *ngIf="gitFilesAggregation"> - <br> - <h3 jhiTranslate="search.metadata.filter">Search Filter</h3> + <div [ngSwitch]="isAuthenticated()"> + <ng-container [queryParamGroup]="paramGroup"> + <div class="row"> + <div class="col-sm-12"> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input + type="text" + class="form-control" + queryParamName="searchText" + placeholder="{{ 'search.filters.search' | translate }}" + /> + </div> + </form> + </div> + </div> - <div class="filter"> - <ng-select - [hidden]="gitFilesAggregation?.repositories == null" - [items]="repos" - bindLabel="key" - [multiple]="true" - (change)="filter()" - [(ngModel)]="searchInput.fulltextSelection.repository" - placeholder="{{ 'search.metadata.repository' | translate }}"> - </ng-select> - </div> + <div class="row"> + <div class="col-sm-3"> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input + type="text" + class="form-control" + queryParamName="programmingLanguage" + placeholder="{{ 'search.filters.programmingLanguage' | translate }}" + /> + </div> + </form> + </div> + <div class="col-sm-3"> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input + type="text" + class="form-control" + queryParamName="keyword" + placeholder="{{ 'search.filters.keywords' | translate }}" + /> + </div> + </form> + </div> + <div class="col-sm-3"> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input type="text" class="form-control" queryParamName="author" placeholder="{{ 'search.filters.author' | translate }}" /> + </div> + </form> + </div> + <div class="col-sm-3"> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input type="text" class="form-control" queryParamName="license" placeholder="{{ 'search.filters.license' | translate }}" /> + </div> + </form> + </div> + </div> + </ng-container> - <div class="filter"> - <ng-select - [hidden]="gitFilesAggregation?.university == null" - [items]="university" - bindLabel="key" - [multiple]="true" - (change)="filter()" - [(ngModel)]="searchInput.fulltextSelection.university" - placeholder="{{ 'search.metadata.university' | translate }}"> - </ng-select> - </div> + <div class="row"> + <div class="col-2"> + <ng-container *ngIf="gitFilesAggregation"> + <br /> + <h3 jhiTranslate="search.metadata.filter">Search Filter</h3> - <div class="filter"> - <ng-select - [hidden]="gitFilesAggregation?.fileFormat == null" - [items]="fileFormat" - bindLabel="key" - [multiple]="true" - (change)="filter()" - [(ngModel)]="searchInput.fulltextSelection.fileFormat" - placeholder="{{ 'search.metadata.fileFormat' | translate }}"> - </ng-select> - </div> + <div class="filter"> + <ng-select + [hidden]="gitFilesAggregation?.repositories == null" + [items]="repos" + bindLabel="key" + [multiple]="true" + (change)="filter()" + [(ngModel)]="searchInput.fulltextSelection.repository" + placeholder="{{ 'search.metadata.repository' | translate }}" + > + </ng-select> + </div> - <hr> + <div class="filter"> + <ng-select + [hidden]="gitFilesAggregation?.university == null" + [items]="university" + bindLabel="key" + [multiple]="true" + (change)="filter()" + [(ngModel)]="searchInput.fulltextSelection.university" + placeholder="{{ 'search.metadata.university' | translate }}" + > + </ng-select> + </div> - <h3 jhiTranslate="search.metadata.information">Search information</h3> + <div class="filter"> + <ng-select + [hidden]="gitFilesAggregation?.fileFormat == null" + [items]="fileFormat" + bindLabel="key" + [multiple]="true" + (change)="filter()" + [(ngModel)]="searchInput.fulltextSelection.fileFormat" + placeholder="{{ 'search.metadata.fileFormat' | translate }}" + > + </ng-select> + </div> - <jhi-home-metadata [frequencies]="gitFilesAggregation?.repositories" - [parameter]="'repository'"></jhi-home-metadata> - <jhi-home-metadata [frequencies]="gitFilesAggregation?.university" - [parameter]="'university'"></jhi-home-metadata> - <jhi-home-metadata [frequencies]="gitFilesAggregation?.fileFormat" - [parameter]="'fileFormat'"></jhi-home-metadata> - </ng-container> - </div> + <hr /> - <div class="col-10"> - <ng-container *ngIf="gitFilesPageDetails"> - <hr> - <h2 id="home-logged-message" jhiTranslate="search.searchResult.title" - [translateValues]="{ results: gitFilesPageDetails?.hitCount || 0 }">search - results</h2> - </ng-container> - <hr [hidden]="gitFilesAggregation == null"> + <h3 jhiTranslate="search.metadata.information">Search information</h3> - <div *ngIf="gitFilesPageDetails?.gitFiles !== null"> - <div - *ngFor="let gitFile of gitFiles"> - <a (click)="onClickMe(gitFile)">{{ gitFile.filePath}}</a> - <div class="solid"> - <div class="row"> - <jhi-home-highlighting [gitFiles]="gitFile"></jhi-home-highlighting> - </div> - </div> + <jhi-home-metadata [frequencies]="gitFilesAggregation?.repositories" [parameter]="'repository'"></jhi-home-metadata> + <jhi-home-metadata [frequencies]="gitFilesAggregation?.university" [parameter]="'university'"></jhi-home-metadata> + <jhi-home-metadata [frequencies]="gitFilesAggregation?.fileFormat" [parameter]="'fileFormat'"></jhi-home-metadata> + </ng-container> + </div> - <div class="row"> - <div class="col-sm"> - <span class="info"><fa-icon icon="language"></fa-icon> - {{gitFile.fileFormat}}</span> - </div> - <div class="col-sm"> - <span class="info"><fa-icon icon="book"></fa-icon> - {{gitFile.repository}}</span> - </div> - </div> + <div class="col-10"> + <ng-container *ngIf="gitFilesPageDetails"> + <hr /> + <h2 + id="home-logged-message" + jhiTranslate="search.searchResult.title" + [translateValues]="{ results: gitFilesPageDetails?.hitCount || 0 }" + > + search results + </h2> + </ng-container> + <hr [hidden]="gitFilesAggregation == null" /> - <hr> - </div> - </div> - <div class="d-flex justify-content-center"> - <ngb-pagination - (pageChange)="onPageChange($event)" - [hidden]="hitCount == 0" - [(page)]="searchInput.page" - [pageSize]="pageSize" - [boundaryLinks]="true" - [maxSize]="5" - [rotate]="true" - [collectionSize]="hitCount"></ngb-pagination> - </div> + <div *ngIf="gitFilesPageDetails?.gitFiles !== null"> + <div *ngFor="let gitFile of gitFiles"> + <a (click)="onClickMe(gitFile)">{{ gitFile.filePath }}</a> + <div class="solid"> + <div class="row"> + <jhi-home-highlighting [gitFiles]="gitFile"></jhi-home-highlighting> + </div> + </div> + <div class="row"> + <div class="col-sm"> + <span class="info"><fa-icon icon="language"></fa-icon> {{ gitFile.fileFormat }}</span> </div> + <div class="col-sm"> + <span class="info"><fa-icon icon="book"></fa-icon> {{ gitFile.repository }}</span> + </div> + </div> + + <hr /> </div> + </div> + <div class="d-flex justify-content-center"> + <ngb-pagination + (pageChange)="onPageChange($event)" + [hidden]="hitCount == 0" + [(page)]="searchInput.page" + [pageSize]="pageSize" + [boundaryLinks]="true" + [maxSize]="5" + [rotate]="true" + [collectionSize]="hitCount" + ></ngb-pagination> + </div> </div> + </div> </div> + </div> </div> diff --git a/src/main/webapp/app/search/search-input/search-input.component.html b/src/main/webapp/app/search/search-input/search-input.component.html index a24e68083874c99b25a81fd42a0c8bb585f1097e..512e3efe5d720ebccba19c0c9ea080ad9f1ca56f 100644 --- a/src/main/webapp/app/search/search-input/search-input.component.html +++ b/src/main/webapp/app/search/search-input/search-input.component.html @@ -1,97 +1,133 @@ <div class="searchform-container"> - <h2 class="display-4" style="width: 100%;" jhiTranslate="search.title">Search!</h2> - <ng-container [queryParamGroup]="paramGroup"> - <div> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="searchText" - placeholder="{{ 'search.filters.search' | translate }}"/> - <ng-template #helpFulltext> {{ 'search.help.fulltext' | translate}}</ng-template> - <fa-icon style="padding: 10px 0px 0px 10px;" [ngbTooltip]="helpFulltext" container="body" [icon]="questionIcon"></fa-icon> - </div> - </form> + <h2 class="display-4" style="width: 100%" jhiTranslate="search.title">Search!</h2> + <ng-container [queryParamGroup]="paramGroup"> + <div> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input type="text" class="form-control" queryParamName="searchText" placeholder="{{ 'search.filters.search' | translate }}" /> + <ng-template #helpFulltext> {{ 'search.help.fulltext' | translate }}</ng-template> + <fa-icon style="padding: 10px 0px 0px 10px" [ngbTooltip]="helpFulltext" container="body" [icon]="questionIcon"></fa-icon> </div> + </form> + </div> - <div> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="programmingLanguage" [ngbTypeahead]="autoCompleteProgrammingLanguage" - placeholder="{{ 'search.filters.programmingLanguage' | translate }}"/> - <ng-template #helpPL> {{ 'search.help.programmingLanguage' | translate}}</ng-template> - <fa-icon style="padding: 10px 0px 0px 10px;" [ngbTooltip]="helpPL" container="body" [icon]="questionIcon"></fa-icon> - </div> - </form> + <div> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input + type="text" + class="form-control" + queryParamName="programmingLanguage" + [ngbTypeahead]="autoCompleteProgrammingLanguage" + placeholder="{{ 'search.filters.programmingLanguage' | translate }}" + /> + <ng-template #helpPL> {{ 'search.help.programmingLanguage' | translate }}</ng-template> + <fa-icon style="padding: 10px 0px 0px 10px" [ngbTooltip]="helpPL" container="body" [icon]="questionIcon"></fa-icon> </div> + </form> + </div> - <div> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="keyword" [ngbTypeahead]="autoCompleteKeyWords" - placeholder="{{ 'search.filters.keywords' | translate }}"/> - <ng-template #helpKeyword> {{ 'search.help.keywords' | translate}}</ng-template> - <fa-icon style="padding: 10px 0px 0px 10px;" [ngbTooltip]="helpKeyword" container="body" [icon]="questionIcon"></fa-icon> - </div> - </form> + <div> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input + type="text" + class="form-control" + queryParamName="keyword" + [ngbTypeahead]="autoCompleteKeyWords" + placeholder="{{ 'search.filters.keywords' | translate }}" + /> + <ng-template #helpKeyword> {{ 'search.help.keywords' | translate }}</ng-template> + <fa-icon style="padding: 10px 0px 0px 10px" [ngbTooltip]="helpKeyword" container="body" [icon]="questionIcon"></fa-icon> </div> + </form> + </div> - <div> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="format" [ngbTypeahead]="autoCompleteFormats" - placeholder="{{ 'search.filters.formats' | translate }}"/> - <ng-template #helpFormat> {{ 'search.help.formats' | translate}}</ng-template> - <fa-icon style="padding: 10px 0px 0px 10px;" [ngbTooltip]="helpFormat" container="body" [icon]="questionIcon"></fa-icon> - </div> - </form> + <div> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input + type="text" + class="form-control" + queryParamName="format" + [ngbTypeahead]="autoCompleteFormats" + placeholder="{{ 'search.filters.formats' | translate }}" + /> + <ng-template #helpFormat> {{ 'search.help.formats' | translate }}</ng-template> + <fa-icon style="padding: 10px 0px 0px 10px" [ngbTooltip]="helpFormat" container="body" [icon]="questionIcon"></fa-icon> </div> + </form> + </div> - <div> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="author" name="author" [ngbTypeahead]="autoCompleteContributorCreator" - placeholder="{{ 'search.filters.author' | translate }}"/> - <ng-template #helpauthorContributors data-container="body"> {{ 'search.help.authorContributors' | translate}}</ng-template> - <fa-icon style="padding: 10px 0px 0px 10px;" [ngbTooltip]="helpauthorContributors" container="body" [icon]="questionIcon"></fa-icon> - </div> - </form> + <div> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input + type="text" + class="form-control" + queryParamName="author" + name="author" + [ngbTypeahead]="autoCompleteContributorCreator" + placeholder="{{ 'search.filters.author' | translate }}" + /> + <ng-template #helpauthorContributors data-container="body"> {{ 'search.help.authorContributors' | translate }}</ng-template> + <fa-icon + style="padding: 10px 0px 0px 10px" + [ngbTooltip]="helpauthorContributors" + container="body" + [icon]="questionIcon" + ></fa-icon> </div> + </form> + </div> - <div> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"> - <input type="text" class="form-control" queryParamName="license" - placeholder="{{ 'search.filters.license' | translate }}"/> - <ng-template #helpLicense> {{ 'search.help.license' | translate}}</ng-template> - <fa-icon style="padding: 10px 0px 0px 10px;" [ngbTooltip]="helpLicense" container="body" [icon]="questionIcon"></fa-icon> - </div> - </form> + <div> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <input type="text" class="form-control" queryParamName="license" placeholder="{{ 'search.filters.license' | translate }}" /> + <ng-template #helpLicense> {{ 'search.help.license' | translate }}</ng-template> + <fa-icon style="padding: 10px 0px 0px 10px" [ngbTooltip]="helpLicense" container="body" [icon]="questionIcon"></fa-icon> </div> - <div *ngIf="searchInput.metadata.parentId"> - <form name="searchForm" class="form-inline"> - <div class="input-group w-100 mt-3"><span jhiTranslate="search.filters.parentId"></span>: {{searchInput.metadata.parentId}} - <ng-template #helpParent data-container="body"> {{ 'search.help.helpParent' | translate}}</ng-template> - <fa-icon style="padding: 5px 0px 0px 5px;float:right;" [ngbTooltip]="helpParent" container="body" [icon]="crossIcon" (click)="clearParentId()"></fa-icon> - </div> - </form> + </form> + </div> + <div *ngIf="searchInput.metadata.parentId"> + <form name="searchForm" class="form-inline"> + <div class="input-group w-100 mt-3"> + <span jhiTranslate="search.filters.parentId"></span>: {{ searchInput.metadata.parentId }} + <ng-template #helpParent data-container="body"> {{ 'search.help.helpParent' | translate }}</ng-template> + <fa-icon + style="padding: 5px 0px 0px 5px; float: right" + [ngbTooltip]="helpParent" + container="body" + [icon]="crossIcon" + (click)="clearParentId()" + ></fa-icon> </div> - <div> - <form name="searchFormLanguage" class="form-inline"> - <div class="nav-item dropdown"> - <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="javascript:void(0);"> - <span jhiTranslate="exercise.metadata.language.mix">Language(s)</span> - </a><span *ngFor="let language of getSelectedLanguages(), let isLast=last">{{'exercise.metadata.' + language | translate}}{{isLast ? '' : ', '}}</span> - <div class="dropdown-menu" style="padding-left: 10px;"> - <table><tr *ngFor="let language of languageValues"><td> - <label class="form-check-label" style="display: inline-block;align-items: left"><input [value]="language" type="checkbox" queryParamName="{{language}}"> {{'exercise.metadata.' + language | translate}}</label> - </td></table> - </div> - </div> - - </form> + </form> + </div> + <div> + <form name="searchFormLanguage" class="form-inline"> + <div class="nav-item dropdown"> + <a class="nav-link dropdown-toggle" data-toggle="dropdown" href="javascript:void(0);"> + <span jhiTranslate="exercise.metadata.language.mix">Language(s)</span> </a + ><span *ngFor="let language of getSelectedLanguages(); let isLast = last" + >{{ 'exercise.metadata.' + language | translate }}{{ isLast ? '' : ', ' }}</span + > + <div class="dropdown-menu" style="padding-left: 10px"> + <table> + <tr *ngFor="let language of languageValues"> + <td> + <label class="form-check-label" style="display: inline-block; align-items: left" + ><input [value]="language" type="checkbox" queryParamName="{{ language }}" /> + {{ 'exercise.metadata.' + language | translate }}</label + > + </td> + </tr> + </table> + </div> </div> - </ng-container> - <jhi-bookmark-info> - </jhi-bookmark-info> + </form> + </div> + </ng-container> + <jhi-bookmark-info> </jhi-bookmark-info> </div> - - diff --git a/src/main/webapp/app/search/service/search-service.ts b/src/main/webapp/app/search/service/search-service.ts index 463fc2b948d034e55764d37731e797d2d11af303..61e58a16b97d9c1c46317753b76b84167e30ceec 100644 --- a/src/main/webapp/app/search/service/search-service.ts +++ b/src/main/webapp/app/search/service/search-service.ts @@ -14,9 +14,13 @@ export class SearchService { public resourceSearchUrlStatisticsForExercise = this.applicationConfigService.getEndpointFor('api/statistics/exercise/'); public resourceKeywordsAutoCompleteDetails = this.applicationConfigService.getEndpointFor('api/search/keywordsAutoComplete'); public resourceFormatsAutoCompleteDetails = this.applicationConfigService.getEndpointFor('api/search/formatsAutoComplete'); - public resourceProgrammingLanguageAutoCompleteDetails = this.applicationConfigService.getEndpointFor('api/search/programmingLanguageAutoComplete'); + public resourceProgrammingLanguageAutoCompleteDetails = this.applicationConfigService.getEndpointFor( + 'api/search/programmingLanguageAutoComplete' + ); public resourceContributorAutoCompleteDetails = this.applicationConfigService.getEndpointFor('api/search/contributorAutoComplete'); - public resourceContributorCreatorAutoCompleteDetails = this.applicationConfigService.getEndpointFor('api/search/contributorCreatorAutoComplete'); + public resourceContributorCreatorAutoCompleteDetails = this.applicationConfigService.getEndpointFor( + 'api/search/contributorCreatorAutoComplete' + ); public resourceCreatorAutoCompleteDetails = this.applicationConfigService.getEndpointFor('api/search/creatorAutoComplete'); constructor(protected http: HttpClient, private applicationConfigService: ApplicationConfigService) {} @@ -45,7 +49,7 @@ export class SearchService { }); } -/** + /** unused!! downloadFile(projectID: string): Observable<Object> { return this.http.post(this.applicationConfigService.getEndpointFor('download/') + projectID, { diff --git a/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.html b/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.html index b97f11a3117579633c855cc5fdaff509ef4abb55..bd3d5dc703ea0ebb67b1ef1dc043b1cf9a752e2a 100644 --- a/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.html +++ b/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.html @@ -1,61 +1,62 @@ <div> - <div class="modal-header"> - <h4 class="modal-title" jhiTranslate="gitlab.pathSelector.title">Gitlab Path</h4> - <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="closeModal(undefined)">×</button> - </div> - <div class="modal-body"> - <div class="justify-content-center p-1"> - <jhi-alert></jhi-alert> - <jhi-alert-error></jhi-alert-error> - <div class="table-responsive p-1" *ngIf="!isLoading"> - <table class="table table-striped"><caption>GitLab Path Selection</caption> - <thead> - <tr> - <th scope="col"></th> - <th scope="col"><span jhiTranslate="gitlab.pathSelector.name">Name</span></th> - <th scope="col"><span jhiTranslate="gitlab.pathSelector.description">Description</span></th> - <th scope="col"><span jhiTranslate="gitlab.pathSelector.visibility">Visibility</span></th> - <th scope="col"><span jhiTranslate="gitlab.pathSelector.url">URL</span></th> - </tr> - </thead> - <tbody> - <tr *ngFor="let group of groups"> - <td> - <img - [height]="48" - src="{{ group.avatarUrl ? group.avatarUrl : '/content/img/gitLab.png' }}" alt="avatar"/> - </td> - <td> - <strong>{{group.name}}</strong> - </td> - <td> - <span>{{group.description}}</span> - </td> - <td> - <span>{{group.visibility}}</span> - </td> - <td> - <span>{{group.webUrl}}</span> - </td> - <td> - <button type="button" class="btn ml-2 btn-primary" (click)="closeModal(group)" jhiTranslate="gitlab.pathSelector.select"> - Select - </button> - </td> - </tr> - </tbody> - </table> - </div> - <div *ngIf="isLoading"> - <div class="h-100 w-100 d-flex justify-content-center align-items-center m-5"> - <div class="spinner"></div> - </div> - </div> - <div *ngIf="errorOccurred"> - <div class="h-100 w-100 d-flex justify-content-center align-items-center m-5"> - <strong jhiTranslate="gitlab.pathSelector.errorOccurred"></strong> - </div> - </div> + <div class="modal-header"> + <h4 class="modal-title" jhiTranslate="gitlab.pathSelector.title">Gitlab Path</h4> + <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="closeModal(undefined)">×</button> + </div> + <div class="modal-body"> + <div class="justify-content-center p-1"> + <jhi-alert></jhi-alert> + <jhi-alert-error></jhi-alert-error> + <div class="table-responsive p-1" *ngIf="!isLoading"> + <table class="table table-striped"> + <caption> + GitLab Path Selection + </caption> + <thead> + <tr> + <th scope="col"></th> + <th scope="col"><span jhiTranslate="gitlab.pathSelector.name">Name</span></th> + <th scope="col"><span jhiTranslate="gitlab.pathSelector.description">Description</span></th> + <th scope="col"><span jhiTranslate="gitlab.pathSelector.visibility">Visibility</span></th> + <th scope="col"><span jhiTranslate="gitlab.pathSelector.url">URL</span></th> + </tr> + </thead> + <tbody> + <tr *ngFor="let group of groups"> + <td> + <img [height]="48" src="{{ group.avatarUrl ? group.avatarUrl : '/content/img/gitLab.png' }}" alt="avatar" /> + </td> + <td> + <strong>{{ group.name }}</strong> + </td> + <td> + <span>{{ group.description }}</span> + </td> + <td> + <span>{{ group.visibility }}</span> + </td> + <td> + <span>{{ group.webUrl }}</span> + </td> + <td> + <button type="button" class="btn ml-2 btn-primary" (click)="closeModal(group)" jhiTranslate="gitlab.pathSelector.select"> + Select + </button> + </td> + </tr> + </tbody> + </table> + </div> + <div *ngIf="isLoading"> + <div class="h-100 w-100 d-flex justify-content-center align-items-center m-5"> + <div class="spinner"></div> + </div> + </div> + <div *ngIf="errorOccurred"> + <div class="h-100 w-100 d-flex justify-content-center align-items-center m-5"> + <strong jhiTranslate="gitlab.pathSelector.errorOccurred"></strong> </div> + </div> </div> + </div> </div> diff --git a/src/main/webapp/app/shared/model/basket/shopping-basket-info.model.ts b/src/main/webapp/app/shared/model/basket/shopping-basket-info.model.ts index 41b44d07c688009a41eaf8828097f3196bd70748..faf684447d634f0e8518108f9036c2ca2e9b7a86 100644 --- a/src/main/webapp/app/shared/model/basket/shopping-basket-info.model.ts +++ b/src/main/webapp/app/shared/model/basket/shopping-basket-info.model.ts @@ -1,11 +1,11 @@ import { SearchResultDTO } from 'app/shared/model/search/search-result-dto.model'; export interface ShoppingBasketInfo { - itemInfos: SearchResultDTO[]; - plugin: string; - action: string; + itemInfos: SearchResultDTO[]; + plugin: string; + action: string; } export interface ShoppingBasketRedirectInfoDTO { - redirectURL: string; -} \ No newline at end of file + redirectURL: string; +} diff --git a/src/main/webapp/app/shared/model/file-info.model.ts b/src/main/webapp/app/shared/model/file-info.model.ts index 96d9d628da68023b52f312667efbd680e187dc72..a5ba887b1ca0803c0809093df905f6db843dc7fc 100644 --- a/src/main/webapp/app/shared/model/file-info.model.ts +++ b/src/main/webapp/app/shared/model/file-info.model.ts @@ -1,5 +1,4 @@ export interface IFileInfo { - extension: string; filename: string; path: string; @@ -9,12 +8,12 @@ export interface IFileInfo { } export class FileInfo implements IFileInfo { - public constructor(public extension: string, - public filename: string, - public path: string, - public file_format: string, - public indexing_date: Date, - public commit_id: string,) { - } - + public constructor( + public extension: string, + public filename: string, + public path: string, + public file_format: string, + public indexing_date: Date, + public commit_id: string + ) {} } diff --git a/src/main/webapp/app/shared/model/fragment.model.ts b/src/main/webapp/app/shared/model/fragment.model.ts index f9e234ded3089f93c00a7e80d80dcb5d62b2a461..60e29ce209ee4480bc1f5d063b24e78c97ae13e9 100644 --- a/src/main/webapp/app/shared/model/fragment.model.ts +++ b/src/main/webapp/app/shared/model/fragment.model.ts @@ -4,10 +4,5 @@ export interface IFragment { } export class Fragment implements IFragment { - constructor( - public fragment: string, - public firstLineNumber: number - ) { - } - + constructor(public fragment: string, public firstLineNumber: number) {} } diff --git a/src/main/webapp/app/shared/model/frequency.model.ts b/src/main/webapp/app/shared/model/frequency.model.ts index 027b41f9035b6173eb3d815d01059a8dc7eac1b0..2397c77506729b270f132f9ad826f1f0b9ae7b9e 100644 --- a/src/main/webapp/app/shared/model/frequency.model.ts +++ b/src/main/webapp/app/shared/model/frequency.model.ts @@ -4,9 +4,5 @@ export interface IFrequency<T> { } export class Frequency<T> implements IFrequency<T> { - constructor( - public key: T, - public value: number - ) { - } + constructor(public key: T, public value: number) {} } diff --git a/src/main/webapp/app/shared/model/git-files-aggregation.ts b/src/main/webapp/app/shared/model/git-files-aggregation.ts index 2e1207514b45ec3f3f5fde007bdecb0245b29ce9..b5bfb33ca6acc9b47f8a9607627c1f07b8e107b9 100644 --- a/src/main/webapp/app/shared/model/git-files-aggregation.ts +++ b/src/main/webapp/app/shared/model/git-files-aggregation.ts @@ -1,4 +1,4 @@ -import {IFrequency} from "app/shared/model/frequency.model"; +import { IFrequency } from 'app/shared/model/frequency.model'; export interface IGitFilesAggregation { fileFormat: IFrequency<string>[]; @@ -10,7 +10,6 @@ export class GitFilesAggregation implements IGitFilesAggregation { constructor( public fileFormat: IFrequency<string>[], public repositories: IFrequency<string>[], - public university: IFrequency<string>[], - ) { - } + public university: IFrequency<string>[] + ) {} } diff --git a/src/main/webapp/app/shared/model/git-files-page-details.model.ts b/src/main/webapp/app/shared/model/git-files-page-details.model.ts index db5534104b3d98c4f6e9523ce17135d1ff7e7e1e..ab57bc2eedf5f7abbabab62e3c1ef61a2d24ba3f 100644 --- a/src/main/webapp/app/shared/model/git-files-page-details.model.ts +++ b/src/main/webapp/app/shared/model/git-files-page-details.model.ts @@ -1,4 +1,4 @@ -import {IGitFiles} from "app/shared/model/git-files.model"; +import { IGitFiles } from 'app/shared/model/git-files.model'; export interface IGitFilesPageDetails { gitFiles: IGitFiles[]; @@ -6,10 +6,5 @@ export interface IGitFilesPageDetails { } export class GitFilesPageDetails implements IGitFilesPageDetails { - constructor( - public gitFiles: IGitFiles[], - public hitCount: number - ) { - } - + constructor(public gitFiles: IGitFiles[], public hitCount: number) {} } diff --git a/src/main/webapp/app/shared/model/git-files.model.ts b/src/main/webapp/app/shared/model/git-files.model.ts index 04df9416c19996e242d4370b51fb060e5a111913..a21df9f2ee7e7ffd5a68362cb81c5ffa3ae734a9 100644 --- a/src/main/webapp/app/shared/model/git-files.model.ts +++ b/src/main/webapp/app/shared/model/git-files.model.ts @@ -1,4 +1,4 @@ -import {IFragment} from "app/shared/model/fragment.model"; +import { IFragment } from 'app/shared/model/fragment.model'; export interface IGitFiles { content: string; @@ -24,8 +24,6 @@ export class GitFiles implements IGitFiles { public fileExtension: string, public fileName: string, public filePath: string, - public gitUrl: string, - ) { - } - + public gitUrl: string + ) {} } diff --git a/src/main/webapp/app/shared/model/search/search-result-dto.model.ts b/src/main/webapp/app/shared/model/search/search-result-dto.model.ts index 98d1de42f15d3f2da9c7a5c01ffeff1dae781422..56048f3f47f6652d2882f9bf84107bb5d08122d2 100644 --- a/src/main/webapp/app/shared/model/search/search-result-dto.model.ts +++ b/src/main/webapp/app/shared/model/search/search-result-dto.model.ts @@ -13,7 +13,7 @@ export interface SearchResultDTO { downloads: number; } -export function getPathOfExerciseId(exerciseId: string):string { +export function getPathOfExerciseId(exerciseId: string): string { if (exerciseId) { const colonPos = exerciseId.indexOf(':"'); if (colonPos >= 0) return exerciseId.slice(colonPos + 1); @@ -27,6 +27,6 @@ export interface PluginActionInfo { commandName: string; } -export function equalPluginActionInfo(a: PluginActionInfo, b: PluginActionInfo):boolean { +export function equalPluginActionInfo(a: PluginActionInfo, b: PluginActionInfo): boolean { return a.action === b.action && a.commandName === b.commandName && a.plugin === b.plugin; } diff --git a/src/main/webapp/app/shared/model/search/search-results-dto.model.ts b/src/main/webapp/app/shared/model/search/search-results-dto.model.ts index 82aea4021ea6559f644212393f7790b7b27f5786..20fca795f72e09e8cdd22af292041f61ace2844e 100644 --- a/src/main/webapp/app/shared/model/search/search-results-dto.model.ts +++ b/src/main/webapp/app/shared/model/search/search-results-dto.model.ts @@ -1,12 +1,7 @@ - import { SearchResultDTO } from './search-result-dto.model'; export interface SearchResultsDTO { - hitCount: number; - pageStartIndex: number; - searchResult: Array<SearchResultDTO>; + hitCount: number; + pageStartIndex: number; + searchResult: Array<SearchResultDTO>; } - - - - diff --git a/src/main/webapp/app/shared/service/cache.service.ts b/src/main/webapp/app/shared/service/cache.service.ts index 05fdfa1c17bf733fc60ddfd1c0cb7fb87a8d49b0..e0a8051e0dd97f12e53ed861ab856ad9df6c5101 100644 --- a/src/main/webapp/app/shared/service/cache.service.ts +++ b/src/main/webapp/app/shared/service/cache.service.ts @@ -4,7 +4,6 @@ import { Injectable } from '@angular/core'; Warning: Objects are stored as json-Strings. I.e. Dates objects (and others) may not be converted correctly */ @Injectable() export class CacheService { - save(options: LocalStorageSaveOptions) { // Set default values for optionals options.expirationMins = options.expirationMins || 0; diff --git a/src/main/webapp/app/shared/service/pages-service.ts b/src/main/webapp/app/shared/service/pages-service.ts index 456911fce8bc73f62509b7d60c5ebee62d198df8..18f5e1dd62fdd4f730eb1506e8c95a1263909e95 100644 --- a/src/main/webapp/app/shared/service/pages-service.ts +++ b/src/main/webapp/app/shared/service/pages-service.ts @@ -5,11 +5,9 @@ import { Observable } from 'rxjs'; import { ApplicationConfigService } from 'app/core/config/application-config.service'; - export interface EditorialPage { path: string; content: string; - } /** @@ -20,30 +18,25 @@ export class PagesService { public pageResourceURL = this.applicationConfigService.getEndpointFor('api/pages'); public attachmentResourceURL = this.applicationConfigService.getEndpointFor('api/pages/attachment'); - constructor(protected http: HttpClient, private applicationConfigService: ApplicationConfigService) {} public getPage(path: string): Observable<EditorialPage> { - const parameters = new HttpParams().set('path', path); - const resp = this.http.get<EditorialPage>(this.pageResourceURL, {params: parameters,}); + const resp = this.http.get<EditorialPage>(this.pageResourceURL, { params: parameters }); return resp; - } - + public getAttachmentURL(path: string): Observable<string> { const parameters = new HttpParams().set('path', path); - const resp = this.http.get<string>(this.attachmentResourceURL, {params: parameters,}); + const resp = this.http.get<string>(this.attachmentResourceURL, { params: parameters }); return resp; - } + } -/** + /** for admins only */ public resetCache(): Observable<string> { - const resp = this.http.delete<string>(this.pageResourceURL); return resp; - } } diff --git a/src/main/webapp/app/shared/service/plugin-service.ts b/src/main/webapp/app/shared/service/plugin-service.ts index 285d3b8f92943435aa0a8533c707018c56109b88..09e113f094a78f09303d453e9199dd13eae078ec 100644 --- a/src/main/webapp/app/shared/service/plugin-service.ts +++ b/src/main/webapp/app/shared/service/plugin-service.ts @@ -14,9 +14,7 @@ export class PluginService { constructor(protected http: HttpClient, private applicationConfigService: ApplicationConfigService) {} - public getRedirectLink(basketInfo: ShoppingBasketInfo ): Observable<ShoppingBasketRedirectInfoDTO> { + public getRedirectLink(basketInfo: ShoppingBasketInfo): Observable<ShoppingBasketRedirectInfoDTO> { return this.http.post<ShoppingBasketRedirectInfoDTO>(this.resourcePluginRedirectService, basketInfo); } - } - diff --git a/src/main/webapp/app/teaserContent/teaserContent.component.html b/src/main/webapp/app/teaserContent/teaserContent.component.html index 2b741f6d7109f566ec05f8a4877a6d2a1e2d9e90..79e11528c25b4e2cb2ba0240014bd4c580e02b3c 100644 --- a/src/main/webapp/app/teaserContent/teaserContent.component.html +++ b/src/main/webapp/app/teaserContent/teaserContent.component.html @@ -1,34 +1,46 @@ -<table aria-describedby="word clouds" style="width: 100%;"> +<table aria-describedby="word clouds" style="width: 100%"> <colgroup> - <col span="1" style="width: 33%;"> - <col span="1" style="width: 33%;"> - <col span="1" style="width: 33%;"> + <col span="1" style="width: 33%" /> + <col span="1" style="width: 33%" /> + <col span="1" style="width: 33%" /> </colgroup> <thead> <tr> - <th style="text-align: center" scope="col">{{'teaser.headings.keywords'|translate}}</th> - <th style="text-align: center" scope="col">{{'teaser.headings.programmingLanguages'|translate}}</th> - <th style="text-align: center" scope="col">{{'teaser.headings.contributors'|translate}}</th> + <th style="text-align: center" scope="col">{{ 'teaser.headings.keywords' | translate }}</th> + <th style="text-align: center" scope="col">{{ 'teaser.headings.programmingLanguages' | translate }}</th> + <th style="text-align: center" scope="col">{{ 'teaser.headings.contributors' | translate }}</th> </tr> </thead> <tbody> <tr> <td data-th="Keywords"> - <angular-tag-cloud [data]="keywordCloudData" [config]="options" + <angular-tag-cloud + [data]="keywordCloudData" + [config]="options" class="teaserCloud" - (clicked)="onKeywordClick($event)" class="teaserCloud"> + (clicked)="onKeywordClick($event)" + class="teaserCloud" + > </angular-tag-cloud> </td> <td data-th="Programming languages"> - <angular-tag-cloud [data]="programmingLanguageCloudData" [config]="options" + <angular-tag-cloud + [data]="programmingLanguageCloudData" + [config]="options" + class="teaserCloud" + (clicked)="onProgrammingLanguageClick($event)" class="teaserCloud" - (clicked)="onProgrammingLanguageClick($event)" class="teaserCloud"> + > </angular-tag-cloud> </td> <td data-th="Contributors"> - <angular-tag-cloud [data]="contributorCloudData" [config]="options" + <angular-tag-cloud + [data]="contributorCloudData" + [config]="options" + class="teaserCloud" + (clicked)="onContributorClick($event)" class="teaserCloud" - (clicked)="onContributorClick($event)" class="teaserCloud"> + > </angular-tag-cloud> </td> </tr> diff --git a/src/main/webapp/content/js/bootstrap4.5.2.min.js b/src/main/webapp/content/js/bootstrap4.5.2.min.js index ef4d9cbd6ab1bf3a1bd86127433eab330a429699..52d0749a200aeea65daf8973efa49f8f0e43aca9 100644 --- a/src/main/webapp/content/js/bootstrap4.5.2.min.js +++ b/src/main/webapp/content/js/bootstrap4.5.2.min.js @@ -1,7 +1,2305 @@ /*! - * Bootstrap v4.5.2 (https://getbootstrap.com/) - * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).bootstrap={},t.jQuery,t.Popper)}(this,(function(t,e,n){"use strict";function i(t,e){for(var n=0;n<e.length;n++){var i=e[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(t,i.key,i)}}function o(t,e,n){return e&&i(t.prototype,e),n&&i(t,n),t}function s(){return(s=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(t[i]=n[i])}return t}).apply(this,arguments)}e=e&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e,n=n&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n;function r(t){var n=this,i=!1;return e(this).one(a.TRANSITION_END,(function(){i=!0})),setTimeout((function(){i||a.triggerTransitionEnd(n)}),t),this}var a={TRANSITION_END:"bsTransitionEnd",getUID:function(t){do{t+=~~(1e6*Math.random())}while(document.getElementById(t));return t},getSelectorFromElement:function(t){var e=t.getAttribute("data-target");if(!e||"#"===e){var n=t.getAttribute("href");e=n&&"#"!==n?n.trim():""}try{return document.querySelector(e)?e:null}catch(t){return null}},getTransitionDurationFromElement:function(t){if(!t)return 0;var n=e(t).css("transition-duration"),i=e(t).css("transition-delay"),o=parseFloat(n),s=parseFloat(i);return o||s?(n=n.split(",")[0],i=i.split(",")[0],1e3*(parseFloat(n)+parseFloat(i))):0},reflow:function(t){return t.offsetHeight},triggerTransitionEnd:function(t){e(t).trigger("transitionend")},supportsTransitionEnd:function(){return Boolean("transitionend")},isElement:function(t){return(t[0]||t).nodeType},typeCheckConfig:function(t,e,n){for(var i in n)if(Object.prototype.hasOwnProperty.call(n,i)){var o=n[i],s=e[i],r=s&&a.isElement(s)?"element":null===(l=s)||"undefined"==typeof l?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();if(!new RegExp(o).test(r))throw new Error(t.toUpperCase()+': Option "'+i+'" provided type "'+r+'" but expected type "'+o+'".')}var l},findShadowRoot:function(t){if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){var e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?a.findShadowRoot(t.parentNode):null},jQueryDetection:function(){if("undefined"==typeof e)throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript.");var t=e.fn.jquery.split(" ")[0].split(".");if(t[0]<2&&t[1]<9||1===t[0]&&9===t[1]&&t[2]<1||t[0]>=4)throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0")}};a.jQueryDetection(),e.fn.emulateTransitionEnd=r,e.event.special[a.TRANSITION_END]={bindType:"transitionend",delegateType:"transitionend",handle:function(t){if(e(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}};var l="alert",c=e.fn[l],h=function(){function t(t){this._element=t}var n=t.prototype;return n.close=function(t){var e=this._element;t&&(e=this._getRootElement(t)),this._triggerCloseEvent(e).isDefaultPrevented()||this._removeElement(e)},n.dispose=function(){e.removeData(this._element,"bs.alert"),this._element=null},n._getRootElement=function(t){var n=a.getSelectorFromElement(t),i=!1;return n&&(i=document.querySelector(n)),i||(i=e(t).closest(".alert")[0]),i},n._triggerCloseEvent=function(t){var n=e.Event("close.bs.alert");return e(t).trigger(n),n},n._removeElement=function(t){var n=this;if(e(t).removeClass("show"),e(t).hasClass("fade")){var i=a.getTransitionDurationFromElement(t);e(t).one(a.TRANSITION_END,(function(e){return n._destroyElement(t,e)})).emulateTransitionEnd(i)}else this._destroyElement(t)},n._destroyElement=function(t){e(t).detach().trigger("closed.bs.alert").remove()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.alert");o||(o=new t(this),i.data("bs.alert",o)),"close"===n&&o[n](this)}))},t._handleDismiss=function(t){return function(e){e&&e.preventDefault(),t.close(this)}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.alert.data-api",'[data-dismiss="alert"]',h._handleDismiss(new h)),e.fn[l]=h._jQueryInterface,e.fn[l].Constructor=h,e.fn[l].noConflict=function(){return e.fn[l]=c,h._jQueryInterface};var u=e.fn.button,d=function(){function t(t){this._element=t}var n=t.prototype;return n.toggle=function(){var t=!0,n=!0,i=e(this._element).closest('[data-toggle="buttons"]')[0];if(i){var o=this._element.querySelector('input:not([type="hidden"])');if(o){if("radio"===o.type)if(o.checked&&this._element.classList.contains("active"))t=!1;else{var s=i.querySelector(".active");s&&e(s).removeClass("active")}t&&("checkbox"!==o.type&&"radio"!==o.type||(o.checked=!this._element.classList.contains("active")),e(o).trigger("change")),o.focus(),n=!1}}this._element.hasAttribute("disabled")||this._element.classList.contains("disabled")||(n&&this._element.setAttribute("aria-pressed",!this._element.classList.contains("active")),t&&e(this._element).toggleClass("active"))},n.dispose=function(){e.removeData(this._element,"bs.button"),this._element=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.button");i||(i=new t(this),e(this).data("bs.button",i)),"toggle"===n&&i[n]()}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=t.target,i=n;if(e(n).hasClass("btn")||(n=e(n).closest(".btn")[0]),!n||n.hasAttribute("disabled")||n.classList.contains("disabled"))t.preventDefault();else{var o=n.querySelector('input:not([type="hidden"])');if(o&&(o.hasAttribute("disabled")||o.classList.contains("disabled")))return void t.preventDefault();("LABEL"!==i.tagName||o&&"checkbox"!==o.type)&&d._jQueryInterface.call(e(n),"toggle")}})).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',(function(t){var n=e(t.target).closest(".btn")[0];e(n).toggleClass("focus",/^focus(in)?$/.test(t.type))})),e(window).on("load.bs.button.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')),e=0,n=t.length;e<n;e++){var i=t[e],o=i.querySelector('input:not([type="hidden"])');o.checked||o.hasAttribute("checked")?i.classList.add("active"):i.classList.remove("active")}for(var s=0,r=(t=[].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length;s<r;s++){var a=t[s];"true"===a.getAttribute("aria-pressed")?a.classList.add("active"):a.classList.remove("active")}})),e.fn.button=d._jQueryInterface,e.fn.button.Constructor=d,e.fn.button.noConflict=function(){return e.fn.button=u,d._jQueryInterface};var f="carousel",g=".bs.carousel",m=e.fn[f],p={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},_={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},v={TOUCH:"touch",PEN:"pen"},b=function(){function t(t,e){this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._element=t,this._indicatorsElement=this._element.querySelector(".carousel-indicators"),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent||window.MSPointerEvent),this._addEventListeners()}var n=t.prototype;return n.next=function(){this._isSliding||this._slide("next")},n.nextWhenVisible=function(){!document.hidden&&e(this._element).is(":visible")&&"hidden"!==e(this._element).css("visibility")&&this.next()},n.prev=function(){this._isSliding||this._slide("prev")},n.pause=function(t){t||(this._isPaused=!0),this._element.querySelector(".carousel-item-next, .carousel-item-prev")&&(a.triggerTransitionEnd(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null},n.cycle=function(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config.interval&&!this._isPaused&&(this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))},n.to=function(t){var n=this;this._activeElement=this._element.querySelector(".active.carousel-item");var i=this._getItemIndex(this._activeElement);if(!(t>this._items.length-1||t<0))if(this._isSliding)e(this._element).one("slid.bs.carousel",(function(){return n.to(t)}));else{if(i===t)return this.pause(),void this.cycle();var o=t>i?"next":"prev";this._slide(o,this._items[t])}},n.dispose=function(){e(this._element).off(g),e.removeData(this._element,"bs.carousel"),this._items=null,this._config=null,this._element=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null},n._getConfig=function(t){return t=s({},p,t),a.typeCheckConfig(f,t,_),t},n._handleSwipe=function(){var t=Math.abs(this.touchDeltaX);if(!(t<=40)){var e=t/this.touchDeltaX;this.touchDeltaX=0,e>0&&this.prev(),e<0&&this.next()}},n._addEventListeners=function(){var t=this;this._config.keyboard&&e(this._element).on("keydown.bs.carousel",(function(e){return t._keydown(e)})),"hover"===this._config.pause&&e(this._element).on("mouseenter.bs.carousel",(function(e){return t.pause(e)})).on("mouseleave.bs.carousel",(function(e){return t.cycle(e)})),this._config.touch&&this._addTouchEventListeners()},n._addTouchEventListeners=function(){var t=this;if(this._touchSupported){var n=function(e){t._pointerEvent&&v[e.originalEvent.pointerType.toUpperCase()]?t.touchStartX=e.originalEvent.clientX:t._pointerEvent||(t.touchStartX=e.originalEvent.touches[0].clientX)},i=function(e){t._pointerEvent&&v[e.originalEvent.pointerType.toUpperCase()]&&(t.touchDeltaX=e.originalEvent.clientX-t.touchStartX),t._handleSwipe(),"hover"===t._config.pause&&(t.pause(),t.touchTimeout&&clearTimeout(t.touchTimeout),t.touchTimeout=setTimeout((function(e){return t.cycle(e)}),500+t._config.interval))};e(this._element.querySelectorAll(".carousel-item img")).on("dragstart.bs.carousel",(function(t){return t.preventDefault()})),this._pointerEvent?(e(this._element).on("pointerdown.bs.carousel",(function(t){return n(t)})),e(this._element).on("pointerup.bs.carousel",(function(t){return i(t)})),this._element.classList.add("pointer-event")):(e(this._element).on("touchstart.bs.carousel",(function(t){return n(t)})),e(this._element).on("touchmove.bs.carousel",(function(e){return function(e){e.originalEvent.touches&&e.originalEvent.touches.length>1?t.touchDeltaX=0:t.touchDeltaX=e.originalEvent.touches[0].clientX-t.touchStartX}(e)})),e(this._element).on("touchend.bs.carousel",(function(t){return i(t)})))}},n._keydown=function(t){if(!/input|textarea/i.test(t.target.tagName))switch(t.which){case 37:t.preventDefault(),this.prev();break;case 39:t.preventDefault(),this.next()}},n._getItemIndex=function(t){return this._items=t&&t.parentNode?[].slice.call(t.parentNode.querySelectorAll(".carousel-item")):[],this._items.indexOf(t)},n._getItemByDirection=function(t,e){var n="next"===t,i="prev"===t,o=this._getItemIndex(e),s=this._items.length-1;if((i&&0===o||n&&o===s)&&!this._config.wrap)return e;var r=(o+("prev"===t?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]},n._triggerSlideEvent=function(t,n){var i=this._getItemIndex(t),o=this._getItemIndex(this._element.querySelector(".active.carousel-item")),s=e.Event("slide.bs.carousel",{relatedTarget:t,direction:n,from:o,to:i});return e(this._element).trigger(s),s},n._setActiveIndicatorElement=function(t){if(this._indicatorsElement){var n=[].slice.call(this._indicatorsElement.querySelectorAll(".active"));e(n).removeClass("active");var i=this._indicatorsElement.children[this._getItemIndex(t)];i&&e(i).addClass("active")}},n._slide=function(t,n){var i,o,s,r=this,l=this._element.querySelector(".active.carousel-item"),c=this._getItemIndex(l),h=n||l&&this._getItemByDirection(t,l),u=this._getItemIndex(h),d=Boolean(this._interval);if("next"===t?(i="carousel-item-left",o="carousel-item-next",s="left"):(i="carousel-item-right",o="carousel-item-prev",s="right"),h&&e(h).hasClass("active"))this._isSliding=!1;else if(!this._triggerSlideEvent(h,s).isDefaultPrevented()&&l&&h){this._isSliding=!0,d&&this.pause(),this._setActiveIndicatorElement(h);var f=e.Event("slid.bs.carousel",{relatedTarget:h,direction:s,from:c,to:u});if(e(this._element).hasClass("slide")){e(h).addClass(o),a.reflow(h),e(l).addClass(i),e(h).addClass(i);var g=parseInt(h.getAttribute("data-interval"),10);g?(this._config.defaultInterval=this._config.defaultInterval||this._config.interval,this._config.interval=g):this._config.interval=this._config.defaultInterval||this._config.interval;var m=a.getTransitionDurationFromElement(l);e(l).one(a.TRANSITION_END,(function(){e(h).removeClass(i+" "+o).addClass("active"),e(l).removeClass("active "+o+" "+i),r._isSliding=!1,setTimeout((function(){return e(r._element).trigger(f)}),0)})).emulateTransitionEnd(m)}else e(l).removeClass("active"),e(h).addClass("active"),this._isSliding=!1,e(this._element).trigger(f);d&&this.cycle()}},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.carousel"),o=s({},p,e(this).data());"object"==typeof n&&(o=s({},o,n));var r="string"==typeof n?n:o.slide;if(i||(i=new t(this,o),e(this).data("bs.carousel",i)),"number"==typeof n)i.to(n);else if("string"==typeof r){if("undefined"==typeof i[r])throw new TypeError('No method named "'+r+'"');i[r]()}else o.interval&&o.ride&&(i.pause(),i.cycle())}))},t._dataApiClickHandler=function(n){var i=a.getSelectorFromElement(this);if(i){var o=e(i)[0];if(o&&e(o).hasClass("carousel")){var r=s({},e(o).data(),e(this).data()),l=this.getAttribute("data-slide-to");l&&(r.interval=!1),t._jQueryInterface.call(e(o),r),l&&e(o).data("bs.carousel").to(l),n.preventDefault()}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return p}}]),t}();e(document).on("click.bs.carousel.data-api","[data-slide], [data-slide-to]",b._dataApiClickHandler),e(window).on("load.bs.carousel.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-ride="carousel"]')),n=0,i=t.length;n<i;n++){var o=e(t[n]);b._jQueryInterface.call(o,o.data())}})),e.fn[f]=b._jQueryInterface,e.fn[f].Constructor=b,e.fn[f].noConflict=function(){return e.fn[f]=m,b._jQueryInterface};var y="collapse",E=e.fn[y],w={toggle:!0,parent:""},T={toggle:"boolean",parent:"(string|element)"},C=function(){function t(t,e){this._isTransitioning=!1,this._element=t,this._config=this._getConfig(e),this._triggerArray=[].slice.call(document.querySelectorAll('[data-toggle="collapse"][href="#'+t.id+'"],[data-toggle="collapse"][data-target="#'+t.id+'"]'));for(var n=[].slice.call(document.querySelectorAll('[data-toggle="collapse"]')),i=0,o=n.length;i<o;i++){var s=n[i],r=a.getSelectorFromElement(s),l=[].slice.call(document.querySelectorAll(r)).filter((function(e){return e===t}));null!==r&&l.length>0&&(this._selector=r,this._triggerArray.push(s))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}var n=t.prototype;return n.toggle=function(){e(this._element).hasClass("show")?this.hide():this.show()},n.show=function(){var n,i,o=this;if(!this._isTransitioning&&!e(this._element).hasClass("show")&&(this._parent&&0===(n=[].slice.call(this._parent.querySelectorAll(".show, .collapsing")).filter((function(t){return"string"==typeof o._config.parent?t.getAttribute("data-parent")===o._config.parent:t.classList.contains("collapse")}))).length&&(n=null),!(n&&(i=e(n).not(this._selector).data("bs.collapse"))&&i._isTransitioning))){var s=e.Event("show.bs.collapse");if(e(this._element).trigger(s),!s.isDefaultPrevented()){n&&(t._jQueryInterface.call(e(n).not(this._selector),"hide"),i||e(n).data("bs.collapse",null));var r=this._getDimension();e(this._element).removeClass("collapse").addClass("collapsing"),this._element.style[r]=0,this._triggerArray.length&&e(this._triggerArray).removeClass("collapsed").attr("aria-expanded",!0),this.setTransitioning(!0);var l="scroll"+(r[0].toUpperCase()+r.slice(1)),c=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(){e(o._element).removeClass("collapsing").addClass("collapse show"),o._element.style[r]="",o.setTransitioning(!1),e(o._element).trigger("shown.bs.collapse")})).emulateTransitionEnd(c),this._element.style[r]=this._element[l]+"px"}}},n.hide=function(){var t=this;if(!this._isTransitioning&&e(this._element).hasClass("show")){var n=e.Event("hide.bs.collapse");if(e(this._element).trigger(n),!n.isDefaultPrevented()){var i=this._getDimension();this._element.style[i]=this._element.getBoundingClientRect()[i]+"px",a.reflow(this._element),e(this._element).addClass("collapsing").removeClass("collapse show");var o=this._triggerArray.length;if(o>0)for(var s=0;s<o;s++){var r=this._triggerArray[s],l=a.getSelectorFromElement(r);if(null!==l)e([].slice.call(document.querySelectorAll(l))).hasClass("show")||e(r).addClass("collapsed").attr("aria-expanded",!1)}this.setTransitioning(!0);this._element.style[i]="";var c=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(){t.setTransitioning(!1),e(t._element).removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")})).emulateTransitionEnd(c)}}},n.setTransitioning=function(t){this._isTransitioning=t},n.dispose=function(){e.removeData(this._element,"bs.collapse"),this._config=null,this._parent=null,this._element=null,this._triggerArray=null,this._isTransitioning=null},n._getConfig=function(t){return(t=s({},w,t)).toggle=Boolean(t.toggle),a.typeCheckConfig(y,t,T),t},n._getDimension=function(){return e(this._element).hasClass("width")?"width":"height"},n._getParent=function(){var n,i=this;a.isElement(this._config.parent)?(n=this._config.parent,"undefined"!=typeof this._config.parent.jquery&&(n=this._config.parent[0])):n=document.querySelector(this._config.parent);var o='[data-toggle="collapse"][data-parent="'+this._config.parent+'"]',s=[].slice.call(n.querySelectorAll(o));return e(s).each((function(e,n){i._addAriaAndCollapsedClass(t._getTargetFromElement(n),[n])})),n},n._addAriaAndCollapsedClass=function(t,n){var i=e(t).hasClass("show");n.length&&e(n).toggleClass("collapsed",!i).attr("aria-expanded",i)},t._getTargetFromElement=function(t){var e=a.getSelectorFromElement(t);return e?document.querySelector(e):null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.collapse"),r=s({},w,i.data(),"object"==typeof n&&n?n:{});if(!o&&r.toggle&&"string"==typeof n&&/show|hide/.test(n)&&(r.toggle=!1),o||(o=new t(this,r),i.data("bs.collapse",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return w}}]),t}();e(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',(function(t){"A"===t.currentTarget.tagName&&t.preventDefault();var n=e(this),i=a.getSelectorFromElement(this),o=[].slice.call(document.querySelectorAll(i));e(o).each((function(){var t=e(this),i=t.data("bs.collapse")?"toggle":n.data();C._jQueryInterface.call(t,i)}))})),e.fn[y]=C._jQueryInterface,e.fn[y].Constructor=C,e.fn[y].noConflict=function(){return e.fn[y]=E,C._jQueryInterface};var S="dropdown",k=e.fn[S],D=new RegExp("38|40|27"),N={offset:0,flip:!0,boundary:"scrollParent",reference:"toggle",display:"dynamic",popperConfig:null},A={offset:"(number|string|function)",flip:"boolean",boundary:"(string|element)",reference:"(string|element)",display:"string",popperConfig:"(null|object)"},I=function(){function t(t,e){this._element=t,this._popper=null,this._config=this._getConfig(e),this._menu=this._getMenuElement(),this._inNavbar=this._detectNavbar(),this._addEventListeners()}var i=t.prototype;return i.toggle=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")){var n=e(this._menu).hasClass("show");t._clearMenus(),n||this.show(!0)}},i.show=function(i){if(void 0===i&&(i=!1),!(this._element.disabled||e(this._element).hasClass("disabled")||e(this._menu).hasClass("show"))){var o={relatedTarget:this._element},s=e.Event("show.bs.dropdown",o),r=t._getParentFromElement(this._element);if(e(r).trigger(s),!s.isDefaultPrevented()){if(!this._inNavbar&&i){if("undefined"==typeof n)throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)");var l=this._element;"parent"===this._config.reference?l=r:a.isElement(this._config.reference)&&(l=this._config.reference,"undefined"!=typeof this._config.reference.jquery&&(l=this._config.reference[0])),"scrollParent"!==this._config.boundary&&e(r).addClass("position-static"),this._popper=new n(l,this._menu,this._getPopperConfig())}"ontouchstart"in document.documentElement&&0===e(r).closest(".navbar-nav").length&&e(document.body).children().on("mouseover",null,e.noop),this._element.focus(),this._element.setAttribute("aria-expanded",!0),e(this._menu).toggleClass("show"),e(r).toggleClass("show").trigger(e.Event("shown.bs.dropdown",o))}}},i.hide=function(){if(!this._element.disabled&&!e(this._element).hasClass("disabled")&&e(this._menu).hasClass("show")){var n={relatedTarget:this._element},i=e.Event("hide.bs.dropdown",n),o=t._getParentFromElement(this._element);e(o).trigger(i),i.isDefaultPrevented()||(this._popper&&this._popper.destroy(),e(this._menu).toggleClass("show"),e(o).toggleClass("show").trigger(e.Event("hidden.bs.dropdown",n)))}},i.dispose=function(){e.removeData(this._element,"bs.dropdown"),e(this._element).off(".bs.dropdown"),this._element=null,this._menu=null,null!==this._popper&&(this._popper.destroy(),this._popper=null)},i.update=function(){this._inNavbar=this._detectNavbar(),null!==this._popper&&this._popper.scheduleUpdate()},i._addEventListeners=function(){var t=this;e(this._element).on("click.bs.dropdown",(function(e){e.preventDefault(),e.stopPropagation(),t.toggle()}))},i._getConfig=function(t){return t=s({},this.constructor.Default,e(this._element).data(),t),a.typeCheckConfig(S,t,this.constructor.DefaultType),t},i._getMenuElement=function(){if(!this._menu){var e=t._getParentFromElement(this._element);e&&(this._menu=e.querySelector(".dropdown-menu"))}return this._menu},i._getPlacement=function(){var t=e(this._element.parentNode),n="bottom-start";return t.hasClass("dropup")?n=e(this._menu).hasClass("dropdown-menu-right")?"top-end":"top-start":t.hasClass("dropright")?n="right-start":t.hasClass("dropleft")?n="left-start":e(this._menu).hasClass("dropdown-menu-right")&&(n="bottom-end"),n},i._detectNavbar=function(){return e(this._element).closest(".navbar").length>0},i._getOffset=function(){var t=this,e={};return"function"==typeof this._config.offset?e.fn=function(e){return e.offsets=s({},e.offsets,t._config.offset(e.offsets,t._element)||{}),e}:e.offset=this._config.offset,e},i._getPopperConfig=function(){var t={placement:this._getPlacement(),modifiers:{offset:this._getOffset(),flip:{enabled:this._config.flip},preventOverflow:{boundariesElement:this._config.boundary}}};return"static"===this._config.display&&(t.modifiers.applyStyle={enabled:!1}),s({},t,this._config.popperConfig)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.dropdown");if(i||(i=new t(this,"object"==typeof n?n:null),e(this).data("bs.dropdown",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},t._clearMenus=function(n){if(!n||3!==n.which&&("keyup"!==n.type||9===n.which))for(var i=[].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')),o=0,s=i.length;o<s;o++){var r=t._getParentFromElement(i[o]),a=e(i[o]).data("bs.dropdown"),l={relatedTarget:i[o]};if(n&&"click"===n.type&&(l.clickEvent=n),a){var c=a._menu;if(e(r).hasClass("show")&&!(n&&("click"===n.type&&/input|textarea/i.test(n.target.tagName)||"keyup"===n.type&&9===n.which)&&e.contains(r,n.target))){var h=e.Event("hide.bs.dropdown",l);e(r).trigger(h),h.isDefaultPrevented()||("ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),i[o].setAttribute("aria-expanded","false"),a._popper&&a._popper.destroy(),e(c).removeClass("show"),e(r).removeClass("show").trigger(e.Event("hidden.bs.dropdown",l)))}}}},t._getParentFromElement=function(t){var e,n=a.getSelectorFromElement(t);return n&&(e=document.querySelector(n)),e||t.parentNode},t._dataApiKeydownHandler=function(n){if(!(/input|textarea/i.test(n.target.tagName)?32===n.which||27!==n.which&&(40!==n.which&&38!==n.which||e(n.target).closest(".dropdown-menu").length):!D.test(n.which))&&!this.disabled&&!e(this).hasClass("disabled")){var i=t._getParentFromElement(this),o=e(i).hasClass("show");if(o||27!==n.which){if(n.preventDefault(),n.stopPropagation(),!o||o&&(27===n.which||32===n.which))return 27===n.which&&e(i.querySelector('[data-toggle="dropdown"]')).trigger("focus"),void e(this).trigger("click");var s=[].slice.call(i.querySelectorAll(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)")).filter((function(t){return e(t).is(":visible")}));if(0!==s.length){var r=s.indexOf(n.target);38===n.which&&r>0&&r--,40===n.which&&r<s.length-1&&r++,r<0&&(r=0),s[r].focus()}}}},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return N}},{key:"DefaultType",get:function(){return A}}]),t}();e(document).on("keydown.bs.dropdown.data-api",'[data-toggle="dropdown"]',I._dataApiKeydownHandler).on("keydown.bs.dropdown.data-api",".dropdown-menu",I._dataApiKeydownHandler).on("click.bs.dropdown.data-api keyup.bs.dropdown.data-api",I._clearMenus).on("click.bs.dropdown.data-api",'[data-toggle="dropdown"]',(function(t){t.preventDefault(),t.stopPropagation(),I._jQueryInterface.call(e(this),"toggle")})).on("click.bs.dropdown.data-api",".dropdown form",(function(t){t.stopPropagation()})),e.fn[S]=I._jQueryInterface,e.fn[S].Constructor=I,e.fn[S].noConflict=function(){return e.fn[S]=k,I._jQueryInterface};var O=e.fn.modal,j={backdrop:!0,keyboard:!0,focus:!0,show:!0},x={backdrop:"(boolean|string)",keyboard:"boolean",focus:"boolean",show:"boolean"},P=function(){function t(t,e){this._config=this._getConfig(e),this._element=t,this._dialog=t.querySelector(".modal-dialog"),this._backdrop=null,this._isShown=!1,this._isBodyOverflowing=!1,this._ignoreBackdropClick=!1,this._isTransitioning=!1,this._scrollbarWidth=0}var n=t.prototype;return n.toggle=function(t){return this._isShown?this.hide():this.show(t)},n.show=function(t){var n=this;if(!this._isShown&&!this._isTransitioning){e(this._element).hasClass("fade")&&(this._isTransitioning=!0);var i=e.Event("show.bs.modal",{relatedTarget:t});e(this._element).trigger(i),this._isShown||i.isDefaultPrevented()||(this._isShown=!0,this._checkScrollbar(),this._setScrollbar(),this._adjustDialog(),this._setEscapeEvent(),this._setResizeEvent(),e(this._element).on("click.dismiss.bs.modal",'[data-dismiss="modal"]',(function(t){return n.hide(t)})),e(this._dialog).on("mousedown.dismiss.bs.modal",(function(){e(n._element).one("mouseup.dismiss.bs.modal",(function(t){e(t.target).is(n._element)&&(n._ignoreBackdropClick=!0)}))})),this._showBackdrop((function(){return n._showElement(t)})))}},n.hide=function(t){var n=this;if(t&&t.preventDefault(),this._isShown&&!this._isTransitioning){var i=e.Event("hide.bs.modal");if(e(this._element).trigger(i),this._isShown&&!i.isDefaultPrevented()){this._isShown=!1;var o=e(this._element).hasClass("fade");if(o&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),e(document).off("focusin.bs.modal"),e(this._element).removeClass("show"),e(this._element).off("click.dismiss.bs.modal"),e(this._dialog).off("mousedown.dismiss.bs.modal"),o){var s=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,(function(t){return n._hideModal(t)})).emulateTransitionEnd(s)}else this._hideModal()}}},n.dispose=function(){[window,this._element,this._dialog].forEach((function(t){return e(t).off(".bs.modal")})),e(document).off("focusin.bs.modal"),e.removeData(this._element,"bs.modal"),this._config=null,this._element=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null},n.handleUpdate=function(){this._adjustDialog()},n._getConfig=function(t){return t=s({},j,t),a.typeCheckConfig("modal",t,x),t},n._triggerBackdropTransition=function(){var t=this;if("static"===this._config.backdrop){var n=e.Event("hidePrevented.bs.modal");if(e(this._element).trigger(n),n.defaultPrevented)return;var i=this._element.scrollHeight>document.documentElement.clientHeight;i||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");var o=a.getTransitionDurationFromElement(this._dialog);e(this._element).off(a.TRANSITION_END),e(this._element).one(a.TRANSITION_END,(function(){t._element.classList.remove("modal-static"),i||e(t._element).one(a.TRANSITION_END,(function(){t._element.style.overflowY=""})).emulateTransitionEnd(t._element,o)})).emulateTransitionEnd(o),this._element.focus()}else this.hide()},n._showElement=function(t){var n=this,i=e(this._element).hasClass("fade"),o=this._dialog?this._dialog.querySelector(".modal-body"):null;this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),e(this._dialog).hasClass("modal-dialog-scrollable")&&o?o.scrollTop=0:this._element.scrollTop=0,i&&a.reflow(this._element),e(this._element).addClass("show"),this._config.focus&&this._enforceFocus();var s=e.Event("shown.bs.modal",{relatedTarget:t}),r=function(){n._config.focus&&n._element.focus(),n._isTransitioning=!1,e(n._element).trigger(s)};if(i){var l=a.getTransitionDurationFromElement(this._dialog);e(this._dialog).one(a.TRANSITION_END,r).emulateTransitionEnd(l)}else r()},n._enforceFocus=function(){var t=this;e(document).off("focusin.bs.modal").on("focusin.bs.modal",(function(n){document!==n.target&&t._element!==n.target&&0===e(t._element).has(n.target).length&&t._element.focus()}))},n._setEscapeEvent=function(){var t=this;this._isShown?e(this._element).on("keydown.dismiss.bs.modal",(function(e){t._config.keyboard&&27===e.which?(e.preventDefault(),t.hide()):t._config.keyboard||27!==e.which||t._triggerBackdropTransition()})):this._isShown||e(this._element).off("keydown.dismiss.bs.modal")},n._setResizeEvent=function(){var t=this;this._isShown?e(window).on("resize.bs.modal",(function(e){return t.handleUpdate(e)})):e(window).off("resize.bs.modal")},n._hideModal=function(){var t=this;this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop((function(){e(document.body).removeClass("modal-open"),t._resetAdjustments(),t._resetScrollbar(),e(t._element).trigger("hidden.bs.modal")}))},n._removeBackdrop=function(){this._backdrop&&(e(this._backdrop).remove(),this._backdrop=null)},n._showBackdrop=function(t){var n=this,i=e(this._element).hasClass("fade")?"fade":"";if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",i&&this._backdrop.classList.add(i),e(this._backdrop).appendTo(document.body),e(this._element).on("click.dismiss.bs.modal",(function(t){n._ignoreBackdropClick?n._ignoreBackdropClick=!1:t.target===t.currentTarget&&n._triggerBackdropTransition()})),i&&a.reflow(this._backdrop),e(this._backdrop).addClass("show"),!t)return;if(!i)return void t();var o=a.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(a.TRANSITION_END,t).emulateTransitionEnd(o)}else if(!this._isShown&&this._backdrop){e(this._backdrop).removeClass("show");var s=function(){n._removeBackdrop(),t&&t()};if(e(this._element).hasClass("fade")){var r=a.getTransitionDurationFromElement(this._backdrop);e(this._backdrop).one(a.TRANSITION_END,s).emulateTransitionEnd(r)}else s()}else t&&t()},n._adjustDialog=function(){var t=this._element.scrollHeight>document.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},n._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},n._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)<window.innerWidth,this._scrollbarWidth=this._getScrollbarWidth()},n._setScrollbar=function(){var t=this;if(this._isBodyOverflowing){var n=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top")),i=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(n,i){var o=i.style.paddingRight,s=e(i).css("padding-right");e(i).data("padding-right",o).css("padding-right",parseFloat(s)+t._scrollbarWidth+"px")})),e(i).each((function(n,i){var o=i.style.marginRight,s=e(i).css("margin-right");e(i).data("margin-right",o).css("margin-right",parseFloat(s)-t._scrollbarWidth+"px")}));var o=document.body.style.paddingRight,s=e(document.body).css("padding-right");e(document.body).data("padding-right",o).css("padding-right",parseFloat(s)+this._scrollbarWidth+"px")}e(document.body).addClass("modal-open")},n._resetScrollbar=function(){var t=[].slice.call(document.querySelectorAll(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top"));e(t).each((function(t,n){var i=e(n).data("padding-right");e(n).removeData("padding-right"),n.style.paddingRight=i||""}));var n=[].slice.call(document.querySelectorAll(".sticky-top"));e(n).each((function(t,n){var i=e(n).data("margin-right");"undefined"!=typeof i&&e(n).css("margin-right",i).removeData("margin-right")}));var i=e(document.body).data("padding-right");e(document.body).removeData("padding-right"),document.body.style.paddingRight=i||""},n._getScrollbarWidth=function(){var t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);var e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e},t._jQueryInterface=function(n,i){return this.each((function(){var o=e(this).data("bs.modal"),r=s({},j,e(this).data(),"object"==typeof n&&n?n:{});if(o||(o=new t(this,r),e(this).data("bs.modal",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](i)}else r.show&&o.show(i)}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return j}}]),t}();e(document).on("click.bs.modal.data-api",'[data-toggle="modal"]',(function(t){var n,i=this,o=a.getSelectorFromElement(this);o&&(n=document.querySelector(o));var r=e(n).data("bs.modal")?"toggle":s({},e(n).data(),e(this).data());"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault();var l=e(n).one("show.bs.modal",(function(t){t.isDefaultPrevented()||l.one("hidden.bs.modal",(function(){e(i).is(":visible")&&i.focus()}))}));P._jQueryInterface.call(e(n),r,this)})),e.fn.modal=P._jQueryInterface,e.fn.modal.Constructor=P,e.fn.modal.noConflict=function(){return e.fn.modal=O,P._jQueryInterface};var R=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],L={"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},q=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi,F=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i;function Q(t,e,n){if(0===t.length)return t;if(n&&"function"==typeof n)return n(t);for(var i=(new window.DOMParser).parseFromString(t,"text/html"),o=Object.keys(e),s=[].slice.call(i.body.querySelectorAll("*")),r=function(t,n){var i=s[t],r=i.nodeName.toLowerCase();if(-1===o.indexOf(i.nodeName.toLowerCase()))return i.parentNode.removeChild(i),"continue";var a=[].slice.call(i.attributes),l=[].concat(e["*"]||[],e[r]||[]);a.forEach((function(t){(function(t,e){var n=t.nodeName.toLowerCase();if(-1!==e.indexOf(n))return-1===R.indexOf(n)||Boolean(t.nodeValue.match(q)||t.nodeValue.match(F));for(var i=e.filter((function(t){return t instanceof RegExp})),o=0,s=i.length;o<s;o++)if(n.match(i[o]))return!0;return!1})(t,l)||i.removeAttribute(t.nodeName)}))},a=0,l=s.length;a<l;a++)r(a);return i.body.innerHTML}var B="tooltip",H=e.fn[B],U=new RegExp("(^|\\s)bs-tooltip\\S+","g"),M=["sanitize","whiteList","sanitizeFn"],W={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string|function)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)",sanitize:"boolean",sanitizeFn:"(null|function)",whiteList:"object",popperConfig:"(null|object)"},V={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"},z={animation:!0,template:'<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:L,popperConfig:null},K={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"},X=function(){function t(t,e){if("undefined"==typeof n)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var i=t.prototype;return i.enable=function(){this._isEnabled=!0},i.disable=function(){this._isEnabled=!1},i.toggleEnabled=function(){this._isEnabled=!this._isEnabled},i.toggle=function(t){if(this._isEnabled)if(t){var n=this.constructor.DATA_KEY,i=e(t.currentTarget).data(n);i||(i=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(n,i)),i._activeTrigger.click=!i._activeTrigger.click,i._isWithActiveTrigger()?i._enter(null,i):i._leave(null,i)}else{if(e(this.getTipElement()).hasClass("show"))return void this._leave(null,this);this._enter(null,this)}},i.dispose=function(){clearTimeout(this._timeout),e.removeData(this.element,this.constructor.DATA_KEY),e(this.element).off(this.constructor.EVENT_KEY),e(this.element).closest(".modal").off("hide.bs.modal",this._hideModalHandler),this.tip&&e(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},i.show=function(){var t=this;if("none"===e(this.element).css("display"))throw new Error("Please use show on visible elements");var i=e.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){e(this.element).trigger(i);var o=a.findShadowRoot(this.element),s=e.contains(null!==o?o:this.element.ownerDocument.documentElement,this.element);if(i.isDefaultPrevented()||!s)return;var r=this.getTipElement(),l=a.getUID(this.constructor.NAME);r.setAttribute("id",l),this.element.setAttribute("aria-describedby",l),this.setContent(),this.config.animation&&e(r).addClass("fade");var c="function"==typeof this.config.placement?this.config.placement.call(this,r,this.element):this.config.placement,h=this._getAttachment(c);this.addAttachmentClass(h);var u=this._getContainer();e(r).data(this.constructor.DATA_KEY,this),e.contains(this.element.ownerDocument.documentElement,this.tip)||e(r).appendTo(u),e(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new n(this.element,r,this._getPopperConfig(h)),e(r).addClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().on("mouseover",null,e.noop);var d=function(){t.config.animation&&t._fixTransition();var n=t._hoverState;t._hoverState=null,e(t.element).trigger(t.constructor.Event.SHOWN),"out"===n&&t._leave(null,t)};if(e(this.tip).hasClass("fade")){var f=a.getTransitionDurationFromElement(this.tip);e(this.tip).one(a.TRANSITION_END,d).emulateTransitionEnd(f)}else d()}},i.hide=function(t){var n=this,i=this.getTipElement(),o=e.Event(this.constructor.Event.HIDE),s=function(){"show"!==n._hoverState&&i.parentNode&&i.parentNode.removeChild(i),n._cleanTipClass(),n.element.removeAttribute("aria-describedby"),e(n.element).trigger(n.constructor.Event.HIDDEN),null!==n._popper&&n._popper.destroy(),t&&t()};if(e(this.element).trigger(o),!o.isDefaultPrevented()){if(e(i).removeClass("show"),"ontouchstart"in document.documentElement&&e(document.body).children().off("mouseover",null,e.noop),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,e(this.tip).hasClass("fade")){var r=a.getTransitionDurationFromElement(i);e(i).one(a.TRANSITION_END,s).emulateTransitionEnd(r)}else s();this._hoverState=""}},i.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},i.isWithContent=function(){return Boolean(this.getTitle())},i.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-tooltip-"+t)},i.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},i.setContent=function(){var t=this.getTipElement();this.setElementContent(e(t.querySelectorAll(".tooltip-inner")),this.getTitle()),e(t).removeClass("fade show")},i.setElementContent=function(t,n){"object"!=typeof n||!n.nodeType&&!n.jquery?this.config.html?(this.config.sanitize&&(n=Q(n,this.config.whiteList,this.config.sanitizeFn)),t.html(n)):t.text(n):this.config.html?e(n).parent().is(t)||t.empty().append(n):t.text(e(n).text())},i.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},i._getPopperConfig=function(t){var e=this;return s({},{placement:t,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:".arrow"},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}},this.config.popperConfig)},i._getOffset=function(){var t=this,e={};return"function"==typeof this.config.offset?e.fn=function(e){return e.offsets=s({},e.offsets,t.config.offset(e.offsets,t.element)||{}),e}:e.offset=this.config.offset,e},i._getContainer=function(){return!1===this.config.container?document.body:a.isElement(this.config.container)?e(this.config.container):e(document).find(this.config.container)},i._getAttachment=function(t){return V[t.toUpperCase()]},i._setListeners=function(){var t=this;this.config.trigger.split(" ").forEach((function(n){if("click"===n)e(t.element).on(t.constructor.Event.CLICK,t.config.selector,(function(e){return t.toggle(e)}));else if("manual"!==n){var i="hover"===n?t.constructor.Event.MOUSEENTER:t.constructor.Event.FOCUSIN,o="hover"===n?t.constructor.Event.MOUSELEAVE:t.constructor.Event.FOCUSOUT;e(t.element).on(i,t.config.selector,(function(e){return t._enter(e)})).on(o,t.config.selector,(function(e){return t._leave(e)}))}})),this._hideModalHandler=function(){t.element&&t.hide()},e(this.element).closest(".modal").on("hide.bs.modal",this._hideModalHandler),this.config.selector?this.config=s({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},i._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},i._enter=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e(n.getTipElement()).hasClass("show")||"show"===n._hoverState?n._hoverState="show":(clearTimeout(n._timeout),n._hoverState="show",n.config.delay&&n.config.delay.show?n._timeout=setTimeout((function(){"show"===n._hoverState&&n.show()}),n.config.delay.show):n.show())},i._leave=function(t,n){var i=this.constructor.DATA_KEY;(n=n||e(t.currentTarget).data(i))||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),e(t.currentTarget).data(i,n)),t&&(n._activeTrigger["focusout"===t.type?"focus":"hover"]=!1),n._isWithActiveTrigger()||(clearTimeout(n._timeout),n._hoverState="out",n.config.delay&&n.config.delay.hide?n._timeout=setTimeout((function(){"out"===n._hoverState&&n.hide()}),n.config.delay.hide):n.hide())},i._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},i._getConfig=function(t){var n=e(this.element).data();return Object.keys(n).forEach((function(t){-1!==M.indexOf(t)&&delete n[t]})),"number"==typeof(t=s({},this.constructor.Default,n,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),a.typeCheckConfig(B,t,this.constructor.DefaultType),t.sanitize&&(t.template=Q(t.template,t.whiteList,t.sanitizeFn)),t},i._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},i._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(U);null!==n&&n.length&&t.removeClass(n.join(""))},i._handlePopperPlacementChange=function(t){this.tip=t.instance.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},i._fixTransition=function(){var t=this.getTipElement(),n=this.config.animation;null===t.getAttribute("x-placement")&&(e(t).removeClass("fade"),this.config.animation=!1,this.hide(),this.show(),this.config.animation=n)},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.tooltip"),o="object"==typeof n&&n;if((i||!/dispose|hide/.test(n))&&(i||(i=new t(this,o),e(this).data("bs.tooltip",i)),"string"==typeof n)){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return z}},{key:"NAME",get:function(){return B}},{key:"DATA_KEY",get:function(){return"bs.tooltip"}},{key:"Event",get:function(){return K}},{key:"EVENT_KEY",get:function(){return".bs.tooltip"}},{key:"DefaultType",get:function(){return W}}]),t}();e.fn[B]=X._jQueryInterface,e.fn[B].Constructor=X,e.fn[B].noConflict=function(){return e.fn[B]=H,X._jQueryInterface};var Y="popover",$=e.fn[Y],J=new RegExp("(^|\\s)bs-popover\\S+","g"),G=s({},X.Default,{placement:"right",trigger:"click",content:"",template:'<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>'}),Z=s({},X.DefaultType,{content:"(string|element|function)"}),tt={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"},et=function(t){var n,i;function s(){return t.apply(this,arguments)||this}i=t,(n=s).prototype=Object.create(i.prototype),n.prototype.constructor=n,n.__proto__=i;var r=s.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){e(this.getTipElement()).addClass("bs-popover-"+t)},r.getTipElement=function(){return this.tip=this.tip||e(this.config.template)[0],this.tip},r.setContent=function(){var t=e(this.getTipElement());this.setElementContent(t.find(".popover-header"),this.getTitle());var n=this._getContent();"function"==typeof n&&(n=n.call(this.element)),this.setElementContent(t.find(".popover-body"),n),t.removeClass("fade show")},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=e(this.getTipElement()),n=t.attr("class").match(J);null!==n&&n.length>0&&t.removeClass(n.join(""))},s._jQueryInterface=function(t){return this.each((function(){var n=e(this).data("bs.popover"),i="object"==typeof t?t:null;if((n||!/dispose|hide/.test(t))&&(n||(n=new s(this,i),e(this).data("bs.popover",n)),"string"==typeof t)){if("undefined"==typeof n[t])throw new TypeError('No method named "'+t+'"');n[t]()}}))},o(s,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return G}},{key:"NAME",get:function(){return Y}},{key:"DATA_KEY",get:function(){return"bs.popover"}},{key:"Event",get:function(){return tt}},{key:"EVENT_KEY",get:function(){return".bs.popover"}},{key:"DefaultType",get:function(){return Z}}]),s}(X);e.fn[Y]=et._jQueryInterface,e.fn[Y].Constructor=et,e.fn[Y].noConflict=function(){return e.fn[Y]=$,et._jQueryInterface};var nt="scrollspy",it=e.fn[nt],ot={offset:10,method:"auto",target:""},st={offset:"number",method:"string",target:"(string|element)"},rt=function(){function t(t,n){var i=this;this._element=t,this._scrollElement="BODY"===t.tagName?window:t,this._config=this._getConfig(n),this._selector=this._config.target+" .nav-link,"+this._config.target+" .list-group-item,"+this._config.target+" .dropdown-item",this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,e(this._scrollElement).on("scroll.bs.scrollspy",(function(t){return i._process(t)})),this.refresh(),this._process()}var n=t.prototype;return n.refresh=function(){var t=this,n=this._scrollElement===this._scrollElement.window?"offset":"position",i="auto"===this._config.method?n:this._config.method,o="position"===i?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),[].slice.call(document.querySelectorAll(this._selector)).map((function(t){var n,s=a.getSelectorFromElement(t);if(s&&(n=document.querySelector(s)),n){var r=n.getBoundingClientRect();if(r.width||r.height)return[e(n)[i]().top+o,s]}return null})).filter((function(t){return t})).sort((function(t,e){return t[0]-e[0]})).forEach((function(e){t._offsets.push(e[0]),t._targets.push(e[1])}))},n.dispose=function(){e.removeData(this._element,"bs.scrollspy"),e(this._scrollElement).off(".bs.scrollspy"),this._element=null,this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null},n._getConfig=function(t){if("string"!=typeof(t=s({},ot,"object"==typeof t&&t?t:{})).target&&a.isElement(t.target)){var n=e(t.target).attr("id");n||(n=a.getUID(nt),e(t.target).attr("id",n)),t.target="#"+n}return a.typeCheckConfig(nt,t,st),t},n._getScrollTop=function(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop},n._getScrollHeight=function(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)},n._getOffsetHeight=function(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height},n._process=function(){var t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),n=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=n){var i=this._targets[this._targets.length-1];this._activeTarget!==i&&this._activate(i)}else{if(this._activeTarget&&t<this._offsets[0]&&this._offsets[0]>0)return this._activeTarget=null,void this._clear();for(var o=this._offsets.length;o--;){this._activeTarget!==this._targets[o]&&t>=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||t<this._offsets[o+1])&&this._activate(this._targets[o])}}},n._activate=function(t){this._activeTarget=t,this._clear();var n=this._selector.split(",").map((function(e){return e+'[data-target="'+t+'"],'+e+'[href="'+t+'"]'})),i=e([].slice.call(document.querySelectorAll(n.join(","))));i.hasClass("dropdown-item")?(i.closest(".dropdown").find(".dropdown-toggle").addClass("active"),i.addClass("active")):(i.addClass("active"),i.parents(".nav, .list-group").prev(".nav-link, .list-group-item").addClass("active"),i.parents(".nav, .list-group").prev(".nav-item").children(".nav-link").addClass("active")),e(this._scrollElement).trigger("activate.bs.scrollspy",{relatedTarget:t})},n._clear=function(){[].slice.call(document.querySelectorAll(this._selector)).filter((function(t){return t.classList.contains("active")})).forEach((function(t){return t.classList.remove("active")}))},t._jQueryInterface=function(n){return this.each((function(){var i=e(this).data("bs.scrollspy");if(i||(i=new t(this,"object"==typeof n&&n),e(this).data("bs.scrollspy",i)),"string"==typeof n){if("undefined"==typeof i[n])throw new TypeError('No method named "'+n+'"');i[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"Default",get:function(){return ot}}]),t}();e(window).on("load.bs.scrollspy.data-api",(function(){for(var t=[].slice.call(document.querySelectorAll('[data-spy="scroll"]')),n=t.length;n--;){var i=e(t[n]);rt._jQueryInterface.call(i,i.data())}})),e.fn[nt]=rt._jQueryInterface,e.fn[nt].Constructor=rt,e.fn[nt].noConflict=function(){return e.fn[nt]=it,rt._jQueryInterface};var at=e.fn.tab,lt=function(){function t(t){this._element=t}var n=t.prototype;return n.show=function(){var t=this;if(!(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&e(this._element).hasClass("active")||e(this._element).hasClass("disabled"))){var n,i,o=e(this._element).closest(".nav, .list-group")[0],s=a.getSelectorFromElement(this._element);if(o){var r="UL"===o.nodeName||"OL"===o.nodeName?"> li > .active":".active";i=(i=e.makeArray(e(o).find(r)))[i.length-1]}var l=e.Event("hide.bs.tab",{relatedTarget:this._element}),c=e.Event("show.bs.tab",{relatedTarget:i});if(i&&e(i).trigger(l),e(this._element).trigger(c),!c.isDefaultPrevented()&&!l.isDefaultPrevented()){s&&(n=document.querySelector(s)),this._activate(this._element,o);var h=function(){var n=e.Event("hidden.bs.tab",{relatedTarget:t._element}),o=e.Event("shown.bs.tab",{relatedTarget:i});e(i).trigger(n),e(t._element).trigger(o)};n?this._activate(n,n.parentNode,h):h()}}},n.dispose=function(){e.removeData(this._element,"bs.tab"),this._element=null},n._activate=function(t,n,i){var o=this,s=(!n||"UL"!==n.nodeName&&"OL"!==n.nodeName?e(n).children(".active"):e(n).find("> li > .active"))[0],r=i&&s&&e(s).hasClass("fade"),l=function(){return o._transitionComplete(t,s,i)};if(s&&r){var c=a.getTransitionDurationFromElement(s);e(s).removeClass("show").one(a.TRANSITION_END,l).emulateTransitionEnd(c)}else l()},n._transitionComplete=function(t,n,i){if(n){e(n).removeClass("active");var o=e(n.parentNode).find("> .dropdown-menu .active")[0];o&&e(o).removeClass("active"),"tab"===n.getAttribute("role")&&n.setAttribute("aria-selected",!1)}if(e(t).addClass("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),a.reflow(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&e(t.parentNode).hasClass("dropdown-menu")){var s=e(t).closest(".dropdown")[0];if(s){var r=[].slice.call(s.querySelectorAll(".dropdown-toggle"));e(r).addClass("active")}t.setAttribute("aria-expanded",!0)}i&&i()},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.tab");if(o||(o=new t(this),i.data("bs.tab",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n]()}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}}]),t}();e(document).on("click.bs.tab.data-api",'[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',(function(t){t.preventDefault(),lt._jQueryInterface.call(e(this),"show")})),e.fn.tab=lt._jQueryInterface,e.fn.tab.Constructor=lt,e.fn.tab.noConflict=function(){return e.fn.tab=at,lt._jQueryInterface};var ct=e.fn.toast,ht={animation:"boolean",autohide:"boolean",delay:"number"},ut={animation:!0,autohide:!0,delay:500},dt=function(){function t(t,e){this._element=t,this._config=this._getConfig(e),this._timeout=null,this._setListeners()}var n=t.prototype;return n.show=function(){var t=this,n=e.Event("show.bs.toast");if(e(this._element).trigger(n),!n.isDefaultPrevented()){this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");var i=function(){t._element.classList.remove("showing"),t._element.classList.add("show"),e(t._element).trigger("shown.bs.toast"),t._config.autohide&&(t._timeout=setTimeout((function(){t.hide()}),t._config.delay))};if(this._element.classList.remove("hide"),a.reflow(this._element),this._element.classList.add("showing"),this._config.animation){var o=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,i).emulateTransitionEnd(o)}else i()}},n.hide=function(){if(this._element.classList.contains("show")){var t=e.Event("hide.bs.toast");e(this._element).trigger(t),t.isDefaultPrevented()||this._close()}},n.dispose=function(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),e(this._element).off("click.dismiss.bs.toast"),e.removeData(this._element,"bs.toast"),this._element=null,this._config=null},n._getConfig=function(t){return t=s({},ut,e(this._element).data(),"object"==typeof t&&t?t:{}),a.typeCheckConfig("toast",t,this.constructor.DefaultType),t},n._setListeners=function(){var t=this;e(this._element).on("click.dismiss.bs.toast",'[data-dismiss="toast"]',(function(){return t.hide()}))},n._close=function(){var t=this,n=function(){t._element.classList.add("hide"),e(t._element).trigger("hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){var i=a.getTransitionDurationFromElement(this._element);e(this._element).one(a.TRANSITION_END,n).emulateTransitionEnd(i)}else n()},n._clearTimeout=function(){clearTimeout(this._timeout),this._timeout=null},t._jQueryInterface=function(n){return this.each((function(){var i=e(this),o=i.data("bs.toast");if(o||(o=new t(this,"object"==typeof n&&n),i.data("bs.toast",o)),"string"==typeof n){if("undefined"==typeof o[n])throw new TypeError('No method named "'+n+'"');o[n](this)}}))},o(t,null,[{key:"VERSION",get:function(){return"4.5.2"}},{key:"DefaultType",get:function(){return ht}},{key:"Default",get:function(){return ut}}]),t}();e.fn.toast=dt._jQueryInterface,e.fn.toast.Constructor=dt,e.fn.toast.noConflict=function(){return e.fn.toast=ct,dt._jQueryInterface},t.Alert=h,t.Button=d,t.Carousel=b,t.Collapse=C,t.Dropdown=I,t.Modal=P,t.Popover=et,t.Scrollspy=rt,t.Tab=lt,t.Toast=dt,t.Tooltip=X,t.Util=a,Object.defineProperty(t,"__esModule",{value:!0})})); -//# sourceMappingURL=bootstrap.min.js.map \ No newline at end of file + * Bootstrap v4.5.2 (https://getbootstrap.com/) + * Copyright 2011-2020 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +!(function (t, e) { + 'object' == typeof exports && 'undefined' != typeof module + ? e(exports, require('jquery'), require('popper.js')) + : 'function' == typeof define && define.amd + ? define(['exports', 'jquery', 'popper.js'], e) + : e(((t = 'undefined' != typeof globalThis ? globalThis : t || self).bootstrap = {}), t.jQuery, t.Popper); +})(this, function (t, e, n) { + 'use strict'; + function i(t, e) { + for (var n = 0; n < e.length; n++) { + var i = e[n]; + (i.enumerable = i.enumerable || !1), (i.configurable = !0), 'value' in i && (i.writable = !0), Object.defineProperty(t, i.key, i); + } + } + function o(t, e, n) { + return e && i(t.prototype, e), n && i(t, n), t; + } + function s() { + return (s = + Object.assign || + function (t) { + for (var e = 1; e < arguments.length; e++) { + var n = arguments[e]; + for (var i in n) Object.prototype.hasOwnProperty.call(n, i) && (t[i] = n[i]); + } + return t; + }).apply(this, arguments); + } + (e = e && Object.prototype.hasOwnProperty.call(e, 'default') ? e.default : e), + (n = n && Object.prototype.hasOwnProperty.call(n, 'default') ? n.default : n); + function r(t) { + var n = this, + i = !1; + return ( + e(this).one(a.TRANSITION_END, function () { + i = !0; + }), + setTimeout(function () { + i || a.triggerTransitionEnd(n); + }, t), + this + ); + } + var a = { + TRANSITION_END: 'bsTransitionEnd', + getUID: function (t) { + do { + t += ~~(1e6 * Math.random()); + } while (document.getElementById(t)); + return t; + }, + getSelectorFromElement: function (t) { + var e = t.getAttribute('data-target'); + if (!e || '#' === e) { + var n = t.getAttribute('href'); + e = n && '#' !== n ? n.trim() : ''; + } + try { + return document.querySelector(e) ? e : null; + } catch (t) { + return null; + } + }, + getTransitionDurationFromElement: function (t) { + if (!t) return 0; + var n = e(t).css('transition-duration'), + i = e(t).css('transition-delay'), + o = parseFloat(n), + s = parseFloat(i); + return o || s ? ((n = n.split(',')[0]), (i = i.split(',')[0]), 1e3 * (parseFloat(n) + parseFloat(i))) : 0; + }, + reflow: function (t) { + return t.offsetHeight; + }, + triggerTransitionEnd: function (t) { + e(t).trigger('transitionend'); + }, + supportsTransitionEnd: function () { + return Boolean('transitionend'); + }, + isElement: function (t) { + return (t[0] || t).nodeType; + }, + typeCheckConfig: function (t, e, n) { + for (var i in n) + if (Object.prototype.hasOwnProperty.call(n, i)) { + var o = n[i], + s = e[i], + r = + s && a.isElement(s) + ? 'element' + : null === (l = s) || 'undefined' == typeof l + ? '' + l + : {}.toString + .call(l) + .match(/\s([a-z]+)/i)[1] + .toLowerCase(); + if (!new RegExp(o).test(r)) + throw new Error(t.toUpperCase() + ': Option "' + i + '" provided type "' + r + '" but expected type "' + o + '".'); + } + var l; + }, + findShadowRoot: function (t) { + if (!document.documentElement.attachShadow) return null; + if ('function' == typeof t.getRootNode) { + var e = t.getRootNode(); + return e instanceof ShadowRoot ? e : null; + } + return t instanceof ShadowRoot ? t : t.parentNode ? a.findShadowRoot(t.parentNode) : null; + }, + jQueryDetection: function () { + if ('undefined' == typeof e) + throw new TypeError("Bootstrap's JavaScript requires jQuery. jQuery must be included before Bootstrap's JavaScript."); + var t = e.fn.jquery.split(' ')[0].split('.'); + if ((t[0] < 2 && t[1] < 9) || (1 === t[0] && 9 === t[1] && t[2] < 1) || t[0] >= 4) + throw new Error("Bootstrap's JavaScript requires at least jQuery v1.9.1 but less than v4.0.0"); + }, + }; + a.jQueryDetection(), + (e.fn.emulateTransitionEnd = r), + (e.event.special[a.TRANSITION_END] = { + bindType: 'transitionend', + delegateType: 'transitionend', + handle: function (t) { + if (e(t.target).is(this)) return t.handleObj.handler.apply(this, arguments); + }, + }); + var l = 'alert', + c = e.fn[l], + h = (function () { + function t(t) { + this._element = t; + } + var n = t.prototype; + return ( + (n.close = function (t) { + var e = this._element; + t && (e = this._getRootElement(t)), this._triggerCloseEvent(e).isDefaultPrevented() || this._removeElement(e); + }), + (n.dispose = function () { + e.removeData(this._element, 'bs.alert'), (this._element = null); + }), + (n._getRootElement = function (t) { + var n = a.getSelectorFromElement(t), + i = !1; + return n && (i = document.querySelector(n)), i || (i = e(t).closest('.alert')[0]), i; + }), + (n._triggerCloseEvent = function (t) { + var n = e.Event('close.bs.alert'); + return e(t).trigger(n), n; + }), + (n._removeElement = function (t) { + var n = this; + if ((e(t).removeClass('show'), e(t).hasClass('fade'))) { + var i = a.getTransitionDurationFromElement(t); + e(t) + .one(a.TRANSITION_END, function (e) { + return n._destroyElement(t, e); + }) + .emulateTransitionEnd(i); + } else this._destroyElement(t); + }), + (n._destroyElement = function (t) { + e(t).detach().trigger('closed.bs.alert').remove(); + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this), + o = i.data('bs.alert'); + o || ((o = new t(this)), i.data('bs.alert', o)), 'close' === n && o[n](this); + }); + }), + (t._handleDismiss = function (t) { + return function (e) { + e && e.preventDefault(), t.close(this); + }; + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + ]), + t + ); + })(); + e(document).on('click.bs.alert.data-api', '[data-dismiss="alert"]', h._handleDismiss(new h())), + (e.fn[l] = h._jQueryInterface), + (e.fn[l].Constructor = h), + (e.fn[l].noConflict = function () { + return (e.fn[l] = c), h._jQueryInterface; + }); + var u = e.fn.button, + d = (function () { + function t(t) { + this._element = t; + } + var n = t.prototype; + return ( + (n.toggle = function () { + var t = !0, + n = !0, + i = e(this._element).closest('[data-toggle="buttons"]')[0]; + if (i) { + var o = this._element.querySelector('input:not([type="hidden"])'); + if (o) { + if ('radio' === o.type) + if (o.checked && this._element.classList.contains('active')) t = !1; + else { + var s = i.querySelector('.active'); + s && e(s).removeClass('active'); + } + t && + (('checkbox' !== o.type && 'radio' !== o.type) || (o.checked = !this._element.classList.contains('active')), + e(o).trigger('change')), + o.focus(), + (n = !1); + } + } + this._element.hasAttribute('disabled') || + this._element.classList.contains('disabled') || + (n && this._element.setAttribute('aria-pressed', !this._element.classList.contains('active')), + t && e(this._element).toggleClass('active')); + }), + (n.dispose = function () { + e.removeData(this._element, 'bs.button'), (this._element = null); + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this).data('bs.button'); + i || ((i = new t(this)), e(this).data('bs.button', i)), 'toggle' === n && i[n](); + }); + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + ]), + t + ); + })(); + e(document) + .on('click.bs.button.data-api', '[data-toggle^="button"]', function (t) { + var n = t.target, + i = n; + if ((e(n).hasClass('btn') || (n = e(n).closest('.btn')[0]), !n || n.hasAttribute('disabled') || n.classList.contains('disabled'))) + t.preventDefault(); + else { + var o = n.querySelector('input:not([type="hidden"])'); + if (o && (o.hasAttribute('disabled') || o.classList.contains('disabled'))) return void t.preventDefault(); + ('LABEL' !== i.tagName || (o && 'checkbox' !== o.type)) && d._jQueryInterface.call(e(n), 'toggle'); + } + }) + .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (t) { + var n = e(t.target).closest('.btn')[0]; + e(n).toggleClass('focus', /^focus(in)?$/.test(t.type)); + }), + e(window).on('load.bs.button.data-api', function () { + for (var t = [].slice.call(document.querySelectorAll('[data-toggle="buttons"] .btn')), e = 0, n = t.length; e < n; e++) { + var i = t[e], + o = i.querySelector('input:not([type="hidden"])'); + o.checked || o.hasAttribute('checked') ? i.classList.add('active') : i.classList.remove('active'); + } + for (var s = 0, r = (t = [].slice.call(document.querySelectorAll('[data-toggle="button"]'))).length; s < r; s++) { + var a = t[s]; + 'true' === a.getAttribute('aria-pressed') ? a.classList.add('active') : a.classList.remove('active'); + } + }), + (e.fn.button = d._jQueryInterface), + (e.fn.button.Constructor = d), + (e.fn.button.noConflict = function () { + return (e.fn.button = u), d._jQueryInterface; + }); + var f = 'carousel', + g = '.bs.carousel', + m = e.fn[f], + p = { interval: 5e3, keyboard: !0, slide: !1, pause: 'hover', wrap: !0, touch: !0 }, + _ = { + interval: '(number|boolean)', + keyboard: 'boolean', + slide: '(boolean|string)', + pause: '(string|boolean)', + wrap: 'boolean', + touch: 'boolean', + }, + v = { TOUCH: 'touch', PEN: 'pen' }, + b = (function () { + function t(t, e) { + (this._items = null), + (this._interval = null), + (this._activeElement = null), + (this._isPaused = !1), + (this._isSliding = !1), + (this.touchTimeout = null), + (this.touchStartX = 0), + (this.touchDeltaX = 0), + (this._config = this._getConfig(e)), + (this._element = t), + (this._indicatorsElement = this._element.querySelector('.carousel-indicators')), + (this._touchSupported = 'ontouchstart' in document.documentElement || navigator.maxTouchPoints > 0), + (this._pointerEvent = Boolean(window.PointerEvent || window.MSPointerEvent)), + this._addEventListeners(); + } + var n = t.prototype; + return ( + (n.next = function () { + this._isSliding || this._slide('next'); + }), + (n.nextWhenVisible = function () { + !document.hidden && e(this._element).is(':visible') && 'hidden' !== e(this._element).css('visibility') && this.next(); + }), + (n.prev = function () { + this._isSliding || this._slide('prev'); + }), + (n.pause = function (t) { + t || (this._isPaused = !0), + this._element.querySelector('.carousel-item-next, .carousel-item-prev') && + (a.triggerTransitionEnd(this._element), this.cycle(!0)), + clearInterval(this._interval), + (this._interval = null); + }), + (n.cycle = function (t) { + t || (this._isPaused = !1), + this._interval && (clearInterval(this._interval), (this._interval = null)), + this._config.interval && + !this._isPaused && + (this._interval = setInterval( + (document.visibilityState ? this.nextWhenVisible : this.next).bind(this), + this._config.interval + )); + }), + (n.to = function (t) { + var n = this; + this._activeElement = this._element.querySelector('.active.carousel-item'); + var i = this._getItemIndex(this._activeElement); + if (!(t > this._items.length - 1 || t < 0)) + if (this._isSliding) + e(this._element).one('slid.bs.carousel', function () { + return n.to(t); + }); + else { + if (i === t) return this.pause(), void this.cycle(); + var o = t > i ? 'next' : 'prev'; + this._slide(o, this._items[t]); + } + }), + (n.dispose = function () { + e(this._element).off(g), + e.removeData(this._element, 'bs.carousel'), + (this._items = null), + (this._config = null), + (this._element = null), + (this._interval = null), + (this._isPaused = null), + (this._isSliding = null), + (this._activeElement = null), + (this._indicatorsElement = null); + }), + (n._getConfig = function (t) { + return (t = s({}, p, t)), a.typeCheckConfig(f, t, _), t; + }), + (n._handleSwipe = function () { + var t = Math.abs(this.touchDeltaX); + if (!(t <= 40)) { + var e = t / this.touchDeltaX; + (this.touchDeltaX = 0), e > 0 && this.prev(), e < 0 && this.next(); + } + }), + (n._addEventListeners = function () { + var t = this; + this._config.keyboard && + e(this._element).on('keydown.bs.carousel', function (e) { + return t._keydown(e); + }), + 'hover' === this._config.pause && + e(this._element) + .on('mouseenter.bs.carousel', function (e) { + return t.pause(e); + }) + .on('mouseleave.bs.carousel', function (e) { + return t.cycle(e); + }), + this._config.touch && this._addTouchEventListeners(); + }), + (n._addTouchEventListeners = function () { + var t = this; + if (this._touchSupported) { + var n = function (e) { + t._pointerEvent && v[e.originalEvent.pointerType.toUpperCase()] + ? (t.touchStartX = e.originalEvent.clientX) + : t._pointerEvent || (t.touchStartX = e.originalEvent.touches[0].clientX); + }, + i = function (e) { + t._pointerEvent && + v[e.originalEvent.pointerType.toUpperCase()] && + (t.touchDeltaX = e.originalEvent.clientX - t.touchStartX), + t._handleSwipe(), + 'hover' === t._config.pause && + (t.pause(), + t.touchTimeout && clearTimeout(t.touchTimeout), + (t.touchTimeout = setTimeout(function (e) { + return t.cycle(e); + }, 500 + t._config.interval))); + }; + e(this._element.querySelectorAll('.carousel-item img')).on('dragstart.bs.carousel', function (t) { + return t.preventDefault(); + }), + this._pointerEvent + ? (e(this._element).on('pointerdown.bs.carousel', function (t) { + return n(t); + }), + e(this._element).on('pointerup.bs.carousel', function (t) { + return i(t); + }), + this._element.classList.add('pointer-event')) + : (e(this._element).on('touchstart.bs.carousel', function (t) { + return n(t); + }), + e(this._element).on('touchmove.bs.carousel', function (e) { + return (function (e) { + e.originalEvent.touches && e.originalEvent.touches.length > 1 + ? (t.touchDeltaX = 0) + : (t.touchDeltaX = e.originalEvent.touches[0].clientX - t.touchStartX); + })(e); + }), + e(this._element).on('touchend.bs.carousel', function (t) { + return i(t); + })); + } + }), + (n._keydown = function (t) { + if (!/input|textarea/i.test(t.target.tagName)) + switch (t.which) { + case 37: + t.preventDefault(), this.prev(); + break; + case 39: + t.preventDefault(), this.next(); + } + }), + (n._getItemIndex = function (t) { + return ( + (this._items = t && t.parentNode ? [].slice.call(t.parentNode.querySelectorAll('.carousel-item')) : []), this._items.indexOf(t) + ); + }), + (n._getItemByDirection = function (t, e) { + var n = 'next' === t, + i = 'prev' === t, + o = this._getItemIndex(e), + s = this._items.length - 1; + if (((i && 0 === o) || (n && o === s)) && !this._config.wrap) return e; + var r = (o + ('prev' === t ? -1 : 1)) % this._items.length; + return -1 === r ? this._items[this._items.length - 1] : this._items[r]; + }), + (n._triggerSlideEvent = function (t, n) { + var i = this._getItemIndex(t), + o = this._getItemIndex(this._element.querySelector('.active.carousel-item')), + s = e.Event('slide.bs.carousel', { relatedTarget: t, direction: n, from: o, to: i }); + return e(this._element).trigger(s), s; + }), + (n._setActiveIndicatorElement = function (t) { + if (this._indicatorsElement) { + var n = [].slice.call(this._indicatorsElement.querySelectorAll('.active')); + e(n).removeClass('active'); + var i = this._indicatorsElement.children[this._getItemIndex(t)]; + i && e(i).addClass('active'); + } + }), + (n._slide = function (t, n) { + var i, + o, + s, + r = this, + l = this._element.querySelector('.active.carousel-item'), + c = this._getItemIndex(l), + h = n || (l && this._getItemByDirection(t, l)), + u = this._getItemIndex(h), + d = Boolean(this._interval); + if ( + ('next' === t + ? ((i = 'carousel-item-left'), (o = 'carousel-item-next'), (s = 'left')) + : ((i = 'carousel-item-right'), (o = 'carousel-item-prev'), (s = 'right')), + h && e(h).hasClass('active')) + ) + this._isSliding = !1; + else if (!this._triggerSlideEvent(h, s).isDefaultPrevented() && l && h) { + (this._isSliding = !0), d && this.pause(), this._setActiveIndicatorElement(h); + var f = e.Event('slid.bs.carousel', { relatedTarget: h, direction: s, from: c, to: u }); + if (e(this._element).hasClass('slide')) { + e(h).addClass(o), a.reflow(h), e(l).addClass(i), e(h).addClass(i); + var g = parseInt(h.getAttribute('data-interval'), 10); + g + ? ((this._config.defaultInterval = this._config.defaultInterval || this._config.interval), (this._config.interval = g)) + : (this._config.interval = this._config.defaultInterval || this._config.interval); + var m = a.getTransitionDurationFromElement(l); + e(l) + .one(a.TRANSITION_END, function () { + e(h) + .removeClass(i + ' ' + o) + .addClass('active'), + e(l).removeClass('active ' + o + ' ' + i), + (r._isSliding = !1), + setTimeout(function () { + return e(r._element).trigger(f); + }, 0); + }) + .emulateTransitionEnd(m); + } else e(l).removeClass('active'), e(h).addClass('active'), (this._isSliding = !1), e(this._element).trigger(f); + d && this.cycle(); + } + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this).data('bs.carousel'), + o = s({}, p, e(this).data()); + 'object' == typeof n && (o = s({}, o, n)); + var r = 'string' == typeof n ? n : o.slide; + if ((i || ((i = new t(this, o)), e(this).data('bs.carousel', i)), 'number' == typeof n)) i.to(n); + else if ('string' == typeof r) { + if ('undefined' == typeof i[r]) throw new TypeError('No method named "' + r + '"'); + i[r](); + } else o.interval && o.ride && (i.pause(), i.cycle()); + }); + }), + (t._dataApiClickHandler = function (n) { + var i = a.getSelectorFromElement(this); + if (i) { + var o = e(i)[0]; + if (o && e(o).hasClass('carousel')) { + var r = s({}, e(o).data(), e(this).data()), + l = this.getAttribute('data-slide-to'); + l && (r.interval = !1), t._jQueryInterface.call(e(o), r), l && e(o).data('bs.carousel').to(l), n.preventDefault(); + } + } + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + { + key: 'Default', + get: function () { + return p; + }, + }, + ]), + t + ); + })(); + e(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', b._dataApiClickHandler), + e(window).on('load.bs.carousel.data-api', function () { + for (var t = [].slice.call(document.querySelectorAll('[data-ride="carousel"]')), n = 0, i = t.length; n < i; n++) { + var o = e(t[n]); + b._jQueryInterface.call(o, o.data()); + } + }), + (e.fn[f] = b._jQueryInterface), + (e.fn[f].Constructor = b), + (e.fn[f].noConflict = function () { + return (e.fn[f] = m), b._jQueryInterface; + }); + var y = 'collapse', + E = e.fn[y], + w = { toggle: !0, parent: '' }, + T = { toggle: 'boolean', parent: '(string|element)' }, + C = (function () { + function t(t, e) { + (this._isTransitioning = !1), + (this._element = t), + (this._config = this._getConfig(e)), + (this._triggerArray = [].slice.call( + document.querySelectorAll( + '[data-toggle="collapse"][href="#' + t.id + '"],[data-toggle="collapse"][data-target="#' + t.id + '"]' + ) + )); + for (var n = [].slice.call(document.querySelectorAll('[data-toggle="collapse"]')), i = 0, o = n.length; i < o; i++) { + var s = n[i], + r = a.getSelectorFromElement(s), + l = [].slice.call(document.querySelectorAll(r)).filter(function (e) { + return e === t; + }); + null !== r && l.length > 0 && ((this._selector = r), this._triggerArray.push(s)); + } + (this._parent = this._config.parent ? this._getParent() : null), + this._config.parent || this._addAriaAndCollapsedClass(this._element, this._triggerArray), + this._config.toggle && this.toggle(); + } + var n = t.prototype; + return ( + (n.toggle = function () { + e(this._element).hasClass('show') ? this.hide() : this.show(); + }), + (n.show = function () { + var n, + i, + o = this; + if ( + !this._isTransitioning && + !e(this._element).hasClass('show') && + (this._parent && + 0 === + (n = [].slice.call(this._parent.querySelectorAll('.show, .collapsing')).filter(function (t) { + return 'string' == typeof o._config.parent + ? t.getAttribute('data-parent') === o._config.parent + : t.classList.contains('collapse'); + })).length && + (n = null), + !(n && (i = e(n).not(this._selector).data('bs.collapse')) && i._isTransitioning)) + ) { + var s = e.Event('show.bs.collapse'); + if ((e(this._element).trigger(s), !s.isDefaultPrevented())) { + n && (t._jQueryInterface.call(e(n).not(this._selector), 'hide'), i || e(n).data('bs.collapse', null)); + var r = this._getDimension(); + e(this._element).removeClass('collapse').addClass('collapsing'), + (this._element.style[r] = 0), + this._triggerArray.length && e(this._triggerArray).removeClass('collapsed').attr('aria-expanded', !0), + this.setTransitioning(!0); + var l = 'scroll' + (r[0].toUpperCase() + r.slice(1)), + c = a.getTransitionDurationFromElement(this._element); + e(this._element) + .one(a.TRANSITION_END, function () { + e(o._element).removeClass('collapsing').addClass('collapse show'), + (o._element.style[r] = ''), + o.setTransitioning(!1), + e(o._element).trigger('shown.bs.collapse'); + }) + .emulateTransitionEnd(c), + (this._element.style[r] = this._element[l] + 'px'); + } + } + }), + (n.hide = function () { + var t = this; + if (!this._isTransitioning && e(this._element).hasClass('show')) { + var n = e.Event('hide.bs.collapse'); + if ((e(this._element).trigger(n), !n.isDefaultPrevented())) { + var i = this._getDimension(); + (this._element.style[i] = this._element.getBoundingClientRect()[i] + 'px'), + a.reflow(this._element), + e(this._element).addClass('collapsing').removeClass('collapse show'); + var o = this._triggerArray.length; + if (o > 0) + for (var s = 0; s < o; s++) { + var r = this._triggerArray[s], + l = a.getSelectorFromElement(r); + if (null !== l) + e([].slice.call(document.querySelectorAll(l))).hasClass('show') || e(r).addClass('collapsed').attr('aria-expanded', !1); + } + this.setTransitioning(!0); + this._element.style[i] = ''; + var c = a.getTransitionDurationFromElement(this._element); + e(this._element) + .one(a.TRANSITION_END, function () { + t.setTransitioning(!1), e(t._element).removeClass('collapsing').addClass('collapse').trigger('hidden.bs.collapse'); + }) + .emulateTransitionEnd(c); + } + } + }), + (n.setTransitioning = function (t) { + this._isTransitioning = t; + }), + (n.dispose = function () { + e.removeData(this._element, 'bs.collapse'), + (this._config = null), + (this._parent = null), + (this._element = null), + (this._triggerArray = null), + (this._isTransitioning = null); + }), + (n._getConfig = function (t) { + return ((t = s({}, w, t)).toggle = Boolean(t.toggle)), a.typeCheckConfig(y, t, T), t; + }), + (n._getDimension = function () { + return e(this._element).hasClass('width') ? 'width' : 'height'; + }), + (n._getParent = function () { + var n, + i = this; + a.isElement(this._config.parent) + ? ((n = this._config.parent), 'undefined' != typeof this._config.parent.jquery && (n = this._config.parent[0])) + : (n = document.querySelector(this._config.parent)); + var o = '[data-toggle="collapse"][data-parent="' + this._config.parent + '"]', + s = [].slice.call(n.querySelectorAll(o)); + return ( + e(s).each(function (e, n) { + i._addAriaAndCollapsedClass(t._getTargetFromElement(n), [n]); + }), + n + ); + }), + (n._addAriaAndCollapsedClass = function (t, n) { + var i = e(t).hasClass('show'); + n.length && e(n).toggleClass('collapsed', !i).attr('aria-expanded', i); + }), + (t._getTargetFromElement = function (t) { + var e = a.getSelectorFromElement(t); + return e ? document.querySelector(e) : null; + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this), + o = i.data('bs.collapse'), + r = s({}, w, i.data(), 'object' == typeof n && n ? n : {}); + if ( + (!o && r.toggle && 'string' == typeof n && /show|hide/.test(n) && (r.toggle = !1), + o || ((o = new t(this, r)), i.data('bs.collapse', o)), + 'string' == typeof n) + ) { + if ('undefined' == typeof o[n]) throw new TypeError('No method named "' + n + '"'); + o[n](); + } + }); + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + { + key: 'Default', + get: function () { + return w; + }, + }, + ]), + t + ); + })(); + e(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (t) { + 'A' === t.currentTarget.tagName && t.preventDefault(); + var n = e(this), + i = a.getSelectorFromElement(this), + o = [].slice.call(document.querySelectorAll(i)); + e(o).each(function () { + var t = e(this), + i = t.data('bs.collapse') ? 'toggle' : n.data(); + C._jQueryInterface.call(t, i); + }); + }), + (e.fn[y] = C._jQueryInterface), + (e.fn[y].Constructor = C), + (e.fn[y].noConflict = function () { + return (e.fn[y] = E), C._jQueryInterface; + }); + var S = 'dropdown', + k = e.fn[S], + D = new RegExp('38|40|27'), + N = { offset: 0, flip: !0, boundary: 'scrollParent', reference: 'toggle', display: 'dynamic', popperConfig: null }, + A = { + offset: '(number|string|function)', + flip: 'boolean', + boundary: '(string|element)', + reference: '(string|element)', + display: 'string', + popperConfig: '(null|object)', + }, + I = (function () { + function t(t, e) { + (this._element = t), + (this._popper = null), + (this._config = this._getConfig(e)), + (this._menu = this._getMenuElement()), + (this._inNavbar = this._detectNavbar()), + this._addEventListeners(); + } + var i = t.prototype; + return ( + (i.toggle = function () { + if (!this._element.disabled && !e(this._element).hasClass('disabled')) { + var n = e(this._menu).hasClass('show'); + t._clearMenus(), n || this.show(!0); + } + }), + (i.show = function (i) { + if ( + (void 0 === i && (i = !1), !(this._element.disabled || e(this._element).hasClass('disabled') || e(this._menu).hasClass('show'))) + ) { + var o = { relatedTarget: this._element }, + s = e.Event('show.bs.dropdown', o), + r = t._getParentFromElement(this._element); + if ((e(r).trigger(s), !s.isDefaultPrevented())) { + if (!this._inNavbar && i) { + if ('undefined' == typeof n) throw new TypeError("Bootstrap's dropdowns require Popper.js (https://popper.js.org/)"); + var l = this._element; + 'parent' === this._config.reference + ? (l = r) + : a.isElement(this._config.reference) && + ((l = this._config.reference), 'undefined' != typeof this._config.reference.jquery && (l = this._config.reference[0])), + 'scrollParent' !== this._config.boundary && e(r).addClass('position-static'), + (this._popper = new n(l, this._menu, this._getPopperConfig())); + } + 'ontouchstart' in document.documentElement && + 0 === e(r).closest('.navbar-nav').length && + e(document.body).children().on('mouseover', null, e.noop), + this._element.focus(), + this._element.setAttribute('aria-expanded', !0), + e(this._menu).toggleClass('show'), + e(r).toggleClass('show').trigger(e.Event('shown.bs.dropdown', o)); + } + } + }), + (i.hide = function () { + if (!this._element.disabled && !e(this._element).hasClass('disabled') && e(this._menu).hasClass('show')) { + var n = { relatedTarget: this._element }, + i = e.Event('hide.bs.dropdown', n), + o = t._getParentFromElement(this._element); + e(o).trigger(i), + i.isDefaultPrevented() || + (this._popper && this._popper.destroy(), + e(this._menu).toggleClass('show'), + e(o).toggleClass('show').trigger(e.Event('hidden.bs.dropdown', n))); + } + }), + (i.dispose = function () { + e.removeData(this._element, 'bs.dropdown'), + e(this._element).off('.bs.dropdown'), + (this._element = null), + (this._menu = null), + null !== this._popper && (this._popper.destroy(), (this._popper = null)); + }), + (i.update = function () { + (this._inNavbar = this._detectNavbar()), null !== this._popper && this._popper.scheduleUpdate(); + }), + (i._addEventListeners = function () { + var t = this; + e(this._element).on('click.bs.dropdown', function (e) { + e.preventDefault(), e.stopPropagation(), t.toggle(); + }); + }), + (i._getConfig = function (t) { + return ( + (t = s({}, this.constructor.Default, e(this._element).data(), t)), a.typeCheckConfig(S, t, this.constructor.DefaultType), t + ); + }), + (i._getMenuElement = function () { + if (!this._menu) { + var e = t._getParentFromElement(this._element); + e && (this._menu = e.querySelector('.dropdown-menu')); + } + return this._menu; + }), + (i._getPlacement = function () { + var t = e(this._element.parentNode), + n = 'bottom-start'; + return ( + t.hasClass('dropup') + ? (n = e(this._menu).hasClass('dropdown-menu-right') ? 'top-end' : 'top-start') + : t.hasClass('dropright') + ? (n = 'right-start') + : t.hasClass('dropleft') + ? (n = 'left-start') + : e(this._menu).hasClass('dropdown-menu-right') && (n = 'bottom-end'), + n + ); + }), + (i._detectNavbar = function () { + return e(this._element).closest('.navbar').length > 0; + }), + (i._getOffset = function () { + var t = this, + e = {}; + return ( + 'function' == typeof this._config.offset + ? (e.fn = function (e) { + return (e.offsets = s({}, e.offsets, t._config.offset(e.offsets, t._element) || {})), e; + }) + : (e.offset = this._config.offset), + e + ); + }), + (i._getPopperConfig = function () { + var t = { + placement: this._getPlacement(), + modifiers: { + offset: this._getOffset(), + flip: { enabled: this._config.flip }, + preventOverflow: { boundariesElement: this._config.boundary }, + }, + }; + return 'static' === this._config.display && (t.modifiers.applyStyle = { enabled: !1 }), s({}, t, this._config.popperConfig); + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this).data('bs.dropdown'); + if ((i || ((i = new t(this, 'object' == typeof n ? n : null)), e(this).data('bs.dropdown', i)), 'string' == typeof n)) { + if ('undefined' == typeof i[n]) throw new TypeError('No method named "' + n + '"'); + i[n](); + } + }); + }), + (t._clearMenus = function (n) { + if (!n || (3 !== n.which && ('keyup' !== n.type || 9 === n.which))) + for (var i = [].slice.call(document.querySelectorAll('[data-toggle="dropdown"]')), o = 0, s = i.length; o < s; o++) { + var r = t._getParentFromElement(i[o]), + a = e(i[o]).data('bs.dropdown'), + l = { relatedTarget: i[o] }; + if ((n && 'click' === n.type && (l.clickEvent = n), a)) { + var c = a._menu; + if ( + e(r).hasClass('show') && + !( + n && + (('click' === n.type && /input|textarea/i.test(n.target.tagName)) || ('keyup' === n.type && 9 === n.which)) && + e.contains(r, n.target) + ) + ) { + var h = e.Event('hide.bs.dropdown', l); + e(r).trigger(h), + h.isDefaultPrevented() || + ('ontouchstart' in document.documentElement && e(document.body).children().off('mouseover', null, e.noop), + i[o].setAttribute('aria-expanded', 'false'), + a._popper && a._popper.destroy(), + e(c).removeClass('show'), + e(r).removeClass('show').trigger(e.Event('hidden.bs.dropdown', l))); + } + } + } + }), + (t._getParentFromElement = function (t) { + var e, + n = a.getSelectorFromElement(t); + return n && (e = document.querySelector(n)), e || t.parentNode; + }), + (t._dataApiKeydownHandler = function (n) { + if ( + !(/input|textarea/i.test(n.target.tagName) + ? 32 === n.which || (27 !== n.which && ((40 !== n.which && 38 !== n.which) || e(n.target).closest('.dropdown-menu').length)) + : !D.test(n.which)) && + !this.disabled && + !e(this).hasClass('disabled') + ) { + var i = t._getParentFromElement(this), + o = e(i).hasClass('show'); + if (o || 27 !== n.which) { + if ((n.preventDefault(), n.stopPropagation(), !o || (o && (27 === n.which || 32 === n.which)))) + return 27 === n.which && e(i.querySelector('[data-toggle="dropdown"]')).trigger('focus'), void e(this).trigger('click'); + var s = [].slice.call(i.querySelectorAll('.dropdown-menu .dropdown-item:not(.disabled):not(:disabled)')).filter(function (t) { + return e(t).is(':visible'); + }); + if (0 !== s.length) { + var r = s.indexOf(n.target); + 38 === n.which && r > 0 && r--, 40 === n.which && r < s.length - 1 && r++, r < 0 && (r = 0), s[r].focus(); + } + } + } + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + { + key: 'Default', + get: function () { + return N; + }, + }, + { + key: 'DefaultType', + get: function () { + return A; + }, + }, + ]), + t + ); + })(); + e(document) + .on('keydown.bs.dropdown.data-api', '[data-toggle="dropdown"]', I._dataApiKeydownHandler) + .on('keydown.bs.dropdown.data-api', '.dropdown-menu', I._dataApiKeydownHandler) + .on('click.bs.dropdown.data-api keyup.bs.dropdown.data-api', I._clearMenus) + .on('click.bs.dropdown.data-api', '[data-toggle="dropdown"]', function (t) { + t.preventDefault(), t.stopPropagation(), I._jQueryInterface.call(e(this), 'toggle'); + }) + .on('click.bs.dropdown.data-api', '.dropdown form', function (t) { + t.stopPropagation(); + }), + (e.fn[S] = I._jQueryInterface), + (e.fn[S].Constructor = I), + (e.fn[S].noConflict = function () { + return (e.fn[S] = k), I._jQueryInterface; + }); + var O = e.fn.modal, + j = { backdrop: !0, keyboard: !0, focus: !0, show: !0 }, + x = { backdrop: '(boolean|string)', keyboard: 'boolean', focus: 'boolean', show: 'boolean' }, + P = (function () { + function t(t, e) { + (this._config = this._getConfig(e)), + (this._element = t), + (this._dialog = t.querySelector('.modal-dialog')), + (this._backdrop = null), + (this._isShown = !1), + (this._isBodyOverflowing = !1), + (this._ignoreBackdropClick = !1), + (this._isTransitioning = !1), + (this._scrollbarWidth = 0); + } + var n = t.prototype; + return ( + (n.toggle = function (t) { + return this._isShown ? this.hide() : this.show(t); + }), + (n.show = function (t) { + var n = this; + if (!this._isShown && !this._isTransitioning) { + e(this._element).hasClass('fade') && (this._isTransitioning = !0); + var i = e.Event('show.bs.modal', { relatedTarget: t }); + e(this._element).trigger(i), + this._isShown || + i.isDefaultPrevented() || + ((this._isShown = !0), + this._checkScrollbar(), + this._setScrollbar(), + this._adjustDialog(), + this._setEscapeEvent(), + this._setResizeEvent(), + e(this._element).on('click.dismiss.bs.modal', '[data-dismiss="modal"]', function (t) { + return n.hide(t); + }), + e(this._dialog).on('mousedown.dismiss.bs.modal', function () { + e(n._element).one('mouseup.dismiss.bs.modal', function (t) { + e(t.target).is(n._element) && (n._ignoreBackdropClick = !0); + }); + }), + this._showBackdrop(function () { + return n._showElement(t); + })); + } + }), + (n.hide = function (t) { + var n = this; + if ((t && t.preventDefault(), this._isShown && !this._isTransitioning)) { + var i = e.Event('hide.bs.modal'); + if ((e(this._element).trigger(i), this._isShown && !i.isDefaultPrevented())) { + this._isShown = !1; + var o = e(this._element).hasClass('fade'); + if ( + (o && (this._isTransitioning = !0), + this._setEscapeEvent(), + this._setResizeEvent(), + e(document).off('focusin.bs.modal'), + e(this._element).removeClass('show'), + e(this._element).off('click.dismiss.bs.modal'), + e(this._dialog).off('mousedown.dismiss.bs.modal'), + o) + ) { + var s = a.getTransitionDurationFromElement(this._element); + e(this._element) + .one(a.TRANSITION_END, function (t) { + return n._hideModal(t); + }) + .emulateTransitionEnd(s); + } else this._hideModal(); + } + } + }), + (n.dispose = function () { + [window, this._element, this._dialog].forEach(function (t) { + return e(t).off('.bs.modal'); + }), + e(document).off('focusin.bs.modal'), + e.removeData(this._element, 'bs.modal'), + (this._config = null), + (this._element = null), + (this._dialog = null), + (this._backdrop = null), + (this._isShown = null), + (this._isBodyOverflowing = null), + (this._ignoreBackdropClick = null), + (this._isTransitioning = null), + (this._scrollbarWidth = null); + }), + (n.handleUpdate = function () { + this._adjustDialog(); + }), + (n._getConfig = function (t) { + return (t = s({}, j, t)), a.typeCheckConfig('modal', t, x), t; + }), + (n._triggerBackdropTransition = function () { + var t = this; + if ('static' === this._config.backdrop) { + var n = e.Event('hidePrevented.bs.modal'); + if ((e(this._element).trigger(n), n.defaultPrevented)) return; + var i = this._element.scrollHeight > document.documentElement.clientHeight; + i || (this._element.style.overflowY = 'hidden'), this._element.classList.add('modal-static'); + var o = a.getTransitionDurationFromElement(this._dialog); + e(this._element).off(a.TRANSITION_END), + e(this._element) + .one(a.TRANSITION_END, function () { + t._element.classList.remove('modal-static'), + i || + e(t._element) + .one(a.TRANSITION_END, function () { + t._element.style.overflowY = ''; + }) + .emulateTransitionEnd(t._element, o); + }) + .emulateTransitionEnd(o), + this._element.focus(); + } else this.hide(); + }), + (n._showElement = function (t) { + var n = this, + i = e(this._element).hasClass('fade'), + o = this._dialog ? this._dialog.querySelector('.modal-body') : null; + (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE) || document.body.appendChild(this._element), + (this._element.style.display = 'block'), + this._element.removeAttribute('aria-hidden'), + this._element.setAttribute('aria-modal', !0), + this._element.setAttribute('role', 'dialog'), + e(this._dialog).hasClass('modal-dialog-scrollable') && o ? (o.scrollTop = 0) : (this._element.scrollTop = 0), + i && a.reflow(this._element), + e(this._element).addClass('show'), + this._config.focus && this._enforceFocus(); + var s = e.Event('shown.bs.modal', { relatedTarget: t }), + r = function () { + n._config.focus && n._element.focus(), (n._isTransitioning = !1), e(n._element).trigger(s); + }; + if (i) { + var l = a.getTransitionDurationFromElement(this._dialog); + e(this._dialog).one(a.TRANSITION_END, r).emulateTransitionEnd(l); + } else r(); + }), + (n._enforceFocus = function () { + var t = this; + e(document) + .off('focusin.bs.modal') + .on('focusin.bs.modal', function (n) { + document !== n.target && t._element !== n.target && 0 === e(t._element).has(n.target).length && t._element.focus(); + }); + }), + (n._setEscapeEvent = function () { + var t = this; + this._isShown + ? e(this._element).on('keydown.dismiss.bs.modal', function (e) { + t._config.keyboard && 27 === e.which + ? (e.preventDefault(), t.hide()) + : t._config.keyboard || 27 !== e.which || t._triggerBackdropTransition(); + }) + : this._isShown || e(this._element).off('keydown.dismiss.bs.modal'); + }), + (n._setResizeEvent = function () { + var t = this; + this._isShown + ? e(window).on('resize.bs.modal', function (e) { + return t.handleUpdate(e); + }) + : e(window).off('resize.bs.modal'); + }), + (n._hideModal = function () { + var t = this; + (this._element.style.display = 'none'), + this._element.setAttribute('aria-hidden', !0), + this._element.removeAttribute('aria-modal'), + this._element.removeAttribute('role'), + (this._isTransitioning = !1), + this._showBackdrop(function () { + e(document.body).removeClass('modal-open'), + t._resetAdjustments(), + t._resetScrollbar(), + e(t._element).trigger('hidden.bs.modal'); + }); + }), + (n._removeBackdrop = function () { + this._backdrop && (e(this._backdrop).remove(), (this._backdrop = null)); + }), + (n._showBackdrop = function (t) { + var n = this, + i = e(this._element).hasClass('fade') ? 'fade' : ''; + if (this._isShown && this._config.backdrop) { + if ( + ((this._backdrop = document.createElement('div')), + (this._backdrop.className = 'modal-backdrop'), + i && this._backdrop.classList.add(i), + e(this._backdrop).appendTo(document.body), + e(this._element).on('click.dismiss.bs.modal', function (t) { + n._ignoreBackdropClick ? (n._ignoreBackdropClick = !1) : t.target === t.currentTarget && n._triggerBackdropTransition(); + }), + i && a.reflow(this._backdrop), + e(this._backdrop).addClass('show'), + !t) + ) + return; + if (!i) return void t(); + var o = a.getTransitionDurationFromElement(this._backdrop); + e(this._backdrop).one(a.TRANSITION_END, t).emulateTransitionEnd(o); + } else if (!this._isShown && this._backdrop) { + e(this._backdrop).removeClass('show'); + var s = function () { + n._removeBackdrop(), t && t(); + }; + if (e(this._element).hasClass('fade')) { + var r = a.getTransitionDurationFromElement(this._backdrop); + e(this._backdrop).one(a.TRANSITION_END, s).emulateTransitionEnd(r); + } else s(); + } else t && t(); + }), + (n._adjustDialog = function () { + var t = this._element.scrollHeight > document.documentElement.clientHeight; + !this._isBodyOverflowing && t && (this._element.style.paddingLeft = this._scrollbarWidth + 'px'), + this._isBodyOverflowing && !t && (this._element.style.paddingRight = this._scrollbarWidth + 'px'); + }), + (n._resetAdjustments = function () { + (this._element.style.paddingLeft = ''), (this._element.style.paddingRight = ''); + }), + (n._checkScrollbar = function () { + var t = document.body.getBoundingClientRect(); + (this._isBodyOverflowing = Math.round(t.left + t.right) < window.innerWidth), (this._scrollbarWidth = this._getScrollbarWidth()); + }), + (n._setScrollbar = function () { + var t = this; + if (this._isBodyOverflowing) { + var n = [].slice.call(document.querySelectorAll('.fixed-top, .fixed-bottom, .is-fixed, .sticky-top')), + i = [].slice.call(document.querySelectorAll('.sticky-top')); + e(n).each(function (n, i) { + var o = i.style.paddingRight, + s = e(i).css('padding-right'); + e(i) + .data('padding-right', o) + .css('padding-right', parseFloat(s) + t._scrollbarWidth + 'px'); + }), + e(i).each(function (n, i) { + var o = i.style.marginRight, + s = e(i).css('margin-right'); + e(i) + .data('margin-right', o) + .css('margin-right', parseFloat(s) - t._scrollbarWidth + 'px'); + }); + var o = document.body.style.paddingRight, + s = e(document.body).css('padding-right'); + e(document.body) + .data('padding-right', o) + .css('padding-right', parseFloat(s) + this._scrollbarWidth + 'px'); + } + e(document.body).addClass('modal-open'); + }), + (n._resetScrollbar = function () { + var t = [].slice.call(document.querySelectorAll('.fixed-top, .fixed-bottom, .is-fixed, .sticky-top')); + e(t).each(function (t, n) { + var i = e(n).data('padding-right'); + e(n).removeData('padding-right'), (n.style.paddingRight = i || ''); + }); + var n = [].slice.call(document.querySelectorAll('.sticky-top')); + e(n).each(function (t, n) { + var i = e(n).data('margin-right'); + 'undefined' != typeof i && e(n).css('margin-right', i).removeData('margin-right'); + }); + var i = e(document.body).data('padding-right'); + e(document.body).removeData('padding-right'), (document.body.style.paddingRight = i || ''); + }), + (n._getScrollbarWidth = function () { + var t = document.createElement('div'); + (t.className = 'modal-scrollbar-measure'), document.body.appendChild(t); + var e = t.getBoundingClientRect().width - t.clientWidth; + return document.body.removeChild(t), e; + }), + (t._jQueryInterface = function (n, i) { + return this.each(function () { + var o = e(this).data('bs.modal'), + r = s({}, j, e(this).data(), 'object' == typeof n && n ? n : {}); + if ((o || ((o = new t(this, r)), e(this).data('bs.modal', o)), 'string' == typeof n)) { + if ('undefined' == typeof o[n]) throw new TypeError('No method named "' + n + '"'); + o[n](i); + } else r.show && o.show(i); + }); + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + { + key: 'Default', + get: function () { + return j; + }, + }, + ]), + t + ); + })(); + e(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (t) { + var n, + i = this, + o = a.getSelectorFromElement(this); + o && (n = document.querySelector(o)); + var r = e(n).data('bs.modal') ? 'toggle' : s({}, e(n).data(), e(this).data()); + ('A' !== this.tagName && 'AREA' !== this.tagName) || t.preventDefault(); + var l = e(n).one('show.bs.modal', function (t) { + t.isDefaultPrevented() || + l.one('hidden.bs.modal', function () { + e(i).is(':visible') && i.focus(); + }); + }); + P._jQueryInterface.call(e(n), r, this); + }), + (e.fn.modal = P._jQueryInterface), + (e.fn.modal.Constructor = P), + (e.fn.modal.noConflict = function () { + return (e.fn.modal = O), P._jQueryInterface; + }); + var R = ['background', 'cite', 'href', 'itemtype', 'longdesc', 'poster', 'src', 'xlink:href'], + L = { + '*': ['class', 'dir', 'id', 'lang', 'role', /^aria-[\w-]*$/i], + a: ['target', 'href', 'title', 'rel'], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ['src', 'srcset', 'alt', 'title', 'width', 'height'], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [], + }, + q = /^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/gi, + F = + /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i; + function Q(t, e, n) { + if (0 === t.length) return t; + if (n && 'function' == typeof n) return n(t); + for ( + var i = new window.DOMParser().parseFromString(t, 'text/html'), + o = Object.keys(e), + s = [].slice.call(i.body.querySelectorAll('*')), + r = function (t, n) { + var i = s[t], + r = i.nodeName.toLowerCase(); + if (-1 === o.indexOf(i.nodeName.toLowerCase())) return i.parentNode.removeChild(i), 'continue'; + var a = [].slice.call(i.attributes), + l = [].concat(e['*'] || [], e[r] || []); + a.forEach(function (t) { + (function (t, e) { + var n = t.nodeName.toLowerCase(); + if (-1 !== e.indexOf(n)) return -1 === R.indexOf(n) || Boolean(t.nodeValue.match(q) || t.nodeValue.match(F)); + for ( + var i = e.filter(function (t) { + return t instanceof RegExp; + }), + o = 0, + s = i.length; + o < s; + o++ + ) + if (n.match(i[o])) return !0; + return !1; + })(t, l) || i.removeAttribute(t.nodeName); + }); + }, + a = 0, + l = s.length; + a < l; + a++ + ) + r(a); + return i.body.innerHTML; + } + var B = 'tooltip', + H = e.fn[B], + U = new RegExp('(^|\\s)bs-tooltip\\S+', 'g'), + M = ['sanitize', 'whiteList', 'sanitizeFn'], + W = { + animation: 'boolean', + template: 'string', + title: '(string|element|function)', + trigger: 'string', + delay: '(number|object)', + html: 'boolean', + selector: '(string|boolean)', + placement: '(string|function)', + offset: '(number|string|function)', + container: '(string|element|boolean)', + fallbackPlacement: '(string|array)', + boundary: '(string|element)', + sanitize: 'boolean', + sanitizeFn: '(null|function)', + whiteList: 'object', + popperConfig: '(null|object)', + }, + V = { AUTO: 'auto', TOP: 'top', RIGHT: 'right', BOTTOM: 'bottom', LEFT: 'left' }, + z = { + animation: !0, + template: '<div class="tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner"></div></div>', + trigger: 'hover focus', + title: '', + delay: 0, + html: !1, + selector: !1, + placement: 'top', + offset: 0, + container: !1, + fallbackPlacement: 'flip', + boundary: 'scrollParent', + sanitize: !0, + sanitizeFn: null, + whiteList: L, + popperConfig: null, + }, + K = { + HIDE: 'hide.bs.tooltip', + HIDDEN: 'hidden.bs.tooltip', + SHOW: 'show.bs.tooltip', + SHOWN: 'shown.bs.tooltip', + INSERTED: 'inserted.bs.tooltip', + CLICK: 'click.bs.tooltip', + FOCUSIN: 'focusin.bs.tooltip', + FOCUSOUT: 'focusout.bs.tooltip', + MOUSEENTER: 'mouseenter.bs.tooltip', + MOUSELEAVE: 'mouseleave.bs.tooltip', + }, + X = (function () { + function t(t, e) { + if ('undefined' == typeof n) throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)"); + (this._isEnabled = !0), + (this._timeout = 0), + (this._hoverState = ''), + (this._activeTrigger = {}), + (this._popper = null), + (this.element = t), + (this.config = this._getConfig(e)), + (this.tip = null), + this._setListeners(); + } + var i = t.prototype; + return ( + (i.enable = function () { + this._isEnabled = !0; + }), + (i.disable = function () { + this._isEnabled = !1; + }), + (i.toggleEnabled = function () { + this._isEnabled = !this._isEnabled; + }), + (i.toggle = function (t) { + if (this._isEnabled) + if (t) { + var n = this.constructor.DATA_KEY, + i = e(t.currentTarget).data(n); + i || ((i = new this.constructor(t.currentTarget, this._getDelegateConfig())), e(t.currentTarget).data(n, i)), + (i._activeTrigger.click = !i._activeTrigger.click), + i._isWithActiveTrigger() ? i._enter(null, i) : i._leave(null, i); + } else { + if (e(this.getTipElement()).hasClass('show')) return void this._leave(null, this); + this._enter(null, this); + } + }), + (i.dispose = function () { + clearTimeout(this._timeout), + e.removeData(this.element, this.constructor.DATA_KEY), + e(this.element).off(this.constructor.EVENT_KEY), + e(this.element).closest('.modal').off('hide.bs.modal', this._hideModalHandler), + this.tip && e(this.tip).remove(), + (this._isEnabled = null), + (this._timeout = null), + (this._hoverState = null), + (this._activeTrigger = null), + this._popper && this._popper.destroy(), + (this._popper = null), + (this.element = null), + (this.config = null), + (this.tip = null); + }), + (i.show = function () { + var t = this; + if ('none' === e(this.element).css('display')) throw new Error('Please use show on visible elements'); + var i = e.Event(this.constructor.Event.SHOW); + if (this.isWithContent() && this._isEnabled) { + e(this.element).trigger(i); + var o = a.findShadowRoot(this.element), + s = e.contains(null !== o ? o : this.element.ownerDocument.documentElement, this.element); + if (i.isDefaultPrevented() || !s) return; + var r = this.getTipElement(), + l = a.getUID(this.constructor.NAME); + r.setAttribute('id', l), + this.element.setAttribute('aria-describedby', l), + this.setContent(), + this.config.animation && e(r).addClass('fade'); + var c = 'function' == typeof this.config.placement ? this.config.placement.call(this, r, this.element) : this.config.placement, + h = this._getAttachment(c); + this.addAttachmentClass(h); + var u = this._getContainer(); + e(r).data(this.constructor.DATA_KEY, this), + e.contains(this.element.ownerDocument.documentElement, this.tip) || e(r).appendTo(u), + e(this.element).trigger(this.constructor.Event.INSERTED), + (this._popper = new n(this.element, r, this._getPopperConfig(h))), + e(r).addClass('show'), + 'ontouchstart' in document.documentElement && e(document.body).children().on('mouseover', null, e.noop); + var d = function () { + t.config.animation && t._fixTransition(); + var n = t._hoverState; + (t._hoverState = null), e(t.element).trigger(t.constructor.Event.SHOWN), 'out' === n && t._leave(null, t); + }; + if (e(this.tip).hasClass('fade')) { + var f = a.getTransitionDurationFromElement(this.tip); + e(this.tip).one(a.TRANSITION_END, d).emulateTransitionEnd(f); + } else d(); + } + }), + (i.hide = function (t) { + var n = this, + i = this.getTipElement(), + o = e.Event(this.constructor.Event.HIDE), + s = function () { + 'show' !== n._hoverState && i.parentNode && i.parentNode.removeChild(i), + n._cleanTipClass(), + n.element.removeAttribute('aria-describedby'), + e(n.element).trigger(n.constructor.Event.HIDDEN), + null !== n._popper && n._popper.destroy(), + t && t(); + }; + if ((e(this.element).trigger(o), !o.isDefaultPrevented())) { + if ( + (e(i).removeClass('show'), + 'ontouchstart' in document.documentElement && e(document.body).children().off('mouseover', null, e.noop), + (this._activeTrigger.click = !1), + (this._activeTrigger.focus = !1), + (this._activeTrigger.hover = !1), + e(this.tip).hasClass('fade')) + ) { + var r = a.getTransitionDurationFromElement(i); + e(i).one(a.TRANSITION_END, s).emulateTransitionEnd(r); + } else s(); + this._hoverState = ''; + } + }), + (i.update = function () { + null !== this._popper && this._popper.scheduleUpdate(); + }), + (i.isWithContent = function () { + return Boolean(this.getTitle()); + }), + (i.addAttachmentClass = function (t) { + e(this.getTipElement()).addClass('bs-tooltip-' + t); + }), + (i.getTipElement = function () { + return (this.tip = this.tip || e(this.config.template)[0]), this.tip; + }), + (i.setContent = function () { + var t = this.getTipElement(); + this.setElementContent(e(t.querySelectorAll('.tooltip-inner')), this.getTitle()), e(t).removeClass('fade show'); + }), + (i.setElementContent = function (t, n) { + 'object' != typeof n || (!n.nodeType && !n.jquery) + ? this.config.html + ? (this.config.sanitize && (n = Q(n, this.config.whiteList, this.config.sanitizeFn)), t.html(n)) + : t.text(n) + : this.config.html + ? e(n).parent().is(t) || t.empty().append(n) + : t.text(e(n).text()); + }), + (i.getTitle = function () { + var t = this.element.getAttribute('data-original-title'); + return t || (t = 'function' == typeof this.config.title ? this.config.title.call(this.element) : this.config.title), t; + }), + (i._getPopperConfig = function (t) { + var e = this; + return s( + {}, + { + placement: t, + modifiers: { + offset: this._getOffset(), + flip: { behavior: this.config.fallbackPlacement }, + arrow: { element: '.arrow' }, + preventOverflow: { boundariesElement: this.config.boundary }, + }, + onCreate: function (t) { + t.originalPlacement !== t.placement && e._handlePopperPlacementChange(t); + }, + onUpdate: function (t) { + return e._handlePopperPlacementChange(t); + }, + }, + this.config.popperConfig + ); + }), + (i._getOffset = function () { + var t = this, + e = {}; + return ( + 'function' == typeof this.config.offset + ? (e.fn = function (e) { + return (e.offsets = s({}, e.offsets, t.config.offset(e.offsets, t.element) || {})), e; + }) + : (e.offset = this.config.offset), + e + ); + }), + (i._getContainer = function () { + return !1 === this.config.container + ? document.body + : a.isElement(this.config.container) + ? e(this.config.container) + : e(document).find(this.config.container); + }), + (i._getAttachment = function (t) { + return V[t.toUpperCase()]; + }), + (i._setListeners = function () { + var t = this; + this.config.trigger.split(' ').forEach(function (n) { + if ('click' === n) + e(t.element).on(t.constructor.Event.CLICK, t.config.selector, function (e) { + return t.toggle(e); + }); + else if ('manual' !== n) { + var i = 'hover' === n ? t.constructor.Event.MOUSEENTER : t.constructor.Event.FOCUSIN, + o = 'hover' === n ? t.constructor.Event.MOUSELEAVE : t.constructor.Event.FOCUSOUT; + e(t.element) + .on(i, t.config.selector, function (e) { + return t._enter(e); + }) + .on(o, t.config.selector, function (e) { + return t._leave(e); + }); + } + }), + (this._hideModalHandler = function () { + t.element && t.hide(); + }), + e(this.element).closest('.modal').on('hide.bs.modal', this._hideModalHandler), + this.config.selector ? (this.config = s({}, this.config, { trigger: 'manual', selector: '' })) : this._fixTitle(); + }), + (i._fixTitle = function () { + var t = typeof this.element.getAttribute('data-original-title'); + (this.element.getAttribute('title') || 'string' !== t) && + (this.element.setAttribute('data-original-title', this.element.getAttribute('title') || ''), + this.element.setAttribute('title', '')); + }), + (i._enter = function (t, n) { + var i = this.constructor.DATA_KEY; + (n = n || e(t.currentTarget).data(i)) || + ((n = new this.constructor(t.currentTarget, this._getDelegateConfig())), e(t.currentTarget).data(i, n)), + t && (n._activeTrigger['focusin' === t.type ? 'focus' : 'hover'] = !0), + e(n.getTipElement()).hasClass('show') || 'show' === n._hoverState + ? (n._hoverState = 'show') + : (clearTimeout(n._timeout), + (n._hoverState = 'show'), + n.config.delay && n.config.delay.show + ? (n._timeout = setTimeout(function () { + 'show' === n._hoverState && n.show(); + }, n.config.delay.show)) + : n.show()); + }), + (i._leave = function (t, n) { + var i = this.constructor.DATA_KEY; + (n = n || e(t.currentTarget).data(i)) || + ((n = new this.constructor(t.currentTarget, this._getDelegateConfig())), e(t.currentTarget).data(i, n)), + t && (n._activeTrigger['focusout' === t.type ? 'focus' : 'hover'] = !1), + n._isWithActiveTrigger() || + (clearTimeout(n._timeout), + (n._hoverState = 'out'), + n.config.delay && n.config.delay.hide + ? (n._timeout = setTimeout(function () { + 'out' === n._hoverState && n.hide(); + }, n.config.delay.hide)) + : n.hide()); + }), + (i._isWithActiveTrigger = function () { + for (var t in this._activeTrigger) if (this._activeTrigger[t]) return !0; + return !1; + }), + (i._getConfig = function (t) { + var n = e(this.element).data(); + return ( + Object.keys(n).forEach(function (t) { + -1 !== M.indexOf(t) && delete n[t]; + }), + 'number' == typeof (t = s({}, this.constructor.Default, n, 'object' == typeof t && t ? t : {})).delay && + (t.delay = { show: t.delay, hide: t.delay }), + 'number' == typeof t.title && (t.title = t.title.toString()), + 'number' == typeof t.content && (t.content = t.content.toString()), + a.typeCheckConfig(B, t, this.constructor.DefaultType), + t.sanitize && (t.template = Q(t.template, t.whiteList, t.sanitizeFn)), + t + ); + }), + (i._getDelegateConfig = function () { + var t = {}; + if (this.config) for (var e in this.config) this.constructor.Default[e] !== this.config[e] && (t[e] = this.config[e]); + return t; + }), + (i._cleanTipClass = function () { + var t = e(this.getTipElement()), + n = t.attr('class').match(U); + null !== n && n.length && t.removeClass(n.join('')); + }), + (i._handlePopperPlacementChange = function (t) { + (this.tip = t.instance.popper), this._cleanTipClass(), this.addAttachmentClass(this._getAttachment(t.placement)); + }), + (i._fixTransition = function () { + var t = this.getTipElement(), + n = this.config.animation; + null === t.getAttribute('x-placement') && + (e(t).removeClass('fade'), (this.config.animation = !1), this.hide(), this.show(), (this.config.animation = n)); + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this).data('bs.tooltip'), + o = 'object' == typeof n && n; + if ((i || !/dispose|hide/.test(n)) && (i || ((i = new t(this, o)), e(this).data('bs.tooltip', i)), 'string' == typeof n)) { + if ('undefined' == typeof i[n]) throw new TypeError('No method named "' + n + '"'); + i[n](); + } + }); + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + { + key: 'Default', + get: function () { + return z; + }, + }, + { + key: 'NAME', + get: function () { + return B; + }, + }, + { + key: 'DATA_KEY', + get: function () { + return 'bs.tooltip'; + }, + }, + { + key: 'Event', + get: function () { + return K; + }, + }, + { + key: 'EVENT_KEY', + get: function () { + return '.bs.tooltip'; + }, + }, + { + key: 'DefaultType', + get: function () { + return W; + }, + }, + ]), + t + ); + })(); + (e.fn[B] = X._jQueryInterface), + (e.fn[B].Constructor = X), + (e.fn[B].noConflict = function () { + return (e.fn[B] = H), X._jQueryInterface; + }); + var Y = 'popover', + $ = e.fn[Y], + J = new RegExp('(^|\\s)bs-popover\\S+', 'g'), + G = s({}, X.Default, { + placement: 'right', + trigger: 'click', + content: '', + template: + '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-header"></h3><div class="popover-body"></div></div>', + }), + Z = s({}, X.DefaultType, { content: '(string|element|function)' }), + tt = { + HIDE: 'hide.bs.popover', + HIDDEN: 'hidden.bs.popover', + SHOW: 'show.bs.popover', + SHOWN: 'shown.bs.popover', + INSERTED: 'inserted.bs.popover', + CLICK: 'click.bs.popover', + FOCUSIN: 'focusin.bs.popover', + FOCUSOUT: 'focusout.bs.popover', + MOUSEENTER: 'mouseenter.bs.popover', + MOUSELEAVE: 'mouseleave.bs.popover', + }, + et = (function (t) { + var n, i; + function s() { + return t.apply(this, arguments) || this; + } + (i = t), ((n = s).prototype = Object.create(i.prototype)), (n.prototype.constructor = n), (n.__proto__ = i); + var r = s.prototype; + return ( + (r.isWithContent = function () { + return this.getTitle() || this._getContent(); + }), + (r.addAttachmentClass = function (t) { + e(this.getTipElement()).addClass('bs-popover-' + t); + }), + (r.getTipElement = function () { + return (this.tip = this.tip || e(this.config.template)[0]), this.tip; + }), + (r.setContent = function () { + var t = e(this.getTipElement()); + this.setElementContent(t.find('.popover-header'), this.getTitle()); + var n = this._getContent(); + 'function' == typeof n && (n = n.call(this.element)), + this.setElementContent(t.find('.popover-body'), n), + t.removeClass('fade show'); + }), + (r._getContent = function () { + return this.element.getAttribute('data-content') || this.config.content; + }), + (r._cleanTipClass = function () { + var t = e(this.getTipElement()), + n = t.attr('class').match(J); + null !== n && n.length > 0 && t.removeClass(n.join('')); + }), + (s._jQueryInterface = function (t) { + return this.each(function () { + var n = e(this).data('bs.popover'), + i = 'object' == typeof t ? t : null; + if ((n || !/dispose|hide/.test(t)) && (n || ((n = new s(this, i)), e(this).data('bs.popover', n)), 'string' == typeof t)) { + if ('undefined' == typeof n[t]) throw new TypeError('No method named "' + t + '"'); + n[t](); + } + }); + }), + o(s, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + { + key: 'Default', + get: function () { + return G; + }, + }, + { + key: 'NAME', + get: function () { + return Y; + }, + }, + { + key: 'DATA_KEY', + get: function () { + return 'bs.popover'; + }, + }, + { + key: 'Event', + get: function () { + return tt; + }, + }, + { + key: 'EVENT_KEY', + get: function () { + return '.bs.popover'; + }, + }, + { + key: 'DefaultType', + get: function () { + return Z; + }, + }, + ]), + s + ); + })(X); + (e.fn[Y] = et._jQueryInterface), + (e.fn[Y].Constructor = et), + (e.fn[Y].noConflict = function () { + return (e.fn[Y] = $), et._jQueryInterface; + }); + var nt = 'scrollspy', + it = e.fn[nt], + ot = { offset: 10, method: 'auto', target: '' }, + st = { offset: 'number', method: 'string', target: '(string|element)' }, + rt = (function () { + function t(t, n) { + var i = this; + (this._element = t), + (this._scrollElement = 'BODY' === t.tagName ? window : t), + (this._config = this._getConfig(n)), + (this._selector = + this._config.target + ' .nav-link,' + this._config.target + ' .list-group-item,' + this._config.target + ' .dropdown-item'), + (this._offsets = []), + (this._targets = []), + (this._activeTarget = null), + (this._scrollHeight = 0), + e(this._scrollElement).on('scroll.bs.scrollspy', function (t) { + return i._process(t); + }), + this.refresh(), + this._process(); + } + var n = t.prototype; + return ( + (n.refresh = function () { + var t = this, + n = this._scrollElement === this._scrollElement.window ? 'offset' : 'position', + i = 'auto' === this._config.method ? n : this._config.method, + o = 'position' === i ? this._getScrollTop() : 0; + (this._offsets = []), + (this._targets = []), + (this._scrollHeight = this._getScrollHeight()), + [].slice + .call(document.querySelectorAll(this._selector)) + .map(function (t) { + var n, + s = a.getSelectorFromElement(t); + if ((s && (n = document.querySelector(s)), n)) { + var r = n.getBoundingClientRect(); + if (r.width || r.height) return [e(n)[i]().top + o, s]; + } + return null; + }) + .filter(function (t) { + return t; + }) + .sort(function (t, e) { + return t[0] - e[0]; + }) + .forEach(function (e) { + t._offsets.push(e[0]), t._targets.push(e[1]); + }); + }), + (n.dispose = function () { + e.removeData(this._element, 'bs.scrollspy'), + e(this._scrollElement).off('.bs.scrollspy'), + (this._element = null), + (this._scrollElement = null), + (this._config = null), + (this._selector = null), + (this._offsets = null), + (this._targets = null), + (this._activeTarget = null), + (this._scrollHeight = null); + }), + (n._getConfig = function (t) { + if ('string' != typeof (t = s({}, ot, 'object' == typeof t && t ? t : {})).target && a.isElement(t.target)) { + var n = e(t.target).attr('id'); + n || ((n = a.getUID(nt)), e(t.target).attr('id', n)), (t.target = '#' + n); + } + return a.typeCheckConfig(nt, t, st), t; + }), + (n._getScrollTop = function () { + return this._scrollElement === window ? this._scrollElement.pageYOffset : this._scrollElement.scrollTop; + }), + (n._getScrollHeight = function () { + return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, document.documentElement.scrollHeight); + }), + (n._getOffsetHeight = function () { + return this._scrollElement === window ? window.innerHeight : this._scrollElement.getBoundingClientRect().height; + }), + (n._process = function () { + var t = this._getScrollTop() + this._config.offset, + e = this._getScrollHeight(), + n = this._config.offset + e - this._getOffsetHeight(); + if ((this._scrollHeight !== e && this.refresh(), t >= n)) { + var i = this._targets[this._targets.length - 1]; + this._activeTarget !== i && this._activate(i); + } else { + if (this._activeTarget && t < this._offsets[0] && this._offsets[0] > 0) return (this._activeTarget = null), void this._clear(); + for (var o = this._offsets.length; o--; ) { + this._activeTarget !== this._targets[o] && + t >= this._offsets[o] && + ('undefined' == typeof this._offsets[o + 1] || t < this._offsets[o + 1]) && + this._activate(this._targets[o]); + } + } + }), + (n._activate = function (t) { + (this._activeTarget = t), this._clear(); + var n = this._selector.split(',').map(function (e) { + return e + '[data-target="' + t + '"],' + e + '[href="' + t + '"]'; + }), + i = e([].slice.call(document.querySelectorAll(n.join(',')))); + i.hasClass('dropdown-item') + ? (i.closest('.dropdown').find('.dropdown-toggle').addClass('active'), i.addClass('active')) + : (i.addClass('active'), + i.parents('.nav, .list-group').prev('.nav-link, .list-group-item').addClass('active'), + i.parents('.nav, .list-group').prev('.nav-item').children('.nav-link').addClass('active')), + e(this._scrollElement).trigger('activate.bs.scrollspy', { relatedTarget: t }); + }), + (n._clear = function () { + [].slice + .call(document.querySelectorAll(this._selector)) + .filter(function (t) { + return t.classList.contains('active'); + }) + .forEach(function (t) { + return t.classList.remove('active'); + }); + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this).data('bs.scrollspy'); + if ((i || ((i = new t(this, 'object' == typeof n && n)), e(this).data('bs.scrollspy', i)), 'string' == typeof n)) { + if ('undefined' == typeof i[n]) throw new TypeError('No method named "' + n + '"'); + i[n](); + } + }); + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + { + key: 'Default', + get: function () { + return ot; + }, + }, + ]), + t + ); + })(); + e(window).on('load.bs.scrollspy.data-api', function () { + for (var t = [].slice.call(document.querySelectorAll('[data-spy="scroll"]')), n = t.length; n--; ) { + var i = e(t[n]); + rt._jQueryInterface.call(i, i.data()); + } + }), + (e.fn[nt] = rt._jQueryInterface), + (e.fn[nt].Constructor = rt), + (e.fn[nt].noConflict = function () { + return (e.fn[nt] = it), rt._jQueryInterface; + }); + var at = e.fn.tab, + lt = (function () { + function t(t) { + this._element = t; + } + var n = t.prototype; + return ( + (n.show = function () { + var t = this; + if ( + !( + (this._element.parentNode && + this._element.parentNode.nodeType === Node.ELEMENT_NODE && + e(this._element).hasClass('active')) || + e(this._element).hasClass('disabled') + ) + ) { + var n, + i, + o = e(this._element).closest('.nav, .list-group')[0], + s = a.getSelectorFromElement(this._element); + if (o) { + var r = 'UL' === o.nodeName || 'OL' === o.nodeName ? '> li > .active' : '.active'; + i = (i = e.makeArray(e(o).find(r)))[i.length - 1]; + } + var l = e.Event('hide.bs.tab', { relatedTarget: this._element }), + c = e.Event('show.bs.tab', { relatedTarget: i }); + if ((i && e(i).trigger(l), e(this._element).trigger(c), !c.isDefaultPrevented() && !l.isDefaultPrevented())) { + s && (n = document.querySelector(s)), this._activate(this._element, o); + var h = function () { + var n = e.Event('hidden.bs.tab', { relatedTarget: t._element }), + o = e.Event('shown.bs.tab', { relatedTarget: i }); + e(i).trigger(n), e(t._element).trigger(o); + }; + n ? this._activate(n, n.parentNode, h) : h(); + } + } + }), + (n.dispose = function () { + e.removeData(this._element, 'bs.tab'), (this._element = null); + }), + (n._activate = function (t, n, i) { + var o = this, + s = (!n || ('UL' !== n.nodeName && 'OL' !== n.nodeName) ? e(n).children('.active') : e(n).find('> li > .active'))[0], + r = i && s && e(s).hasClass('fade'), + l = function () { + return o._transitionComplete(t, s, i); + }; + if (s && r) { + var c = a.getTransitionDurationFromElement(s); + e(s).removeClass('show').one(a.TRANSITION_END, l).emulateTransitionEnd(c); + } else l(); + }), + (n._transitionComplete = function (t, n, i) { + if (n) { + e(n).removeClass('active'); + var o = e(n.parentNode).find('> .dropdown-menu .active')[0]; + o && e(o).removeClass('active'), 'tab' === n.getAttribute('role') && n.setAttribute('aria-selected', !1); + } + if ( + (e(t).addClass('active'), + 'tab' === t.getAttribute('role') && t.setAttribute('aria-selected', !0), + a.reflow(t), + t.classList.contains('fade') && t.classList.add('show'), + t.parentNode && e(t.parentNode).hasClass('dropdown-menu')) + ) { + var s = e(t).closest('.dropdown')[0]; + if (s) { + var r = [].slice.call(s.querySelectorAll('.dropdown-toggle')); + e(r).addClass('active'); + } + t.setAttribute('aria-expanded', !0); + } + i && i(); + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this), + o = i.data('bs.tab'); + if ((o || ((o = new t(this)), i.data('bs.tab', o)), 'string' == typeof n)) { + if ('undefined' == typeof o[n]) throw new TypeError('No method named "' + n + '"'); + o[n](); + } + }); + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + ]), + t + ); + })(); + e(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]', function (t) { + t.preventDefault(), lt._jQueryInterface.call(e(this), 'show'); + }), + (e.fn.tab = lt._jQueryInterface), + (e.fn.tab.Constructor = lt), + (e.fn.tab.noConflict = function () { + return (e.fn.tab = at), lt._jQueryInterface; + }); + var ct = e.fn.toast, + ht = { animation: 'boolean', autohide: 'boolean', delay: 'number' }, + ut = { animation: !0, autohide: !0, delay: 500 }, + dt = (function () { + function t(t, e) { + (this._element = t), (this._config = this._getConfig(e)), (this._timeout = null), this._setListeners(); + } + var n = t.prototype; + return ( + (n.show = function () { + var t = this, + n = e.Event('show.bs.toast'); + if ((e(this._element).trigger(n), !n.isDefaultPrevented())) { + this._clearTimeout(), this._config.animation && this._element.classList.add('fade'); + var i = function () { + t._element.classList.remove('showing'), + t._element.classList.add('show'), + e(t._element).trigger('shown.bs.toast'), + t._config.autohide && + (t._timeout = setTimeout(function () { + t.hide(); + }, t._config.delay)); + }; + if ( + (this._element.classList.remove('hide'), + a.reflow(this._element), + this._element.classList.add('showing'), + this._config.animation) + ) { + var o = a.getTransitionDurationFromElement(this._element); + e(this._element).one(a.TRANSITION_END, i).emulateTransitionEnd(o); + } else i(); + } + }), + (n.hide = function () { + if (this._element.classList.contains('show')) { + var t = e.Event('hide.bs.toast'); + e(this._element).trigger(t), t.isDefaultPrevented() || this._close(); + } + }), + (n.dispose = function () { + this._clearTimeout(), + this._element.classList.contains('show') && this._element.classList.remove('show'), + e(this._element).off('click.dismiss.bs.toast'), + e.removeData(this._element, 'bs.toast'), + (this._element = null), + (this._config = null); + }), + (n._getConfig = function (t) { + return ( + (t = s({}, ut, e(this._element).data(), 'object' == typeof t && t ? t : {})), + a.typeCheckConfig('toast', t, this.constructor.DefaultType), + t + ); + }), + (n._setListeners = function () { + var t = this; + e(this._element).on('click.dismiss.bs.toast', '[data-dismiss="toast"]', function () { + return t.hide(); + }); + }), + (n._close = function () { + var t = this, + n = function () { + t._element.classList.add('hide'), e(t._element).trigger('hidden.bs.toast'); + }; + if ((this._element.classList.remove('show'), this._config.animation)) { + var i = a.getTransitionDurationFromElement(this._element); + e(this._element).one(a.TRANSITION_END, n).emulateTransitionEnd(i); + } else n(); + }), + (n._clearTimeout = function () { + clearTimeout(this._timeout), (this._timeout = null); + }), + (t._jQueryInterface = function (n) { + return this.each(function () { + var i = e(this), + o = i.data('bs.toast'); + if ((o || ((o = new t(this, 'object' == typeof n && n)), i.data('bs.toast', o)), 'string' == typeof n)) { + if ('undefined' == typeof o[n]) throw new TypeError('No method named "' + n + '"'); + o[n](this); + } + }); + }), + o(t, null, [ + { + key: 'VERSION', + get: function () { + return '4.5.2'; + }, + }, + { + key: 'DefaultType', + get: function () { + return ht; + }, + }, + { + key: 'Default', + get: function () { + return ut; + }, + }, + ]), + t + ); + })(); + (e.fn.toast = dt._jQueryInterface), + (e.fn.toast.Constructor = dt), + (e.fn.toast.noConflict = function () { + return (e.fn.toast = ct), dt._jQueryInterface; + }), + (t.Alert = h), + (t.Button = d), + (t.Carousel = b), + (t.Collapse = C), + (t.Dropdown = I), + (t.Modal = P), + (t.Popover = et), + (t.Scrollspy = rt), + (t.Tab = lt), + (t.Toast = dt), + (t.Tooltip = X), + (t.Util = a), + Object.defineProperty(t, '__esModule', { value: !0 }); +}); +//# sourceMappingURL=bootstrap.min.js.map diff --git a/src/main/webapp/content/js/duplicate/README.md b/src/main/webapp/content/js/duplicate/README.md index 6295143102ac047ddb35ec61f69be3197eb862e5..aa69692a22898d2c78a42c1f884609b87e3995fa 100644 --- a/src/main/webapp/content/js/duplicate/README.md +++ b/src/main/webapp/content/js/duplicate/README.md @@ -1,9 +1,11 @@ This file is a folder for javascript files from other node modules. Typically they are duplicates. If somebody finds a better way to include this scripts: You are welcome. Things that did not work: + - https://basarat.gitbook.io/typescript/type-system/migrating - importing js-files via vendor.ts - importing js-files via angular.json Other problems + - highlighting with prism is not yet supported :-( diff --git a/src/main/webapp/content/js/duplicate/components/prism-java.min.js b/src/main/webapp/content/js/duplicate/components/prism-java.min.js index 21a5b505344c829befd9a2e8061f0db0349b39a1..a6a332af8bad3c507fa8c450b6cfea7bd863f3cd 100644 --- a/src/main/webapp/content/js/duplicate/components/prism-java.min.js +++ b/src/main/webapp/content/js/duplicate/components/prism-java.min.js @@ -1 +1,40 @@ -!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",a={pattern:RegExp(n+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{"class-name":[a,{pattern:RegExp(n+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=())])"),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(\:\:\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!<keyword>)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(/<keyword>/g,function(){return t.source})),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism); \ No newline at end of file +!(function (e) { + var t = + /\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/, + n = '(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*', + a = { + pattern: RegExp(n + '[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b'), + lookbehind: !0, + inside: { namespace: { pattern: /^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/, inside: { punctuation: /\./ } }, punctuation: /\./ }, + }; + (e.languages.java = e.languages.extend('clike', { + 'class-name': [a, { pattern: RegExp(n + '[A-Z]\\w*(?=\\s+\\w+\\s*[;,=())])'), lookbehind: !0, inside: a.inside }], + keyword: t, + function: [e.languages.clike.function, { pattern: /(\:\:\s*)[a-z_]\w*/, lookbehind: !0 }], + number: + /\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i, + operator: { pattern: /(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m, lookbehind: !0 }, + })), + e.languages.insertBefore('java', 'string', { + 'triple-quoted-string': { pattern: /"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/, greedy: !0, alias: 'string' }, + }), + e.languages.insertBefore('java', 'class-name', { + annotation: { pattern: /(^|[^.])@\w+(?:\s*\.\s*\w+)*/, lookbehind: !0, alias: 'punctuation' }, + generics: { + pattern: /<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/, + inside: { 'class-name': a, keyword: t, punctuation: /[<>(),.:]/, operator: /[?&|]/ }, + }, + namespace: { + pattern: RegExp( + '(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!<keyword>)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?'.replace( + /<keyword>/g, + function () { + return t.source; + } + ) + ), + lookbehind: !0, + inside: { punctuation: /\./ }, + }, + }); +})(Prism); diff --git a/src/main/webapp/content/js/duplicate/components/prism-javascript.min.js b/src/main/webapp/content/js/duplicate/components/prism-javascript.min.js index 4a170a47b99787ad6185767d2db384a2b9285db9..e211d52764db7283a1464627f7557fb336df408f 100644 --- a/src/main/webapp/content/js/duplicate/components/prism-javascript.min.js +++ b/src/main/webapp/content/js/duplicate/components/prism-javascript.min.js @@ -1 +1,71 @@ -Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-flags":/[a-z]+$/,"regex-delimiter":/^\/|\/$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript; \ No newline at end of file +(Prism.languages.javascript = Prism.languages.extend('clike', { + 'class-name': [ + Prism.languages.clike['class-name'], + { pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/, lookbehind: !0 }, + ], + keyword: [ + { pattern: /((?:^|})\s*)(?:catch|finally)\b/, lookbehind: !0 }, + { + pattern: + /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, + lookbehind: !0, + }, + ], + function: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, + number: + /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/, + operator: /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/, +})), + (Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/), + Prism.languages.insertBefore('javascript', 'keyword', { + regex: { + pattern: + /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/, + lookbehind: !0, + greedy: !0, + inside: { + 'regex-source': { pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/, lookbehind: !0, alias: 'language-regex', inside: Prism.languages.regex }, + 'regex-flags': /[a-z]+$/, + 'regex-delimiter': /^\/|\/$/, + }, + }, + 'function-variable': { + pattern: + /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/, + alias: 'function', + }, + parameter: [ + { + pattern: + /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/, + lookbehind: !0, + inside: Prism.languages.javascript, + }, + { pattern: /(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i, inside: Prism.languages.javascript }, + { pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/, lookbehind: !0, inside: Prism.languages.javascript }, + { + pattern: + /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/, + lookbehind: !0, + inside: Prism.languages.javascript, + }, + ], + constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/, + }), + Prism.languages.insertBefore('javascript', 'string', { + 'template-string': { + pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/, + greedy: !0, + inside: { + 'template-punctuation': { pattern: /^`|`$/, alias: 'string' }, + interpolation: { + pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/, + lookbehind: !0, + inside: { 'interpolation-punctuation': { pattern: /^\${|}$/, alias: 'punctuation' }, rest: Prism.languages.javascript }, + }, + string: /[\s\S]+/, + }, + }, + }), + Prism.languages.markup && Prism.languages.markup.tag.addInlined('script', 'javascript'), + (Prism.languages.js = Prism.languages.javascript); diff --git a/src/main/webapp/content/js/duplicate/components/prism-json.js b/src/main/webapp/content/js/duplicate/components/prism-json.js index 07c4ea5dac6504a520fa4a81bd3bc5b0fd8a7c80..b7a3ae431d77fe4e99897a876a7b89eec98ac2c2 100644 --- a/src/main/webapp/content/js/duplicate/components/prism-json.js +++ b/src/main/webapp/content/js/duplicate/components/prism-json.js @@ -1,25 +1,25 @@ // https://www.json.org/json-en.html Prism.languages.json = { - 'property': { - pattern: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/, - greedy: true - }, - 'string': { - pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/, - greedy: true - }, - 'comment': { - pattern: /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/, - greedy: true - }, - 'number': /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i, - 'punctuation': /[{}[\],]/, - 'operator': /:/, - 'boolean': /\b(?:true|false)\b/, - 'null': { - pattern: /\bnull\b/, - alias: 'keyword' - } + property: { + pattern: /"(?:\\.|[^\\"\r\n])*"(?=\s*:)/, + greedy: true, + }, + string: { + pattern: /"(?:\\.|[^\\"\r\n])*"(?!\s*:)/, + greedy: true, + }, + comment: { + pattern: /\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/, + greedy: true, + }, + number: /-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i, + punctuation: /[{}[\],]/, + operator: /:/, + boolean: /\b(?:true|false)\b/, + null: { + pattern: /\bnull\b/, + alias: 'keyword', + }, }; Prism.languages.webmanifest = Prism.languages.json; diff --git a/src/main/webapp/content/js/duplicate/components/prism-python.min.js b/src/main/webapp/content/js/duplicate/components/prism-python.min.js index a43da8d681ab95060baefcf230f0cac27cd07a17..de39481a7c26b709a317dfa7ce8c08e905fa93c3 100644 --- a/src/main/webapp/content/js/duplicate/components/prism-python.min.js +++ b/src/main/webapp/content/js/duplicate/components/prism-python.min.js @@ -1 +1,34 @@ -Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},"string-interpolation":{pattern:/(?:f|rf|fr)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:{{)*){(?!{)(?:[^{}]|{(?!{)(?:[^{}]|{(?!{)(?:[^{}])+})+})+}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=}$)/,lookbehind:!0},"conversion-option":{pattern://,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|rb|br)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^\s*)@\w+(?:\.\w+)*/im,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:True|False|None)\b/,number:/(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python,Prism.languages.py=Prism.languages.python; \ No newline at end of file +(Prism.languages.python = { + comment: { pattern: /(^|[^\\])#.*/, lookbehind: !0 }, + 'string-interpolation': { + pattern: /(?:f|rf|fr)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i, + greedy: !0, + inside: { + interpolation: { + pattern: /((?:^|[^{])(?:{{)*){(?!{)(?:[^{}]|{(?!{)(?:[^{}]|{(?!{)(?:[^{}])+})+})+}/, + lookbehind: !0, + inside: { + 'format-spec': { pattern: /(:)[^:(){}]+(?=}$)/, lookbehind: !0 }, + 'conversion-option': { pattern: //, alias: 'punctuation' }, + rest: null, + }, + }, + string: /[\s\S]+/, + }, + }, + 'triple-quoted-string': { pattern: /(?:[rub]|rb|br)?("""|''')[\s\S]*?\1/i, greedy: !0, alias: 'string' }, + string: { pattern: /(?:[rub]|rb|br)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i, greedy: !0 }, + function: { pattern: /((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g, lookbehind: !0 }, + 'class-name': { pattern: /(\bclass\s+)\w+/i, lookbehind: !0 }, + decorator: { pattern: /(^\s*)@\w+(?:\.\w+)*/im, lookbehind: !0, alias: ['annotation', 'punctuation'], inside: { punctuation: /\./ } }, + keyword: + /\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/, + builtin: + /\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/, + boolean: /\b(?:True|False|None)\b/, + number: /(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?j?\b/i, + operator: /[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/, + punctuation: /[{}[\];(),.:]/, +}), + (Prism.languages.python['string-interpolation'].inside.interpolation.inside.rest = Prism.languages.python), + (Prism.languages.py = Prism.languages.python); diff --git a/src/main/webapp/content/js/duplicate/components/prism-sql.min.js b/src/main/webapp/content/js/duplicate/components/prism-sql.min.js index b256396ae30bc442300b13162f0bcb6ce1481258..eeef56f9678bbca31f53ad116fec1d70f4ab871b 100644 --- a/src/main/webapp/content/js/duplicate/components/prism-sql.min.js +++ b/src/main/webapp/content/js/duplicate/components/prism-sql.min.js @@ -1 +1,12 @@ -Prism.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:S|ING)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:TRUE|FALSE|NULL)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/}; \ No newline at end of file +Prism.languages.sql = { + comment: { pattern: /(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/, lookbehind: !0 }, + variable: [{ pattern: /@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/, greedy: !0 }, /@[\w.$]+/], + string: { pattern: /(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/, greedy: !0, lookbehind: !0 }, + function: /\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i, + keyword: + /\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:S|ING)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i, + boolean: /\b(?:TRUE|FALSE|NULL)\b/i, + number: /\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i, + operator: /[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i, + punctuation: /[;[\]()`,.]/, +}; diff --git a/src/main/webapp/content/js/duplicate/joypixels.min.js b/src/main/webapp/content/js/duplicate/joypixels.min.js index aa71d121510ef97d6a144c63c16f2d4167261df8..b9a7cdd1192a522142c522c1411e616c2ed8f92a 100644 --- a/src/main/webapp/content/js/duplicate/joypixels.min.js +++ b/src/main/webapp/content/js/duplicate/joypixels.min.js @@ -1,15 +1,10901 @@ /*! emoji-toolkit 22-02-2021 */ -!function(ns){ns.emojiList={":england:":{uc_base:"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f",uc_full:"1f3f4-e0067-e0062-e0065-e006e-e0067-e007f",shortnames:[],category:"flags"},":scotland:":{uc_base:"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f",uc_full:"1f3f4-e0067-e0062-e0073-e0063-e0074-e007f",shortnames:[],category:"flags"},":wales:":{uc_base:"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f",uc_full:"1f3f4-e0067-e0062-e0077-e006c-e0073-e007f",shortnames:[],category:"flags"},":kiss_man_man_tone1:":{uc_base:"1f468-1f3fb-2764-1f48b-1f468-1f3fb",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_man_man_light_skin_tone:"],category:"people"},":kiss_man_man_tone1_tone2:":{uc_base:"1f468-1f3fb-2764-1f48b-1f468-1f3fc",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_man_man_light_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_man_man_tone1_tone3:":{uc_base:"1f468-1f3fb-2764-1f48b-1f468-1f3fd",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_man_man_light_skin_tone_medium_skin_tone:"],category:"people"},":kiss_man_man_tone1_tone4:":{uc_base:"1f468-1f3fb-2764-1f48b-1f468-1f3fe",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_man_man_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_man_man_tone1_tone5:":{uc_base:"1f468-1f3fb-2764-1f48b-1f468-1f3ff",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_man_man_light_skin_tone_dark_skin_tone:"],category:"people"},":kiss_man_man_tone2:":{uc_base:"1f468-1f3fc-2764-1f48b-1f468-1f3fc",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_man_man_medium_light_skin_tone:"],category:"people"},":kiss_man_man_tone2_tone1:":{uc_base:"1f468-1f3fc-2764-1f48b-1f468-1f3fb",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_man_man_medium_light_skin_tone_light_skin_tone:"],category:"people"},":kiss_man_man_tone2_tone3:":{uc_base:"1f468-1f3fc-2764-1f48b-1f468-1f3fd",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_man_man_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":kiss_man_man_tone2_tone4:":{uc_base:"1f468-1f3fc-2764-1f48b-1f468-1f3fe",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_man_man_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_man_man_tone2_tone5:":{uc_base:"1f468-1f3fc-2764-1f48b-1f468-1f3ff",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_man_man_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":kiss_man_man_tone3:":{uc_base:"1f468-1f3fd-2764-1f48b-1f468-1f3fd",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_man_man_medium_skin_tone:"],category:"people"},":kiss_man_man_tone3_tone1:":{uc_base:"1f468-1f3fd-2764-1f48b-1f468-1f3fb",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_man_man_medium_skin_tone_light_skin_tone:"],category:"people"},":kiss_man_man_tone3_tone2:":{uc_base:"1f468-1f3fd-2764-1f48b-1f468-1f3fc",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_man_man_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_man_man_tone3_tone4:":{uc_base:"1f468-1f3fd-2764-1f48b-1f468-1f3fe",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_man_man_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_man_man_tone3_tone5:":{uc_base:"1f468-1f3fd-2764-1f48b-1f468-1f3ff",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_man_man_medium_skin_tone_dark_skin_tone:"],category:"people"},":kiss_man_man_tone4:":{uc_base:"1f468-1f3fe-2764-1f48b-1f468-1f3fe",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_man_man_medium_dark_skin_tone:"],category:"people"},":kiss_man_man_tone4_tone1:":{uc_base:"1f468-1f3fe-2764-1f48b-1f468-1f3fb",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_man_man_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":kiss_man_man_tone4_tone2:":{uc_base:"1f468-1f3fe-2764-1f48b-1f468-1f3fc",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_man_man_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_man_man_tone4_tone3:":{uc_base:"1f468-1f3fe-2764-1f48b-1f468-1f3fd",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_man_man_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":kiss_man_man_tone4_tone5:":{uc_base:"1f468-1f3fe-2764-1f48b-1f468-1f3ff",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_man_man_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":kiss_man_man_tone5:":{uc_base:"1f468-1f3ff-2764-1f48b-1f468-1f3ff",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_man_man_dark_skin_tone:"],category:"people"},":kiss_man_man_tone5_tone1:":{uc_base:"1f468-1f3ff-2764-1f48b-1f468-1f3fb",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_man_man_dark_skin_tone_light_skin_tone:"],category:"people"},":kiss_man_man_tone5_tone2:":{uc_base:"1f468-1f3ff-2764-1f48b-1f468-1f3fc",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_man_man_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_man_man_tone5_tone3:":{uc_base:"1f468-1f3ff-2764-1f48b-1f468-1f3fd",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_man_man_dark_skin_tone_medium_skin_tone:"],category:"people"},":kiss_man_man_tone5_tone4:":{uc_base:"1f468-1f3ff-2764-1f48b-1f468-1f3fe",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_man_man_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_person_person_tone1_tone2:":{uc_base:"1f9d1-1f3fb-2764-1f48b-1f9d1-1f3fc",uc_full:"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc",shortnames:[":kiss_person_person_light_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_person_person_tone1_tone3:":{uc_base:"1f9d1-1f3fb-2764-1f48b-1f9d1-1f3fd",uc_full:"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd",shortnames:[":kiss_person_person_light_skin_tone_medium_skin_tone:"],category:"people"},":kiss_person_person_tone1_tone4:":{uc_base:"1f9d1-1f3fb-2764-1f48b-1f9d1-1f3fe",uc_full:"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe",shortnames:[":kiss_person_person_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_person_person_tone1_tone5:":{uc_base:"1f9d1-1f3fb-2764-1f48b-1f9d1-1f3ff",uc_full:"1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff",shortnames:[":kiss_person_person_light_skin_tone_dark_skin_tone:"],category:"people"},":kiss_person_person_tone2_tone1:":{uc_base:"1f9d1-1f3fc-2764-1f48b-1f9d1-1f3fb",uc_full:"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb",shortnames:[":kiss_person_person_medium_light_skin_tone_light_skin_tone:"],category:"people"},":kiss_person_person_tone2_tone3:":{uc_base:"1f9d1-1f3fc-2764-1f48b-1f9d1-1f3fd",uc_full:"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd",shortnames:[":kiss_person_person_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":kiss_person_person_tone2_tone4:":{uc_base:"1f9d1-1f3fc-2764-1f48b-1f9d1-1f3fe",uc_full:"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe",shortnames:[":kiss_person_person_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_person_person_tone2_tone5:":{uc_base:"1f9d1-1f3fc-2764-1f48b-1f9d1-1f3ff",uc_full:"1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff",shortnames:[":kiss_person_person_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":kiss_person_person_tone3_tone1:":{uc_base:"1f9d1-1f3fd-2764-1f48b-1f9d1-1f3fb",uc_full:"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb",shortnames:[":kiss_person_person_medium_skin_tone_light_skin_tone:"],category:"people"},":kiss_person_person_tone3_tone2:":{uc_base:"1f9d1-1f3fd-2764-1f48b-1f9d1-1f3fc",uc_full:"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc",shortnames:[":kiss_person_person_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_person_person_tone3_tone4:":{uc_base:"1f9d1-1f3fd-2764-1f48b-1f9d1-1f3fe",uc_full:"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe",shortnames:[":kiss_person_person_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_person_person_tone3_tone5:":{uc_base:"1f9d1-1f3fd-2764-1f48b-1f9d1-1f3ff",uc_full:"1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff",shortnames:[":kiss_person_person_medium_skin_tone_dark_skin_tone:"],category:"people"},":kiss_person_person_tone4_tone1:":{uc_base:"1f9d1-1f3fe-2764-1f48b-1f9d1-1f3fb",uc_full:"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb",shortnames:[":kiss_person_person_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":kiss_person_person_tone4_tone2:":{uc_base:"1f9d1-1f3fe-2764-1f48b-1f9d1-1f3fc",uc_full:"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc",shortnames:[":kiss_person_person_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_person_person_tone4_tone3:":{uc_base:"1f9d1-1f3fe-2764-1f48b-1f9d1-1f3fd",uc_full:"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd",shortnames:[":kiss_person_person_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":kiss_person_person_tone4_tone5:":{uc_base:"1f9d1-1f3fe-2764-1f48b-1f9d1-1f3ff",uc_full:"1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff",shortnames:[":kiss_person_person_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":kiss_person_person_tone5_tone1:":{uc_base:"1f9d1-1f3ff-2764-1f48b-1f9d1-1f3fb",uc_full:"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb",shortnames:[":kiss_person_person_dark_skin_tone_light_skin_tone:"],category:"people"},":kiss_person_person_tone5_tone2:":{uc_base:"1f9d1-1f3ff-2764-1f48b-1f9d1-1f3fc",uc_full:"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc",shortnames:[":kiss_person_person_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_person_person_tone5_tone3:":{uc_base:"1f9d1-1f3ff-2764-1f48b-1f9d1-1f3fd",uc_full:"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd",shortnames:[":kiss_person_person_dark_skin_tone_medium_skin_tone:"],category:"people"},":kiss_person_person_tone5_tone4:":{uc_base:"1f9d1-1f3ff-2764-1f48b-1f9d1-1f3fe",uc_full:"1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe",shortnames:[":kiss_person_person_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone1:":{uc_base:"1f469-1f3fb-2764-1f48b-1f468-1f3fb",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_woman_man_light_skin_tone:"],category:"people"},":kiss_woman_man_tone1_tone2:":{uc_base:"1f469-1f3fb-2764-1f48b-1f468-1f3fc",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_woman_man_light_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_woman_man_tone1_tone3:":{uc_base:"1f469-1f3fb-2764-1f48b-1f468-1f3fd",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_woman_man_light_skin_tone_medium_skin_tone:"],category:"people"},":kiss_woman_man_tone1_tone4:":{uc_base:"1f469-1f3fb-2764-1f48b-1f468-1f3fe",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_woman_man_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone1_tone5:":{uc_base:"1f469-1f3fb-2764-1f48b-1f468-1f3ff",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_woman_man_light_skin_tone_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone2:":{uc_base:"1f469-1f3fc-2764-1f48b-1f468-1f3fc",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_woman_man_medium_light_skin_tone:"],category:"people"},":kiss_woman_man_tone2_tone1:":{uc_base:"1f469-1f3fc-2764-1f48b-1f468-1f3fb",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_woman_man_medium_light_skin_tone_light_skin_tone:"],category:"people"},":kiss_woman_man_tone2_tone3:":{uc_base:"1f469-1f3fc-2764-1f48b-1f468-1f3fd",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_woman_man_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":kiss_woman_man_tone2_tone4:":{uc_base:"1f469-1f3fc-2764-1f48b-1f468-1f3fe",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_woman_man_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone2_tone5:":{uc_base:"1f469-1f3fc-2764-1f48b-1f468-1f3ff",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_woman_man_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone3:":{uc_base:"1f469-1f3fd-2764-1f48b-1f468-1f3fd",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_woman_man_medium_skin_tone:"],category:"people"},":kiss_woman_man_tone3_tone1:":{uc_base:"1f469-1f3fd-2764-1f48b-1f468-1f3fb",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_woman_man_medium_skin_tone_light_skin_tone:"],category:"people"},":kiss_woman_man_tone3_tone2:":{uc_base:"1f469-1f3fd-2764-1f48b-1f468-1f3fc",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_woman_man_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_woman_man_tone3_tone4:":{uc_base:"1f469-1f3fd-2764-1f48b-1f468-1f3fe",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_woman_man_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone3_tone5:":{uc_base:"1f469-1f3fd-2764-1f48b-1f468-1f3ff",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_woman_man_medium_skin_tone_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone4:":{uc_base:"1f469-1f3fe-2764-1f48b-1f468-1f3fe",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_woman_man_medium_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone4_tone1:":{uc_base:"1f469-1f3fe-2764-1f48b-1f468-1f3fb",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_woman_man_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":kiss_woman_man_tone4_tone2:":{uc_base:"1f469-1f3fe-2764-1f48b-1f468-1f3fc",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_woman_man_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_woman_man_tone4_tone3:":{uc_base:"1f469-1f3fe-2764-1f48b-1f468-1f3fd",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_woman_man_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":kiss_woman_man_tone4_tone5:":{uc_base:"1f469-1f3fe-2764-1f48b-1f468-1f3ff",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_woman_man_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone5:":{uc_base:"1f469-1f3ff-2764-1f48b-1f468-1f3ff",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff",shortnames:[":kiss_woman_man_dark_skin_tone:"],category:"people"},":kiss_woman_man_tone5_tone1:":{uc_base:"1f469-1f3ff-2764-1f48b-1f468-1f3fb",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb",shortnames:[":kiss_woman_man_dark_skin_tone_light_skin_tone:"],category:"people"},":kiss_woman_man_tone5_tone2:":{uc_base:"1f469-1f3ff-2764-1f48b-1f468-1f3fc",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc",shortnames:[":kiss_woman_man_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_woman_man_tone5_tone3:":{uc_base:"1f469-1f3ff-2764-1f48b-1f468-1f3fd",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd",shortnames:[":kiss_woman_man_dark_skin_tone_medium_skin_tone:"],category:"people"},":kiss_woman_man_tone5_tone4:":{uc_base:"1f469-1f3ff-2764-1f48b-1f468-1f3fe",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe",shortnames:[":kiss_woman_man_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone1:":{uc_base:"1f469-1f3fb-2764-1f48b-1f469-1f3fb",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb",shortnames:[":kiss_woman_woman_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone1_tone2:":{uc_base:"1f469-1f3fb-2764-1f48b-1f469-1f3fc",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc",shortnames:[":kiss_woman_woman_light_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone1_tone3:":{uc_base:"1f469-1f3fb-2764-1f48b-1f469-1f3fd",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd",shortnames:[":kiss_woman_woman_light_skin_tone_medium_skin_tone:"],category:"people"},":kiss_woman_woman_tone1_tone4:":{uc_base:"1f469-1f3fb-2764-1f48b-1f469-1f3fe",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe",shortnames:[":kiss_woman_woman_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone1_tone5:":{uc_base:"1f469-1f3fb-2764-1f48b-1f469-1f3ff",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff",shortnames:[":kiss_woman_woman_light_skin_tone_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone2:":{uc_base:"1f469-1f3fc-2764-1f48b-1f469-1f3fc",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc",shortnames:[":kiss_woman_woman_medium_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone2_tone1:":{uc_base:"1f469-1f3fc-2764-1f48b-1f469-1f3fb",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb",shortnames:[":kiss_woman_woman_medium_light_skin_tone_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone2_tone3:":{uc_base:"1f469-1f3fc-2764-1f48b-1f469-1f3fd",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd",shortnames:[":kiss_woman_woman_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":kiss_woman_woman_tone2_tone4:":{uc_base:"1f469-1f3fc-2764-1f48b-1f469-1f3fe",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe",shortnames:[":kiss_woman_woman_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone2_tone5:":{uc_base:"1f469-1f3fc-2764-1f48b-1f469-1f3ff",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff",shortnames:[":kiss_woman_woman_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone3:":{uc_base:"1f469-1f3fd-2764-1f48b-1f469-1f3fd",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd",shortnames:[":kiss_woman_woman_medium_skin_tone:"],category:"people"},":kiss_woman_woman_tone3_tone1:":{uc_base:"1f469-1f3fd-2764-1f48b-1f469-1f3fb",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb",shortnames:[":kiss_woman_woman_medium_skin_tone_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone3_tone2:":{uc_base:"1f469-1f3fd-2764-1f48b-1f469-1f3fc",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc",shortnames:[":kiss_woman_woman_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone3_tone4:":{uc_base:"1f469-1f3fd-2764-1f48b-1f469-1f3fe",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe",shortnames:[":kiss_woman_woman_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone3_tone5:":{uc_base:"1f469-1f3fd-2764-1f48b-1f469-1f3ff",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff",shortnames:[":kiss_woman_woman_medium_skin_tone_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone4:":{uc_base:"1f469-1f3fe-2764-1f48b-1f469-1f3fe",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe",shortnames:[":kiss_woman_woman_medium_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone4_tone1:":{uc_base:"1f469-1f3fe-2764-1f48b-1f469-1f3fb",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb",shortnames:[":kiss_woman_woman_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone4_tone2:":{uc_base:"1f469-1f3fe-2764-1f48b-1f469-1f3fc",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc",shortnames:[":kiss_woman_woman_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone4_tone3:":{uc_base:"1f469-1f3fe-2764-1f48b-1f469-1f3fd",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd",shortnames:[":kiss_woman_woman_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":kiss_woman_woman_tone4_tone5:":{uc_base:"1f469-1f3fe-2764-1f48b-1f469-1f3ff",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff",shortnames:[":kiss_woman_woman_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone5:":{uc_base:"1f469-1f3ff-2764-1f48b-1f469-1f3ff",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff",shortnames:[":kiss_woman_woman_dark_skin_tone:"],category:"people"},":kiss_woman_woman_tone5_tone1:":{uc_base:"1f469-1f3ff-2764-1f48b-1f469-1f3fb",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb",shortnames:[":kiss_woman_woman_dark_skin_tone_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone5_tone2:":{uc_base:"1f469-1f3ff-2764-1f48b-1f469-1f3fc",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc",shortnames:[":kiss_woman_woman_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":kiss_woman_woman_tone5_tone3:":{uc_base:"1f469-1f3ff-2764-1f48b-1f469-1f3fd",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd",shortnames:[":kiss_woman_woman_dark_skin_tone_medium_skin_tone:"],category:"people"},":kiss_woman_woman_tone5_tone4:":{uc_base:"1f469-1f3ff-2764-1f48b-1f469-1f3fe",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe",shortnames:[":kiss_woman_woman_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":men_holding_hands_tone1_tone2:":{uc_base:"1f468-1f3fb-1f91d-1f468-1f3fc",uc_full:"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc",shortnames:[":men_holding_hands_light_skin_tone_medium_light_skin_tone:"],category:"people"},":men_holding_hands_tone1_tone3:":{uc_base:"1f468-1f3fb-1f91d-1f468-1f3fd",uc_full:"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd",shortnames:[":men_holding_hands_light_skin_tone_medium_skin_tone:"],category:"people"},":men_holding_hands_tone1_tone4:":{uc_base:"1f468-1f3fb-1f91d-1f468-1f3fe",uc_full:"1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe",shortnames:[":men_holding_hands_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":men_holding_hands_tone1_tone5:":{uc_base:"1f468-1f3fb-1f91d-1f468-1f3ff",uc_full:"1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff",shortnames:[":men_holding_hands_light_skin_tone_dark_skin_tone:"],category:"people"},":men_holding_hands_tone2_tone1:":{uc_base:"1f468-1f3fc-1f91d-1f468-1f3fb",uc_full:"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb",shortnames:[":men_holding_hands_medium_light_skin_tone_light_skin_tone:"],category:"people"},":men_holding_hands_tone2_tone3:":{uc_base:"1f468-1f3fc-1f91d-1f468-1f3fd",uc_full:"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd",shortnames:[":men_holding_hands_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":men_holding_hands_tone2_tone4:":{uc_base:"1f468-1f3fc-1f91d-1f468-1f3fe",uc_full:"1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe",shortnames:[":men_holding_hands_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":men_holding_hands_tone2_tone5:":{uc_base:"1f468-1f3fc-1f91d-1f468-1f3ff",uc_full:"1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff",shortnames:[":men_holding_hands_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":men_holding_hands_tone3_tone1:":{uc_base:"1f468-1f3fd-1f91d-1f468-1f3fb",uc_full:"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb",shortnames:[":men_holding_hands_medium_skin_tone_light_skin_tone:"],category:"people"},":men_holding_hands_tone3_tone2:":{uc_base:"1f468-1f3fd-1f91d-1f468-1f3fc",uc_full:"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc",shortnames:[":men_holding_hands_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":men_holding_hands_tone3_tone4:":{uc_base:"1f468-1f3fd-1f91d-1f468-1f3fe",uc_full:"1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe",shortnames:[":men_holding_hands_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":men_holding_hands_tone3_tone5:":{uc_base:"1f468-1f3fd-1f91d-1f468-1f3ff",uc_full:"1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff",shortnames:[":men_holding_hands_medium_skin_tone_dark_skin_tone:"],category:"people"},":men_holding_hands_tone4_tone1:":{uc_base:"1f468-1f3fe-1f91d-1f468-1f3fb",uc_full:"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb",shortnames:[":men_holding_hands_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":men_holding_hands_tone4_tone2:":{uc_base:"1f468-1f3fe-1f91d-1f468-1f3fc",uc_full:"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc",shortnames:[":men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":men_holding_hands_tone4_tone3:":{uc_base:"1f468-1f3fe-1f91d-1f468-1f3fd",uc_full:"1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd",shortnames:[":men_holding_hands_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":men_holding_hands_tone4_tone5:":{uc_base:"1f468-1f3fe-1f91d-1f468-1f3ff",uc_full:"1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff",shortnames:[":men_holding_hands_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":men_holding_hands_tone5_tone1:":{uc_base:"1f468-1f3ff-1f91d-1f468-1f3fb",uc_full:"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb",shortnames:[":men_holding_hands_dark_skin_tone_light_skin_tone:"],category:"people"},":men_holding_hands_tone5_tone2:":{uc_base:"1f468-1f3ff-1f91d-1f468-1f3fc",uc_full:"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc",shortnames:[":men_holding_hands_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":men_holding_hands_tone5_tone3:":{uc_base:"1f468-1f3ff-1f91d-1f468-1f3fd",uc_full:"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd",shortnames:[":men_holding_hands_dark_skin_tone_medium_skin_tone:"],category:"people"},":men_holding_hands_tone5_tone4:":{uc_base:"1f468-1f3ff-1f91d-1f468-1f3fe",uc_full:"1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe",shortnames:[":men_holding_hands_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":people_holding_hands_tone1:":{uc_base:"1f9d1-1f3fb-1f91d-1f9d1-1f3fb",uc_full:"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb",shortnames:[":people_holding_hands_light_skin_tone:"],category:"people"},":people_holding_hands_tone1_tone2:":{uc_base:"1f9d1-1f3fb-1f91d-1f9d1-1f3fc",uc_full:"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc",shortnames:[":people_holding_hands_light_skin_tone_medium_light_skin_tone:"],category:"people"},":people_holding_hands_tone1_tone3:":{uc_base:"1f9d1-1f3fb-1f91d-1f9d1-1f3fd",uc_full:"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd",shortnames:[":people_holding_hands_light_skin_tone_medium_skin_tone:"],category:"people"},":people_holding_hands_tone1_tone4:":{uc_base:"1f9d1-1f3fb-1f91d-1f9d1-1f3fe",uc_full:"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe",shortnames:[":people_holding_hands_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":people_holding_hands_tone1_tone5:":{uc_base:"1f9d1-1f3fb-1f91d-1f9d1-1f3ff",uc_full:"1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff",shortnames:[":people_holding_hands_light_skin_tone_dark_skin_tone:"],category:"people"},":people_holding_hands_tone2:":{uc_base:"1f9d1-1f3fc-1f91d-1f9d1-1f3fc",uc_full:"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc",shortnames:[":people_holding_hands_medium_light_skin_tone:"],category:"people"},":people_holding_hands_tone2_tone1:":{uc_base:"1f9d1-1f3fc-1f91d-1f9d1-1f3fb",uc_full:"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb",shortnames:[":people_holding_hands_medium_light_skin_tone_light_skin_tone:"],category:"people"},":people_holding_hands_tone2_tone3:":{uc_base:"1f9d1-1f3fc-1f91d-1f9d1-1f3fd",uc_full:"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd",shortnames:[":people_holding_hands_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":people_holding_hands_tone2_tone4:":{uc_base:"1f9d1-1f3fc-1f91d-1f9d1-1f3fe",uc_full:"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe",shortnames:[":people_holding_hands_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":people_holding_hands_tone2_tone5:":{uc_base:"1f9d1-1f3fc-1f91d-1f9d1-1f3ff",uc_full:"1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff",shortnames:[":people_holding_hands_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":people_holding_hands_tone3:":{uc_base:"1f9d1-1f3fd-1f91d-1f9d1-1f3fd",uc_full:"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd",shortnames:[":people_holding_hands_medium_skin_tone:"],category:"people"},":people_holding_hands_tone3_tone1:":{uc_base:"1f9d1-1f3fd-1f91d-1f9d1-1f3fb",uc_full:"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb",shortnames:[":people_holding_hands_medium_skin_tone_light_skin_tone:"],category:"people"},":people_holding_hands_tone3_tone2:":{uc_base:"1f9d1-1f3fd-1f91d-1f9d1-1f3fc",uc_full:"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc",shortnames:[":people_holding_hands_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":people_holding_hands_tone3_tone4:":{uc_base:"1f9d1-1f3fd-1f91d-1f9d1-1f3fe",uc_full:"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe",shortnames:[":people_holding_hands_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":people_holding_hands_tone3_tone5:":{uc_base:"1f9d1-1f3fd-1f91d-1f9d1-1f3ff",uc_full:"1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff",shortnames:[":people_holding_hands_medium_skin_tone_dark_skin_tone:"],category:"people"},":people_holding_hands_tone4:":{uc_base:"1f9d1-1f3fe-1f91d-1f9d1-1f3fe",uc_full:"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe",shortnames:[":people_holding_hands_medium_dark_skin_tone:"],category:"people"},":people_holding_hands_tone4_tone1:":{uc_base:"1f9d1-1f3fe-1f91d-1f9d1-1f3fb",uc_full:"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb",shortnames:[":people_holding_hands_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":people_holding_hands_tone4_tone2:":{uc_base:"1f9d1-1f3fe-1f91d-1f9d1-1f3fc",uc_full:"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc",shortnames:[":people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":people_holding_hands_tone4_tone3:":{uc_base:"1f9d1-1f3fe-1f91d-1f9d1-1f3fd",uc_full:"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd",shortnames:[":people_holding_hands_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":people_holding_hands_tone4_tone5:":{uc_base:"1f9d1-1f3fe-1f91d-1f9d1-1f3ff",uc_full:"1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff",shortnames:[":people_holding_hands_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":people_holding_hands_tone5:":{uc_base:"1f9d1-1f3ff-1f91d-1f9d1-1f3ff",uc_full:"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff",shortnames:[":people_holding_hands_dark_skin_tone:"],category:"people"},":people_holding_hands_tone5_tone1:":{uc_base:"1f9d1-1f3ff-1f91d-1f9d1-1f3fb",uc_full:"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb",shortnames:[":people_holding_hands_dark_skin_tone_light_skin_tone:"],category:"people"},":people_holding_hands_tone5_tone2:":{uc_base:"1f9d1-1f3ff-1f91d-1f9d1-1f3fc",uc_full:"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc",shortnames:[":people_holding_hands_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":people_holding_hands_tone5_tone3:":{uc_base:"1f9d1-1f3ff-1f91d-1f9d1-1f3fd",uc_full:"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd",shortnames:[":people_holding_hands_dark_skin_tone_medium_skin_tone:"],category:"people"},":people_holding_hands_tone5_tone4:":{uc_base:"1f9d1-1f3ff-1f91d-1f9d1-1f3fe",uc_full:"1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe",shortnames:[":people_holding_hands_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone1_tone2:":{uc_base:"1f469-1f3fb-1f91d-1f468-1f3fc",uc_full:"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc", -shortnames:[":woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone1_tone3:":{uc_base:"1f469-1f3fb-1f91d-1f468-1f3fd",uc_full:"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd",shortnames:[":woman_and_man_holding_hands_light_skin_tone_medium_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone1_tone4:":{uc_base:"1f469-1f3fb-1f91d-1f468-1f3fe",uc_full:"1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe",shortnames:[":woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone1_tone5:":{uc_base:"1f469-1f3fb-1f91d-1f468-1f3ff",uc_full:"1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff",shortnames:[":woman_and_man_holding_hands_light_skin_tone_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone2_tone1:":{uc_base:"1f469-1f3fc-1f91d-1f468-1f3fb",uc_full:"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb",shortnames:[":woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone2_tone3:":{uc_base:"1f469-1f3fc-1f91d-1f468-1f3fd",uc_full:"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd",shortnames:[":woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone2_tone4:":{uc_base:"1f469-1f3fc-1f91d-1f468-1f3fe",uc_full:"1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe",shortnames:[":woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone2_tone5:":{uc_base:"1f469-1f3fc-1f91d-1f468-1f3ff",uc_full:"1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff",shortnames:[":woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone3_tone1:":{uc_base:"1f469-1f3fd-1f91d-1f468-1f3fb",uc_full:"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb",shortnames:[":woman_and_man_holding_hands_medium_skin_tone_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone3_tone2:":{uc_base:"1f469-1f3fd-1f91d-1f468-1f3fc",uc_full:"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc",shortnames:[":woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone3_tone4:":{uc_base:"1f469-1f3fd-1f91d-1f468-1f3fe",uc_full:"1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe",shortnames:[":woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone3_tone5:":{uc_base:"1f469-1f3fd-1f91d-1f468-1f3ff",uc_full:"1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff",shortnames:[":woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone4_tone1:":{uc_base:"1f469-1f3fe-1f91d-1f468-1f3fb",uc_full:"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb",shortnames:[":woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone4_tone2:":{uc_base:"1f469-1f3fe-1f91d-1f468-1f3fc",uc_full:"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc",shortnames:[":woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone4_tone3:":{uc_base:"1f469-1f3fe-1f91d-1f468-1f3fd",uc_full:"1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd",shortnames:[":woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone4_tone5:":{uc_base:"1f469-1f3fe-1f91d-1f468-1f3ff",uc_full:"1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff",shortnames:[":woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone5_tone1:":{uc_base:"1f469-1f3ff-1f91d-1f468-1f3fb",uc_full:"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb",shortnames:[":woman_and_man_holding_hands_dark_skin_tone_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone5_tone2:":{uc_base:"1f469-1f3ff-1f91d-1f468-1f3fc",uc_full:"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc",shortnames:[":woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone5_tone3:":{uc_base:"1f469-1f3ff-1f91d-1f468-1f3fd",uc_full:"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd",shortnames:[":woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone5_tone4:":{uc_base:"1f469-1f3ff-1f91d-1f468-1f3fe",uc_full:"1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe",shortnames:[":woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":women_holding_hands_tone1_tone2:":{uc_base:"1f469-1f3fb-1f91d-1f469-1f3fc",uc_full:"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc",shortnames:[":women_holding_hands_light_skin_tone_medium_light_skin_tone:"],category:"people"},":women_holding_hands_tone1_tone3:":{uc_base:"1f469-1f3fb-1f91d-1f469-1f3fd",uc_full:"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd",shortnames:[":women_holding_hands_light_skin_tone_medium_skin_tone:"],category:"people"},":women_holding_hands_tone1_tone4:":{uc_base:"1f469-1f3fb-1f91d-1f469-1f3fe",uc_full:"1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe",shortnames:[":women_holding_hands_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":women_holding_hands_tone1_tone5:":{uc_base:"1f469-1f3fb-1f91d-1f469-1f3ff",uc_full:"1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff",shortnames:[":women_holding_hands_light_skin_tone_dark_skin_tone:"],category:"people"},":women_holding_hands_tone2_tone1:":{uc_base:"1f469-1f3fc-1f91d-1f469-1f3fb",uc_full:"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb",shortnames:[":women_holding_hands_medium_light_skin_tone_light_skin_tone:"],category:"people"},":women_holding_hands_tone2_tone3:":{uc_base:"1f469-1f3fc-1f91d-1f469-1f3fd",uc_full:"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd",shortnames:[":women_holding_hands_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":women_holding_hands_tone2_tone4:":{uc_base:"1f469-1f3fc-1f91d-1f469-1f3fe",uc_full:"1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe",shortnames:[":women_holding_hands_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":women_holding_hands_tone2_tone5:":{uc_base:"1f469-1f3fc-1f91d-1f469-1f3ff",uc_full:"1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff",shortnames:[":women_holding_hands_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":women_holding_hands_tone3_tone1:":{uc_base:"1f469-1f3fd-1f91d-1f469-1f3fb",uc_full:"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb",shortnames:[":women_holding_hands_medium_skin_tone_light_skin_tone:"],category:"people"},":women_holding_hands_tone3_tone2:":{uc_base:"1f469-1f3fd-1f91d-1f469-1f3fc",uc_full:"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc",shortnames:[":women_holding_hands_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":women_holding_hands_tone3_tone4:":{uc_base:"1f469-1f3fd-1f91d-1f469-1f3fe",uc_full:"1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe",shortnames:[":women_holding_hands_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":women_holding_hands_tone3_tone5:":{uc_base:"1f469-1f3fd-1f91d-1f469-1f3ff",uc_full:"1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff",shortnames:[":women_holding_hands_medium_skin_tone_dark_skin_tone:"],category:"people"},":women_holding_hands_tone4_tone1:":{uc_base:"1f469-1f3fe-1f91d-1f469-1f3fb",uc_full:"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb",shortnames:[":women_holding_hands_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":women_holding_hands_tone4_tone2:":{uc_base:"1f469-1f3fe-1f91d-1f469-1f3fc",uc_full:"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc",shortnames:[":women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":women_holding_hands_tone4_tone3:":{uc_base:"1f469-1f3fe-1f91d-1f469-1f3fd",uc_full:"1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd",shortnames:[":women_holding_hands_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":women_holding_hands_tone4_tone5:":{uc_base:"1f469-1f3fe-1f91d-1f469-1f3ff",uc_full:"1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff",shortnames:[":women_holding_hands_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":women_holding_hands_tone5_tone1:":{uc_base:"1f469-1f3ff-1f91d-1f469-1f3fb",uc_full:"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb",shortnames:[":women_holding_hands_dark_skin_tone_light_skin_tone:"],category:"people"},":women_holding_hands_tone5_tone2:":{uc_base:"1f469-1f3ff-1f91d-1f469-1f3fc",uc_full:"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc",shortnames:[":women_holding_hands_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":women_holding_hands_tone5_tone3:":{uc_base:"1f469-1f3ff-1f91d-1f469-1f3fd",uc_full:"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd",shortnames:[":women_holding_hands_dark_skin_tone_medium_skin_tone:"],category:"people"},":women_holding_hands_tone5_tone4:":{uc_base:"1f469-1f3ff-1f91d-1f469-1f3fe",uc_full:"1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe",shortnames:[":women_holding_hands_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone1:":{uc_base:"1f468-1f3fb-2764-1f468-1f3fb",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_man_man_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone1_tone2:":{uc_base:"1f468-1f3fb-2764-1f468-1f3fc",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_man_man_light_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone1_tone3:":{uc_base:"1f468-1f3fb-2764-1f468-1f3fd",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_man_man_light_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone1_tone4:":{uc_base:"1f468-1f3fb-2764-1f468-1f3fe",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_man_man_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone1_tone5:":{uc_base:"1f468-1f3fb-2764-1f468-1f3ff",uc_full:"1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_man_man_light_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone2:":{uc_base:"1f468-1f3fc-2764-1f468-1f3fc",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_man_man_medium_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone2_tone1:":{uc_base:"1f468-1f3fc-2764-1f468-1f3fb",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_man_man_medium_light_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone2_tone3:":{uc_base:"1f468-1f3fc-2764-1f468-1f3fd",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_man_man_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone2_tone4:":{uc_base:"1f468-1f3fc-2764-1f468-1f3fe",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_man_man_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone2_tone5:":{uc_base:"1f468-1f3fc-2764-1f468-1f3ff",uc_full:"1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_man_man_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone3:":{uc_base:"1f468-1f3fd-2764-1f468-1f3fd",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_man_man_medium_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone3_tone1:":{uc_base:"1f468-1f3fd-2764-1f468-1f3fb",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_man_man_medium_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone3_tone2:":{uc_base:"1f468-1f3fd-2764-1f468-1f3fc",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_man_man_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone3_tone4:":{uc_base:"1f468-1f3fd-2764-1f468-1f3fe",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_man_man_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone3_tone5:":{uc_base:"1f468-1f3fd-2764-1f468-1f3ff",uc_full:"1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_man_man_medium_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone4:":{uc_base:"1f468-1f3fe-2764-1f468-1f3fe",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_man_man_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone4_tone1:":{uc_base:"1f468-1f3fe-2764-1f468-1f3fb",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_man_man_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone4_tone2:":{uc_base:"1f468-1f3fe-2764-1f468-1f3fc",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_man_man_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone4_tone3:":{uc_base:"1f468-1f3fe-2764-1f468-1f3fd",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_man_man_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone4_tone5:":{uc_base:"1f468-1f3fe-2764-1f468-1f3ff",uc_full:"1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_man_man_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone5:":{uc_base:"1f468-1f3ff-2764-1f468-1f3ff",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_man_man_dark_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone5_tone1:":{uc_base:"1f468-1f3ff-2764-1f468-1f3fb",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_man_man_dark_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone5_tone2:":{uc_base:"1f468-1f3ff-2764-1f468-1f3fc",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_man_man_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone5_tone3:":{uc_base:"1f468-1f3ff-2764-1f468-1f3fd",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_man_man_dark_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_man_man_tone5_tone4:":{uc_base:"1f468-1f3ff-2764-1f468-1f3fe",uc_full:"1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_man_man_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone1_tone2:":{uc_base:"1f9d1-1f3fb-2764-1f9d1-1f3fc",uc_full:"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fc",shortnames:[":couple_with_heart_person_person_light_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone1_tone3:":{uc_base:"1f9d1-1f3fb-2764-1f9d1-1f3fd",uc_full:"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fd",shortnames:[":couple_with_heart_person_person_light_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone1_tone4:":{uc_base:"1f9d1-1f3fb-2764-1f9d1-1f3fe",uc_full:"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fe",shortnames:[":couple_with_heart_person_person_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone1_tone5:":{uc_base:"1f9d1-1f3fb-2764-1f9d1-1f3ff",uc_full:"1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3ff",shortnames:[":couple_with_heart_person_person_light_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone2_tone1:":{uc_base:"1f9d1-1f3fc-2764-1f9d1-1f3fb",uc_full:"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fb",shortnames:[":couple_with_heart_person_person_medium_light_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone2_tone3:":{uc_base:"1f9d1-1f3fc-2764-1f9d1-1f3fd",uc_full:"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fd",shortnames:[":couple_with_heart_person_person_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone2_tone4:":{uc_base:"1f9d1-1f3fc-2764-1f9d1-1f3fe",uc_full:"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fe",shortnames:[":couple_with_heart_person_person_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone2_tone5:":{uc_base:"1f9d1-1f3fc-2764-1f9d1-1f3ff",uc_full:"1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3ff",shortnames:[":couple_with_heart_person_person_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone3_tone1:":{uc_base:"1f9d1-1f3fd-2764-1f9d1-1f3fb",uc_full:"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fb",shortnames:[":couple_with_heart_person_person_medium_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone3_tone2:":{uc_base:"1f9d1-1f3fd-2764-1f9d1-1f3fc",uc_full:"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fc",shortnames:[":couple_with_heart_person_person_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone3_tone4:":{uc_base:"1f9d1-1f3fd-2764-1f9d1-1f3fe",uc_full:"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fe",shortnames:[":couple_with_heart_person_person_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone3_tone5:":{uc_base:"1f9d1-1f3fd-2764-1f9d1-1f3ff",uc_full:"1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3ff",shortnames:[":couple_with_heart_person_person_medium_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone4_tone1:":{uc_base:"1f9d1-1f3fe-2764-1f9d1-1f3fb",uc_full:"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fb",shortnames:[":couple_with_heart_person_person_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone4_tone2:":{uc_base:"1f9d1-1f3fe-2764-1f9d1-1f3fc",uc_full:"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fc",shortnames:[":couple_with_heart_person_person_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone4_tone3:":{uc_base:"1f9d1-1f3fe-2764-1f9d1-1f3fd",uc_full:"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fd",shortnames:[":couple_with_heart_person_person_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone4_tone5:":{uc_base:"1f9d1-1f3fe-2764-1f9d1-1f3ff",uc_full:"1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3ff",shortnames:[":couple_with_heart_person_person_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone5_tone1:":{uc_base:"1f9d1-1f3ff-2764-1f9d1-1f3fb",uc_full:"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fb",shortnames:[":couple_with_heart_person_person_dark_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone5_tone2:":{uc_base:"1f9d1-1f3ff-2764-1f9d1-1f3fc",uc_full:"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fc",shortnames:[":couple_with_heart_person_person_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone5_tone3:":{uc_base:"1f9d1-1f3ff-2764-1f9d1-1f3fd",uc_full:"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fd",shortnames:[":couple_with_heart_person_person_dark_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_person_person_tone5_tone4:":{uc_base:"1f9d1-1f3ff-2764-1f9d1-1f3fe",uc_full:"1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fe",shortnames:[":couple_with_heart_person_person_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone1:":{uc_base:"1f469-1f3fb-2764-1f468-1f3fb",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_woman_man_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone1_tone2:":{uc_base:"1f469-1f3fb-2764-1f468-1f3fc",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_woman_man_light_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone1_tone3:":{uc_base:"1f469-1f3fb-2764-1f468-1f3fd",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_woman_man_light_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone1_tone4:":{uc_base:"1f469-1f3fb-2764-1f468-1f3fe",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_woman_man_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone1_tone5:":{uc_base:"1f469-1f3fb-2764-1f468-1f3ff",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_woman_man_light_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone2:":{uc_base:"1f469-1f3fc-2764-1f468-1f3fc",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_woman_man_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone2_tone1:":{uc_base:"1f469-1f3fc-2764-1f468-1f3fb",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_woman_man_medium_light_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone2_tone3:":{uc_base:"1f469-1f3fc-2764-1f468-1f3fd",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_woman_man_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone2_tone4:":{uc_base:"1f469-1f3fc-2764-1f468-1f3fe",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_woman_man_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone2_tone5:":{uc_base:"1f469-1f3fc-2764-1f468-1f3ff",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_woman_man_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone3:":{uc_base:"1f469-1f3fd-2764-1f468-1f3fd",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_woman_man_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone3_tone1:":{uc_base:"1f469-1f3fd-2764-1f468-1f3fb",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_woman_man_medium_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone3_tone2:":{uc_base:"1f469-1f3fd-2764-1f468-1f3fc",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_woman_man_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone3_tone4:":{uc_base:"1f469-1f3fd-2764-1f468-1f3fe",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_woman_man_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone3_tone5:":{uc_base:"1f469-1f3fd-2764-1f468-1f3ff",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_woman_man_medium_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone4:":{uc_base:"1f469-1f3fe-2764-1f468-1f3fe",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_woman_man_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone4_tone1:":{uc_base:"1f469-1f3fe-2764-1f468-1f3fb",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_woman_man_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone4_tone2:":{uc_base:"1f469-1f3fe-2764-1f468-1f3fc",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_woman_man_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone4_tone3:":{uc_base:"1f469-1f3fe-2764-1f468-1f3fd",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_woman_man_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone4_tone5:":{uc_base:"1f469-1f3fe-2764-1f468-1f3ff",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_woman_man_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone5:":{uc_base:"1f469-1f3ff-2764-1f468-1f3ff",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff",shortnames:[":couple_with_heart_woman_man_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone5_tone1:":{uc_base:"1f469-1f3ff-2764-1f468-1f3fb",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb",shortnames:[":couple_with_heart_woman_man_dark_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone5_tone2:":{uc_base:"1f469-1f3ff-2764-1f468-1f3fc",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc",shortnames:[":couple_with_heart_woman_man_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone5_tone3:":{uc_base:"1f469-1f3ff-2764-1f468-1f3fd",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd",shortnames:[":couple_with_heart_woman_man_dark_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_man_tone5_tone4:":{uc_base:"1f469-1f3ff-2764-1f468-1f3fe",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe",shortnames:[":couple_with_heart_woman_man_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone1:":{uc_base:"1f469-1f3fb-2764-1f469-1f3fb",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb",shortnames:[":couple_with_heart_woman_woman_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone1_tone2:":{uc_base:"1f469-1f3fb-2764-1f469-1f3fc",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fc",shortnames:[":couple_with_heart_woman_woman_light_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone1_tone3:":{uc_base:"1f469-1f3fb-2764-1f469-1f3fd",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fd",shortnames:[":couple_with_heart_woman_woman_light_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone1_tone4:":{uc_base:"1f469-1f3fb-2764-1f469-1f3fe",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fe",shortnames:[":couple_with_heart_woman_woman_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone1_tone5:":{uc_base:"1f469-1f3fb-2764-1f469-1f3ff",uc_full:"1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3ff",shortnames:[":couple_with_heart_woman_woman_light_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone2:":{uc_base:"1f469-1f3fc-2764-1f469-1f3fc",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc",shortnames:[":couple_with_heart_woman_woman_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone2_tone1:":{uc_base:"1f469-1f3fc-2764-1f469-1f3fb",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fb",shortnames:[":couple_with_heart_woman_woman_medium_light_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone2_tone3:":{uc_base:"1f469-1f3fc-2764-1f469-1f3fd",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fd",shortnames:[":couple_with_heart_woman_woman_medium_light_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone2_tone4:":{uc_base:"1f469-1f3fc-2764-1f469-1f3fe",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fe",shortnames:[":couple_with_heart_woman_woman_medium_light_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone2_tone5:":{uc_base:"1f469-1f3fc-2764-1f469-1f3ff",uc_full:"1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3ff",shortnames:[":couple_with_heart_woman_woman_medium_light_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone3:":{uc_base:"1f469-1f3fd-2764-1f469-1f3fd",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd",shortnames:[":couple_with_heart_woman_woman_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone3_tone1:":{uc_base:"1f469-1f3fd-2764-1f469-1f3fb",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fb",shortnames:[":couple_with_heart_woman_woman_medium_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone3_tone2:":{uc_base:"1f469-1f3fd-2764-1f469-1f3fc",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fc",shortnames:[":couple_with_heart_woman_woman_medium_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone3_tone4:":{uc_base:"1f469-1f3fd-2764-1f469-1f3fe",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fe",shortnames:[":couple_with_heart_woman_woman_medium_skin_tone_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone3_tone5:":{uc_base:"1f469-1f3fd-2764-1f469-1f3ff",uc_full:"1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3ff",shortnames:[":couple_with_heart_woman_woman_medium_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone4:":{uc_base:"1f469-1f3fe-2764-1f469-1f3fe",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe",shortnames:[":couple_with_heart_woman_woman_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone4_tone1:":{uc_base:"1f469-1f3fe-2764-1f469-1f3fb",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fb",shortnames:[":couple_with_heart_woman_woman_medium_dark_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone4_tone2:":{uc_base:"1f469-1f3fe-2764-1f469-1f3fc",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fc",shortnames:[":couple_with_heart_woman_woman_medium_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone4_tone3:":{uc_base:"1f469-1f3fe-2764-1f469-1f3fd",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fd",shortnames:[":couple_with_heart_woman_woman_medium_dark_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone4_tone5:":{uc_base:"1f469-1f3fe-2764-1f469-1f3ff",uc_full:"1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3ff",shortnames:[":couple_with_heart_woman_woman_medium_dark_skin_tone_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone5:":{uc_base:"1f469-1f3ff-2764-1f469-1f3ff",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff",shortnames:[":couple_with_heart_woman_woman_dark_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone5_tone1:":{uc_base:"1f469-1f3ff-2764-1f469-1f3fb",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fb",shortnames:[":couple_with_heart_woman_woman_dark_skin_tone_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone5_tone2:":{uc_base:"1f469-1f3ff-2764-1f469-1f3fc",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fc",shortnames:[":couple_with_heart_woman_woman_dark_skin_tone_medium_light_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone5_tone3:":{uc_base:"1f469-1f3ff-2764-1f469-1f3fd",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fd",shortnames:[":couple_with_heart_woman_woman_dark_skin_tone_medium_skin_tone:"],category:"people"},":couple_with_heart_woman_woman_tone5_tone4:":{uc_base:"1f469-1f3ff-2764-1f469-1f3fe",uc_full:"1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fe",shortnames:[":couple_with_heart_woman_woman_dark_skin_tone_medium_dark_skin_tone:"],category:"people"},":family_mmbb:":{uc_base:"1f468-1f468-1f466-1f466",uc_full:"1f468-200d-1f468-200d-1f466-200d-1f466",shortnames:[],category:"people"},":family_mmgb:":{uc_base:"1f468-1f468-1f467-1f466",uc_full:"1f468-200d-1f468-200d-1f467-200d-1f466",shortnames:[],category:"people"},":family_mmgg:":{uc_base:"1f468-1f468-1f467-1f467",uc_full:"1f468-200d-1f468-200d-1f467-200d-1f467",shortnames:[],category:"people"},":family_mwbb:":{uc_base:"1f468-1f469-1f466-1f466",uc_full:"1f468-200d-1f469-200d-1f466-200d-1f466", -shortnames:[],category:"people"},":family_mwgb:":{uc_base:"1f468-1f469-1f467-1f466",uc_full:"1f468-200d-1f469-200d-1f467-200d-1f466",shortnames:[],category:"people"},":family_mwgg:":{uc_base:"1f468-1f469-1f467-1f467",uc_full:"1f468-200d-1f469-200d-1f467-200d-1f467",shortnames:[],category:"people"},":family_wwbb:":{uc_base:"1f469-1f469-1f466-1f466",uc_full:"1f469-200d-1f469-200d-1f466-200d-1f466",shortnames:[],category:"people"},":family_wwgb:":{uc_base:"1f469-1f469-1f467-1f466",uc_full:"1f469-200d-1f469-200d-1f467-200d-1f466",shortnames:[],category:"people"},":family_wwgg:":{uc_base:"1f469-1f469-1f467-1f467",uc_full:"1f469-200d-1f469-200d-1f467-200d-1f467",shortnames:[],category:"people"},":kiss_mm:":{uc_base:"1f468-2764-1f48b-1f468",uc_full:"1f468-200d-2764-fe0f-200d-1f48b-200d-1f468",shortnames:[":couplekiss_mm:"],category:"people"},":kiss_woman_man:":{uc_base:"1f469-2764-1f48b-1f468",uc_full:"1f469-200d-2764-fe0f-200d-1f48b-200d-1f468",shortnames:[],category:"people"},":kiss_ww:":{uc_base:"1f469-2764-1f48b-1f469",uc_full:"1f469-200d-2764-fe0f-200d-1f48b-200d-1f469",shortnames:[":couplekiss_ww:"],category:"people"},":artist_tone1:":{uc_base:"1f9d1-1f3fb-1f3a8",uc_full:"1f9d1-1f3fb-200d-1f3a8",shortnames:[":artist_light_skin_tone:"],category:"people"},":artist_tone2:":{uc_base:"1f9d1-1f3fc-1f3a8",uc_full:"1f9d1-1f3fc-200d-1f3a8",shortnames:[":artist_medium_light_skin_tone:"],category:"people"},":artist_tone3:":{uc_base:"1f9d1-1f3fd-1f3a8",uc_full:"1f9d1-1f3fd-200d-1f3a8",shortnames:[":artist_medium_skin_tone:"],category:"people"},":artist_tone4:":{uc_base:"1f9d1-1f3fe-1f3a8",uc_full:"1f9d1-1f3fe-200d-1f3a8",shortnames:[":artist_medium_dark_skin_tone:"],category:"people"},":artist_tone5:":{uc_base:"1f9d1-1f3ff-1f3a8",uc_full:"1f9d1-1f3ff-200d-1f3a8",shortnames:[":artist_dark_skin_tone:"],category:"people"},":astronaut_tone1:":{uc_base:"1f9d1-1f3fb-1f680",uc_full:"1f9d1-1f3fb-200d-1f680",shortnames:[":astronaut_light_skin_tone:"],category:"people"},":astronaut_tone2:":{uc_base:"1f9d1-1f3fc-1f680",uc_full:"1f9d1-1f3fc-200d-1f680",shortnames:[":astronaut_medium_light_skin_tone:"],category:"people"},":astronaut_tone3:":{uc_base:"1f9d1-1f3fd-1f680",uc_full:"1f9d1-1f3fd-200d-1f680",shortnames:[":astronaut_medium_skin_tone:"],category:"people"},":astronaut_tone4:":{uc_base:"1f9d1-1f3fe-1f680",uc_full:"1f9d1-1f3fe-200d-1f680",shortnames:[":astronaut_medium_dark_skin_tone:"],category:"people"},":astronaut_tone5:":{uc_base:"1f9d1-1f3ff-1f680",uc_full:"1f9d1-1f3ff-200d-1f680",shortnames:[":astronaut_dark_skin_tone:"],category:"people"},":cook_tone1:":{uc_base:"1f9d1-1f3fb-1f373",uc_full:"1f9d1-1f3fb-200d-1f373",shortnames:[":cook_light_skin_tone:"],category:"people"},":cook_tone2:":{uc_base:"1f9d1-1f3fc-1f373",uc_full:"1f9d1-1f3fc-200d-1f373",shortnames:[":cook_medium_light_skin_tone:"],category:"people"},":cook_tone3:":{uc_base:"1f9d1-1f3fd-1f373",uc_full:"1f9d1-1f3fd-200d-1f373",shortnames:[":cook_medium_skin_tone:"],category:"people"},":cook_tone4:":{uc_base:"1f9d1-1f3fe-1f373",uc_full:"1f9d1-1f3fe-200d-1f373",shortnames:[":cook_medium_dark_skin_tone:"],category:"people"},":cook_tone5:":{uc_base:"1f9d1-1f3ff-1f373",uc_full:"1f9d1-1f3ff-200d-1f373",shortnames:[":cook_dark_skin_tone:"],category:"people"},":factory_worker_tone1:":{uc_base:"1f9d1-1f3fb-1f3ed",uc_full:"1f9d1-1f3fb-200d-1f3ed",shortnames:[":factory_worker_light_skin_tone:"],category:"people"},":factory_worker_tone2:":{uc_base:"1f9d1-1f3fc-1f3ed",uc_full:"1f9d1-1f3fc-200d-1f3ed",shortnames:[":factory_worker_medium_light_skin_tone:"],category:"people"},":factory_worker_tone3:":{uc_base:"1f9d1-1f3fd-1f3ed",uc_full:"1f9d1-1f3fd-200d-1f3ed",shortnames:[":factory_worker_medium_skin_tone:"],category:"people"},":factory_worker_tone4:":{uc_base:"1f9d1-1f3fe-1f3ed",uc_full:"1f9d1-1f3fe-200d-1f3ed",shortnames:[":factory_worker_medium_dark_skin_tone:"],category:"people"},":factory_worker_tone5:":{uc_base:"1f9d1-1f3ff-1f3ed",uc_full:"1f9d1-1f3ff-200d-1f3ed",shortnames:[":factory_worker_dark_skin_tone:"],category:"people"},":family_man_boy_boy:":{uc_base:"1f468-1f466-1f466",uc_full:"1f468-200d-1f466-200d-1f466",shortnames:[],category:"people"},":family_man_girl_boy:":{uc_base:"1f468-1f467-1f466",uc_full:"1f468-200d-1f467-200d-1f466",shortnames:[],category:"people"},":family_man_girl_girl:":{uc_base:"1f468-1f467-1f467",uc_full:"1f468-200d-1f467-200d-1f467",shortnames:[],category:"people"},":family_man_woman_boy:":{uc_base:"1f468-1f469-1f466",uc_full:"1f468-200d-1f469-200d-1f466",shortnames:[],category:"people"},":family_mmb:":{uc_base:"1f468-1f468-1f466",uc_full:"1f468-200d-1f468-200d-1f466",shortnames:[],category:"people"},":family_mmg:":{uc_base:"1f468-1f468-1f467",uc_full:"1f468-200d-1f468-200d-1f467",shortnames:[],category:"people"},":family_mwg:":{uc_base:"1f468-1f469-1f467",uc_full:"1f468-200d-1f469-200d-1f467",shortnames:[],category:"people"},":family_woman_boy_boy:":{uc_base:"1f469-1f466-1f466",uc_full:"1f469-200d-1f466-200d-1f466",shortnames:[],category:"people"},":family_woman_girl_boy:":{uc_base:"1f469-1f467-1f466",uc_full:"1f469-200d-1f467-200d-1f466",shortnames:[],category:"people"},":family_woman_girl_girl:":{uc_base:"1f469-1f467-1f467",uc_full:"1f469-200d-1f467-200d-1f467",shortnames:[],category:"people"},":family_wwb:":{uc_base:"1f469-1f469-1f466",uc_full:"1f469-200d-1f469-200d-1f466",shortnames:[],category:"people"},":family_wwg:":{uc_base:"1f469-1f469-1f467",uc_full:"1f469-200d-1f469-200d-1f467",shortnames:[],category:"people"},":farmer_tone1:":{uc_base:"1f9d1-1f3fb-1f33e",uc_full:"1f9d1-1f3fb-200d-1f33e",shortnames:[":farmer_light_skin_tone:"],category:"people"},":farmer_tone2:":{uc_base:"1f9d1-1f3fc-1f33e",uc_full:"1f9d1-1f3fc-200d-1f33e",shortnames:[":farmer_medium_light_skin_tone:"],category:"people"},":farmer_tone3:":{uc_base:"1f9d1-1f3fd-1f33e",uc_full:"1f9d1-1f3fd-200d-1f33e",shortnames:[":farmer_medium_skin_tone:"],category:"people"},":farmer_tone4:":{uc_base:"1f9d1-1f3fe-1f33e",uc_full:"1f9d1-1f3fe-200d-1f33e",shortnames:[":farmer_medium_dark_skin_tone:"],category:"people"},":farmer_tone5:":{uc_base:"1f9d1-1f3ff-1f33e",uc_full:"1f9d1-1f3ff-200d-1f33e",shortnames:[":farmer_dark_skin_tone:"],category:"people"},":firefighter_tone1:":{uc_base:"1f9d1-1f3fb-1f692",uc_full:"1f9d1-1f3fb-200d-1f692",shortnames:[":firefighter_light_skin_tone:"],category:"people"},":firefighter_tone2:":{uc_base:"1f9d1-1f3fc-1f692",uc_full:"1f9d1-1f3fc-200d-1f692",shortnames:[":firefighter_medium_light_skin_tone:"],category:"people"},":firefighter_tone3:":{uc_base:"1f9d1-1f3fd-1f692",uc_full:"1f9d1-1f3fd-200d-1f692",shortnames:[":firefighter_medium_skin_tone:"],category:"people"},":firefighter_tone4:":{uc_base:"1f9d1-1f3fe-1f692",uc_full:"1f9d1-1f3fe-200d-1f692",shortnames:[":firefighter_medium_dark_skin_tone:"],category:"people"},":firefighter_tone5:":{uc_base:"1f9d1-1f3ff-1f692",uc_full:"1f9d1-1f3ff-200d-1f692",shortnames:[":firefighter_dark_skin_tone:"],category:"people"},":man_artist_tone1:":{uc_base:"1f468-1f3fb-1f3a8",uc_full:"1f468-1f3fb-200d-1f3a8",shortnames:[":man_artist_light_skin_tone:"],category:"people"},":man_artist_tone2:":{uc_base:"1f468-1f3fc-1f3a8",uc_full:"1f468-1f3fc-200d-1f3a8",shortnames:[":man_artist_medium_light_skin_tone:"],category:"people"},":man_artist_tone3:":{uc_base:"1f468-1f3fd-1f3a8",uc_full:"1f468-1f3fd-200d-1f3a8",shortnames:[":man_artist_medium_skin_tone:"],category:"people"},":man_artist_tone4:":{uc_base:"1f468-1f3fe-1f3a8",uc_full:"1f468-1f3fe-200d-1f3a8",shortnames:[":man_artist_medium_dark_skin_tone:"],category:"people"},":man_artist_tone5:":{uc_base:"1f468-1f3ff-1f3a8",uc_full:"1f468-1f3ff-200d-1f3a8",shortnames:[":man_artist_dark_skin_tone:"],category:"people"},":man_astronaut_tone1:":{uc_base:"1f468-1f3fb-1f680",uc_full:"1f468-1f3fb-200d-1f680",shortnames:[":man_astronaut_light_skin_tone:"],category:"people"},":man_astronaut_tone2:":{uc_base:"1f468-1f3fc-1f680",uc_full:"1f468-1f3fc-200d-1f680",shortnames:[":man_astronaut_medium_light_skin_tone:"],category:"people"},":man_astronaut_tone3:":{uc_base:"1f468-1f3fd-1f680",uc_full:"1f468-1f3fd-200d-1f680",shortnames:[":man_astronaut_medium_skin_tone:"],category:"people"},":man_astronaut_tone4:":{uc_base:"1f468-1f3fe-1f680",uc_full:"1f468-1f3fe-200d-1f680",shortnames:[":man_astronaut_medium_dark_skin_tone:"],category:"people"},":man_astronaut_tone5:":{uc_base:"1f468-1f3ff-1f680",uc_full:"1f468-1f3ff-200d-1f680",shortnames:[":man_astronaut_dark_skin_tone:"],category:"people"},":man_bald_tone1:":{uc_base:"1f468-1f3fb-1f9b2",uc_full:"1f468-1f3fb-200d-1f9b2",shortnames:[":man_bald_light_skin_tone:"],category:"people"},":man_bald_tone2:":{uc_base:"1f468-1f3fc-1f9b2",uc_full:"1f468-1f3fc-200d-1f9b2",shortnames:[":man_bald_medium_light_skin_tone:"],category:"people"},":man_bald_tone3:":{uc_base:"1f468-1f3fd-1f9b2",uc_full:"1f468-1f3fd-200d-1f9b2",shortnames:[":man_bald_medium_skin_tone:"],category:"people"},":man_bald_tone4:":{uc_base:"1f468-1f3fe-1f9b2",uc_full:"1f468-1f3fe-200d-1f9b2",shortnames:[":man_bald_medium_dark_skin_tone:"],category:"people"},":man_bald_tone5:":{uc_base:"1f468-1f3ff-1f9b2",uc_full:"1f468-1f3ff-200d-1f9b2",shortnames:[":man_bald_dark_skin_tone:"],category:"people"},":man_cook_tone1:":{uc_base:"1f468-1f3fb-1f373",uc_full:"1f468-1f3fb-200d-1f373",shortnames:[":man_cook_light_skin_tone:"],category:"people"},":man_cook_tone2:":{uc_base:"1f468-1f3fc-1f373",uc_full:"1f468-1f3fc-200d-1f373",shortnames:[":man_cook_medium_light_skin_tone:"],category:"people"},":man_cook_tone3:":{uc_base:"1f468-1f3fd-1f373",uc_full:"1f468-1f3fd-200d-1f373",shortnames:[":man_cook_medium_skin_tone:"],category:"people"},":man_cook_tone4:":{uc_base:"1f468-1f3fe-1f373",uc_full:"1f468-1f3fe-200d-1f373",shortnames:[":man_cook_medium_dark_skin_tone:"],category:"people"},":man_cook_tone5:":{uc_base:"1f468-1f3ff-1f373",uc_full:"1f468-1f3ff-200d-1f373",shortnames:[":man_cook_dark_skin_tone:"],category:"people"},":man_curly_haired_tone1:":{uc_base:"1f468-1f3fb-1f9b1",uc_full:"1f468-1f3fb-200d-1f9b1",shortnames:[":man_curly_haired_light_skin_tone:"],category:"people"},":man_curly_haired_tone2:":{uc_base:"1f468-1f3fc-1f9b1",uc_full:"1f468-1f3fc-200d-1f9b1",shortnames:[":man_curly_haired_medium_light_skin_tone:"],category:"people"},":man_curly_haired_tone3:":{uc_base:"1f468-1f3fd-1f9b1",uc_full:"1f468-1f3fd-200d-1f9b1",shortnames:[":man_curly_haired_medium_skin_tone:"],category:"people"},":man_curly_haired_tone4:":{uc_base:"1f468-1f3fe-1f9b1",uc_full:"1f468-1f3fe-200d-1f9b1",shortnames:[":man_curly_haired_medium_dark_skin_tone:"],category:"people"},":man_curly_haired_tone5:":{uc_base:"1f468-1f3ff-1f9b1",uc_full:"1f468-1f3ff-200d-1f9b1",shortnames:[":man_curly_haired_dark_skin_tone:"],category:"people"},":man_factory_worker_tone1:":{uc_base:"1f468-1f3fb-1f3ed",uc_full:"1f468-1f3fb-200d-1f3ed",shortnames:[":man_factory_worker_light_skin_tone:"],category:"people"},":man_factory_worker_tone2:":{uc_base:"1f468-1f3fc-1f3ed",uc_full:"1f468-1f3fc-200d-1f3ed",shortnames:[":man_factory_worker_medium_light_skin_tone:"],category:"people"},":man_factory_worker_tone3:":{uc_base:"1f468-1f3fd-1f3ed",uc_full:"1f468-1f3fd-200d-1f3ed",shortnames:[":man_factory_worker_medium_skin_tone:"],category:"people"},":man_factory_worker_tone4:":{uc_base:"1f468-1f3fe-1f3ed",uc_full:"1f468-1f3fe-200d-1f3ed",shortnames:[":man_factory_worker_medium_dark_skin_tone:"],category:"people"},":man_factory_worker_tone5:":{uc_base:"1f468-1f3ff-1f3ed",uc_full:"1f468-1f3ff-200d-1f3ed",shortnames:[":man_factory_worker_dark_skin_tone:"],category:"people"},":man_farmer_tone1:":{uc_base:"1f468-1f3fb-1f33e",uc_full:"1f468-1f3fb-200d-1f33e",shortnames:[":man_farmer_light_skin_tone:"],category:"people"},":man_farmer_tone2:":{uc_base:"1f468-1f3fc-1f33e",uc_full:"1f468-1f3fc-200d-1f33e",shortnames:[":man_farmer_medium_light_skin_tone:"],category:"people"},":man_farmer_tone3:":{uc_base:"1f468-1f3fd-1f33e",uc_full:"1f468-1f3fd-200d-1f33e",shortnames:[":man_farmer_medium_skin_tone:"],category:"people"},":man_farmer_tone4:":{uc_base:"1f468-1f3fe-1f33e",uc_full:"1f468-1f3fe-200d-1f33e",shortnames:[":man_farmer_medium_dark_skin_tone:"],category:"people"},":man_farmer_tone5:":{uc_base:"1f468-1f3ff-1f33e",uc_full:"1f468-1f3ff-200d-1f33e",shortnames:[":man_farmer_dark_skin_tone:"],category:"people"},":man_feeding_baby_tone1:":{uc_base:"1f468-1f3fb-1f37c",uc_full:"1f468-1f3fb-200d-1f37c",shortnames:[":man_feeding_baby_light_skin_tone:"],category:"people"},":man_feeding_baby_tone2:":{uc_base:"1f468-1f3fc-1f37c",uc_full:"1f468-1f3fc-200d-1f37c",shortnames:[":man_feeding_baby_medium_light_skin_tone:"],category:"people"},":man_feeding_baby_tone3:":{uc_base:"1f468-1f3fd-1f37c",uc_full:"1f468-1f3fd-200d-1f37c",shortnames:[":man_feeding_baby_medium_skin_tone:"],category:"people"},":man_feeding_baby_tone4:":{uc_base:"1f468-1f3fe-1f37c",uc_full:"1f468-1f3fe-200d-1f37c",shortnames:[":man_feeding_baby_medium_dark_skin_tone:"],category:"people"},":man_feeding_baby_tone5:":{uc_base:"1f468-1f3ff-1f37c",uc_full:"1f468-1f3ff-200d-1f37c",shortnames:[":man_feeding_baby_dark_skin_tone:"],category:"people"},":man_firefighter_tone1:":{uc_base:"1f468-1f3fb-1f692",uc_full:"1f468-1f3fb-200d-1f692",shortnames:[":man_firefighter_light_skin_tone:"],category:"people"},":man_firefighter_tone2:":{uc_base:"1f468-1f3fc-1f692",uc_full:"1f468-1f3fc-200d-1f692",shortnames:[":man_firefighter_medium_light_skin_tone:"],category:"people"},":man_firefighter_tone3:":{uc_base:"1f468-1f3fd-1f692",uc_full:"1f468-1f3fd-200d-1f692",shortnames:[":man_firefighter_medium_skin_tone:"],category:"people"},":man_firefighter_tone4:":{uc_base:"1f468-1f3fe-1f692",uc_full:"1f468-1f3fe-200d-1f692",shortnames:[":man_firefighter_medium_dark_skin_tone:"],category:"people"},":man_firefighter_tone5:":{uc_base:"1f468-1f3ff-1f692",uc_full:"1f468-1f3ff-200d-1f692",shortnames:[":man_firefighter_dark_skin_tone:"],category:"people"},":man_in_manual_wheelchair_tone1:":{uc_base:"1f468-1f3fb-1f9bd",uc_full:"1f468-1f3fb-200d-1f9bd",shortnames:[":man_in_manual_wheelchair_light_skin_tone:"],category:"people"},":man_in_manual_wheelchair_tone2:":{uc_base:"1f468-1f3fc-1f9bd",uc_full:"1f468-1f3fc-200d-1f9bd",shortnames:[":man_in_manual_wheelchair_medium_light_skin_tone:"],category:"people"},":man_in_manual_wheelchair_tone3:":{uc_base:"1f468-1f3fd-1f9bd",uc_full:"1f468-1f3fd-200d-1f9bd",shortnames:[":man_in_manual_wheelchair_medium_skin_tone:"],category:"people"},":man_in_manual_wheelchair_tone4:":{uc_base:"1f468-1f3fe-1f9bd",uc_full:"1f468-1f3fe-200d-1f9bd",shortnames:[":man_in_manual_wheelchair_medium_dark_skin_tone:"],category:"people"},":man_in_manual_wheelchair_tone5:":{uc_base:"1f468-1f3ff-1f9bd",uc_full:"1f468-1f3ff-200d-1f9bd",shortnames:[":man_in_manual_wheelchair_dark_skin_tone:"],category:"people"},":man_in_motorized_wheelchair_tone1:":{uc_base:"1f468-1f3fb-1f9bc",uc_full:"1f468-1f3fb-200d-1f9bc",shortnames:[":man_in_motorized_wheelchair_light_skin_tone:"],category:"people"},":man_in_motorized_wheelchair_tone2:":{uc_base:"1f468-1f3fc-1f9bc",uc_full:"1f468-1f3fc-200d-1f9bc",shortnames:[":man_in_motorized_wheelchair_medium_light_skin_tone:"],category:"people"},":man_in_motorized_wheelchair_tone3:":{uc_base:"1f468-1f3fd-1f9bc",uc_full:"1f468-1f3fd-200d-1f9bc",shortnames:[":man_in_motorized_wheelchair_medium_skin_tone:"],category:"people"},":man_in_motorized_wheelchair_tone4:":{uc_base:"1f468-1f3fe-1f9bc",uc_full:"1f468-1f3fe-200d-1f9bc",shortnames:[":man_in_motorized_wheelchair_medium_dark_skin_tone:"],category:"people"},":man_in_motorized_wheelchair_tone5:":{uc_base:"1f468-1f3ff-1f9bc",uc_full:"1f468-1f3ff-200d-1f9bc",shortnames:[":man_in_motorized_wheelchair_dark_skin_tone:"],category:"people"},":man_mechanic_tone1:":{uc_base:"1f468-1f3fb-1f527",uc_full:"1f468-1f3fb-200d-1f527",shortnames:[":man_mechanic_light_skin_tone:"],category:"people"},":man_mechanic_tone2:":{uc_base:"1f468-1f3fc-1f527",uc_full:"1f468-1f3fc-200d-1f527",shortnames:[":man_mechanic_medium_light_skin_tone:"],category:"people"},":man_mechanic_tone3:":{uc_base:"1f468-1f3fd-1f527",uc_full:"1f468-1f3fd-200d-1f527",shortnames:[":man_mechanic_medium_skin_tone:"],category:"people"},":man_mechanic_tone4:":{uc_base:"1f468-1f3fe-1f527",uc_full:"1f468-1f3fe-200d-1f527",shortnames:[":man_mechanic_medium_dark_skin_tone:"],category:"people"},":man_mechanic_tone5:":{uc_base:"1f468-1f3ff-1f527",uc_full:"1f468-1f3ff-200d-1f527",shortnames:[":man_mechanic_dark_skin_tone:"],category:"people"},":man_office_worker_tone1:":{uc_base:"1f468-1f3fb-1f4bc",uc_full:"1f468-1f3fb-200d-1f4bc",shortnames:[":man_office_worker_light_skin_tone:"],category:"people"},":man_office_worker_tone2:":{uc_base:"1f468-1f3fc-1f4bc",uc_full:"1f468-1f3fc-200d-1f4bc",shortnames:[":man_office_worker_medium_light_skin_tone:"],category:"people"},":man_office_worker_tone3:":{uc_base:"1f468-1f3fd-1f4bc",uc_full:"1f468-1f3fd-200d-1f4bc",shortnames:[":man_office_worker_medium_skin_tone:"],category:"people"},":man_office_worker_tone4:":{uc_base:"1f468-1f3fe-1f4bc",uc_full:"1f468-1f3fe-200d-1f4bc",shortnames:[":man_office_worker_medium_dark_skin_tone:"],category:"people"},":man_office_worker_tone5:":{uc_base:"1f468-1f3ff-1f4bc",uc_full:"1f468-1f3ff-200d-1f4bc",shortnames:[":man_office_worker_dark_skin_tone:"],category:"people"},":man_red_haired_tone1:":{uc_base:"1f468-1f3fb-1f9b0",uc_full:"1f468-1f3fb-200d-1f9b0",shortnames:[":man_red_haired_light_skin_tone:"],category:"people"},":man_red_haired_tone2:":{uc_base:"1f468-1f3fc-1f9b0",uc_full:"1f468-1f3fc-200d-1f9b0",shortnames:[":man_red_haired_medium_light_skin_tone:"],category:"people"},":man_red_haired_tone3:":{uc_base:"1f468-1f3fd-1f9b0",uc_full:"1f468-1f3fd-200d-1f9b0",shortnames:[":man_red_haired_medium_skin_tone:"],category:"people"},":man_red_haired_tone4:":{uc_base:"1f468-1f3fe-1f9b0",uc_full:"1f468-1f3fe-200d-1f9b0",shortnames:[":man_red_haired_medium_dark_skin_tone:"],category:"people"},":man_red_haired_tone5:":{uc_base:"1f468-1f3ff-1f9b0",uc_full:"1f468-1f3ff-200d-1f9b0",shortnames:[":man_red_haired_dark_skin_tone:"],category:"people"},":man_scientist_tone1:":{uc_base:"1f468-1f3fb-1f52c",uc_full:"1f468-1f3fb-200d-1f52c",shortnames:[":man_scientist_light_skin_tone:"],category:"people"},":man_scientist_tone2:":{uc_base:"1f468-1f3fc-1f52c",uc_full:"1f468-1f3fc-200d-1f52c",shortnames:[":man_scientist_medium_light_skin_tone:"],category:"people"},":man_scientist_tone3:":{uc_base:"1f468-1f3fd-1f52c",uc_full:"1f468-1f3fd-200d-1f52c",shortnames:[":man_scientist_medium_skin_tone:"],category:"people"},":man_scientist_tone4:":{uc_base:"1f468-1f3fe-1f52c",uc_full:"1f468-1f3fe-200d-1f52c",shortnames:[":man_scientist_medium_dark_skin_tone:"],category:"people"},":man_scientist_tone5:":{uc_base:"1f468-1f3ff-1f52c",uc_full:"1f468-1f3ff-200d-1f52c",shortnames:[":man_scientist_dark_skin_tone:"],category:"people"},":man_singer_tone1:":{uc_base:"1f468-1f3fb-1f3a4",uc_full:"1f468-1f3fb-200d-1f3a4",shortnames:[":man_singer_light_skin_tone:"],category:"people"},":man_singer_tone2:":{uc_base:"1f468-1f3fc-1f3a4",uc_full:"1f468-1f3fc-200d-1f3a4",shortnames:[":man_singer_medium_light_skin_tone:"],category:"people"},":man_singer_tone3:":{uc_base:"1f468-1f3fd-1f3a4",uc_full:"1f468-1f3fd-200d-1f3a4",shortnames:[":man_singer_medium_skin_tone:"],category:"people"},":man_singer_tone4:":{uc_base:"1f468-1f3fe-1f3a4",uc_full:"1f468-1f3fe-200d-1f3a4",shortnames:[":man_singer_medium_dark_skin_tone:"],category:"people"},":man_singer_tone5:":{uc_base:"1f468-1f3ff-1f3a4",uc_full:"1f468-1f3ff-200d-1f3a4",shortnames:[":man_singer_dark_skin_tone:"],category:"people"},":man_student_tone1:":{uc_base:"1f468-1f3fb-1f393",uc_full:"1f468-1f3fb-200d-1f393",shortnames:[":man_student_light_skin_tone:"],category:"people"},":man_student_tone2:":{uc_base:"1f468-1f3fc-1f393",uc_full:"1f468-1f3fc-200d-1f393",shortnames:[":man_student_medium_light_skin_tone:"],category:"people"},":man_student_tone3:":{uc_base:"1f468-1f3fd-1f393",uc_full:"1f468-1f3fd-200d-1f393",shortnames:[":man_student_medium_skin_tone:"],category:"people"},":man_student_tone4:":{uc_base:"1f468-1f3fe-1f393",uc_full:"1f468-1f3fe-200d-1f393",shortnames:[":man_student_medium_dark_skin_tone:"],category:"people"},":man_student_tone5:":{uc_base:"1f468-1f3ff-1f393",uc_full:"1f468-1f3ff-200d-1f393",shortnames:[":man_student_dark_skin_tone:"],category:"people"},":man_teacher_tone1:":{uc_base:"1f468-1f3fb-1f3eb",uc_full:"1f468-1f3fb-200d-1f3eb",shortnames:[":man_teacher_light_skin_tone:"],category:"people"},":man_teacher_tone2:":{uc_base:"1f468-1f3fc-1f3eb",uc_full:"1f468-1f3fc-200d-1f3eb",shortnames:[":man_teacher_medium_light_skin_tone:"],category:"people"},":man_teacher_tone3:":{uc_base:"1f468-1f3fd-1f3eb",uc_full:"1f468-1f3fd-200d-1f3eb",shortnames:[":man_teacher_medium_skin_tone:"],category:"people"},":man_teacher_tone4:":{uc_base:"1f468-1f3fe-1f3eb",uc_full:"1f468-1f3fe-200d-1f3eb",shortnames:[":man_teacher_medium_dark_skin_tone:"],category:"people"},":man_teacher_tone5:":{uc_base:"1f468-1f3ff-1f3eb",uc_full:"1f468-1f3ff-200d-1f3eb",shortnames:[":man_teacher_dark_skin_tone:"],category:"people"},":man_technologist_tone1:":{uc_base:"1f468-1f3fb-1f4bb",uc_full:"1f468-1f3fb-200d-1f4bb",shortnames:[":man_technologist_light_skin_tone:"],category:"people"},":man_technologist_tone2:":{uc_base:"1f468-1f3fc-1f4bb",uc_full:"1f468-1f3fc-200d-1f4bb",shortnames:[":man_technologist_medium_light_skin_tone:"],category:"people"},":man_technologist_tone3:":{uc_base:"1f468-1f3fd-1f4bb",uc_full:"1f468-1f3fd-200d-1f4bb",shortnames:[":man_technologist_medium_skin_tone:"],category:"people"},":man_technologist_tone4:":{uc_base:"1f468-1f3fe-1f4bb",uc_full:"1f468-1f3fe-200d-1f4bb",shortnames:[":man_technologist_medium_dark_skin_tone:"],category:"people"},":man_technologist_tone5:":{uc_base:"1f468-1f3ff-1f4bb",uc_full:"1f468-1f3ff-200d-1f4bb",shortnames:[":man_technologist_dark_skin_tone:"],category:"people"},":man_white_haired_tone1:":{uc_base:"1f468-1f3fb-1f9b3",uc_full:"1f468-1f3fb-200d-1f9b3",shortnames:[":man_white_haired_light_skin_tone:"],category:"people"},":man_white_haired_tone2:":{uc_base:"1f468-1f3fc-1f9b3",uc_full:"1f468-1f3fc-200d-1f9b3",shortnames:[":man_white_haired_medium_light_skin_tone:"],category:"people"},":man_white_haired_tone3:":{uc_base:"1f468-1f3fd-1f9b3",uc_full:"1f468-1f3fd-200d-1f9b3",shortnames:[":man_white_haired_medium_skin_tone:"],category:"people"},":man_white_haired_tone4:":{uc_base:"1f468-1f3fe-1f9b3",uc_full:"1f468-1f3fe-200d-1f9b3",shortnames:[":man_white_haired_medium_dark_skin_tone:"],category:"people"},":man_white_haired_tone5:":{uc_base:"1f468-1f3ff-1f9b3",uc_full:"1f468-1f3ff-200d-1f9b3",shortnames:[":man_white_haired_dark_skin_tone:"],category:"people"},":man_with_probing_cane_tone1:":{uc_base:"1f468-1f3fb-1f9af",uc_full:"1f468-1f3fb-200d-1f9af",shortnames:[":man_with_probing_cane_light_skin_tone:"],category:"people"},":man_with_probing_cane_tone2:":{uc_base:"1f468-1f3fc-1f9af",uc_full:"1f468-1f3fc-200d-1f9af",shortnames:[":man_with_probing_cane_medium_light_skin_tone:"],category:"people"},":man_with_probing_cane_tone3:":{uc_base:"1f468-1f3fd-1f9af",uc_full:"1f468-1f3fd-200d-1f9af",shortnames:[":man_with_probing_cane_medium_skin_tone:"],category:"people"},":man_with_probing_cane_tone4:":{uc_base:"1f468-1f3fe-1f9af",uc_full:"1f468-1f3fe-200d-1f9af",shortnames:[":man_with_probing_cane_medium_dark_skin_tone:"],category:"people"},":man_with_probing_cane_tone5:":{uc_base:"1f468-1f3ff-1f9af",uc_full:"1f468-1f3ff-200d-1f9af",shortnames:[":man_with_probing_cane_dark_skin_tone:"],category:"people"},":mechanic_tone1:":{uc_base:"1f9d1-1f3fb-1f527",uc_full:"1f9d1-1f3fb-200d-1f527",shortnames:[":mechanic_light_skin_tone:"],category:"people"},":mechanic_tone2:":{uc_base:"1f9d1-1f3fc-1f527",uc_full:"1f9d1-1f3fc-200d-1f527",shortnames:[":mechanic_medium_light_skin_tone:"],category:"people"},":mechanic_tone3:":{uc_base:"1f9d1-1f3fd-1f527",uc_full:"1f9d1-1f3fd-200d-1f527",shortnames:[":mechanic_medium_skin_tone:"],category:"people"},":mechanic_tone4:":{uc_base:"1f9d1-1f3fe-1f527",uc_full:"1f9d1-1f3fe-200d-1f527",shortnames:[":mechanic_medium_dark_skin_tone:"],category:"people"},":mechanic_tone5:":{uc_base:"1f9d1-1f3ff-1f527",uc_full:"1f9d1-1f3ff-200d-1f527",shortnames:[":mechanic_dark_skin_tone:"],category:"people"},":mx_claus_tone1:":{uc_base:"1f9d1-1f3fb-1f384",uc_full:"1f9d1-1f3fb-200d-1f384",shortnames:[":mx_claus_light_skin_tone:"],category:"people"},":mx_claus_tone2:":{uc_base:"1f9d1-1f3fc-1f384",uc_full:"1f9d1-1f3fc-200d-1f384",shortnames:[":mx_claus_medium_light_skin_tone:"],category:"people"},":mx_claus_tone3:":{uc_base:"1f9d1-1f3fd-1f384",uc_full:"1f9d1-1f3fd-200d-1f384",shortnames:[":mx_claus_medium_skin_tone:"],category:"people"},":mx_claus_tone4:":{uc_base:"1f9d1-1f3fe-1f384",uc_full:"1f9d1-1f3fe-200d-1f384",shortnames:[":mx_claus_medium_dark_skin_tone:"],category:"people"},":mx_claus_tone5:":{uc_base:"1f9d1-1f3ff-1f384",uc_full:"1f9d1-1f3ff-200d-1f384",shortnames:[":mx_claus_dark_skin_tone:"],category:"people"},":office_worker_tone1:":{uc_base:"1f9d1-1f3fb-1f4bc",uc_full:"1f9d1-1f3fb-200d-1f4bc",shortnames:[":office_worker_light_skin_tone:"],category:"people"},":office_worker_tone2:":{uc_base:"1f9d1-1f3fc-1f4bc",uc_full:"1f9d1-1f3fc-200d-1f4bc",shortnames:[":office_worker_medium_light_skin_tone:"],category:"people"},":office_worker_tone3:":{uc_base:"1f9d1-1f3fd-1f4bc",uc_full:"1f9d1-1f3fd-200d-1f4bc",shortnames:[":office_worker_medium_skin_tone:"],category:"people"},":office_worker_tone4:":{uc_base:"1f9d1-1f3fe-1f4bc",uc_full:"1f9d1-1f3fe-200d-1f4bc",shortnames:[":office_worker_medium_dark_skin_tone:"],category:"people"},":office_worker_tone5:":{uc_base:"1f9d1-1f3ff-1f4bc",uc_full:"1f9d1-1f3ff-200d-1f4bc",shortnames:[":office_worker_dark_skin_tone:"],category:"people"},":people_holding_hands:":{uc_base:"1f9d1-1f91d-1f9d1",uc_full:"1f9d1-200d-1f91d-200d-1f9d1",shortnames:[],category:"people"},":person_feeding_baby_tone1:":{uc_base:"1f9d1-1f3fb-1f37c",uc_full:"1f9d1-1f3fb-200d-1f37c",shortnames:[":person_feeding_baby_light_skin_tone:"],category:"people"},":person_feeding_baby_tone2:":{uc_base:"1f9d1-1f3fc-1f37c",uc_full:"1f9d1-1f3fc-200d-1f37c",shortnames:[":person_feeding_baby_medium_light_skin_tone:"],category:"people"},":person_feeding_baby_tone3:":{uc_base:"1f9d1-1f3fd-1f37c",uc_full:"1f9d1-1f3fd-200d-1f37c",shortnames:[":person_feeding_baby_medium_skin_tone:"],category:"people"},":person_feeding_baby_tone4:":{uc_base:"1f9d1-1f3fe-1f37c",uc_full:"1f9d1-1f3fe-200d-1f37c",shortnames:[":person_feeding_baby_medium_dark_skin_tone:"],category:"people"},":person_feeding_baby_tone5:":{uc_base:"1f9d1-1f3ff-1f37c",uc_full:"1f9d1-1f3ff-200d-1f37c",shortnames:[":person_feeding_baby_dark_skin_tone:"],category:"people"},":person_in_manual_wheelchair_tone1:":{uc_base:"1f9d1-1f3fb-1f9bd",uc_full:"1f9d1-1f3fb-200d-1f9bd",shortnames:[":person_in_manual_wheelchair_light_skin_tone:"],category:"people"},":person_in_manual_wheelchair_tone2:":{uc_base:"1f9d1-1f3fc-1f9bd",uc_full:"1f9d1-1f3fc-200d-1f9bd",shortnames:[":person_in_manual_wheelchair_medium_light_skin_tone:"],category:"people"},":person_in_manual_wheelchair_tone3:":{uc_base:"1f9d1-1f3fd-1f9bd",uc_full:"1f9d1-1f3fd-200d-1f9bd",shortnames:[":person_in_manual_wheelchair_medium_skin_tone:"],category:"people"},":person_in_manual_wheelchair_tone4:":{uc_base:"1f9d1-1f3fe-1f9bd",uc_full:"1f9d1-1f3fe-200d-1f9bd",shortnames:[":person_in_manual_wheelchair_medium_dark_skin_tone:"],category:"people"},":person_in_manual_wheelchair_tone5:":{uc_base:"1f9d1-1f3ff-1f9bd",uc_full:"1f9d1-1f3ff-200d-1f9bd",shortnames:[":person_in_manual_wheelchair_dark_skin_tone:"],category:"people"},":person_in_motorized_wheelchair_tone1:":{uc_base:"1f9d1-1f3fb-1f9bc",uc_full:"1f9d1-1f3fb-200d-1f9bc",shortnames:[":person_in_motorized_wheelchair_light_skin_tone:"],category:"people"},":person_in_motorized_wheelchair_tone2:":{uc_base:"1f9d1-1f3fc-1f9bc",uc_full:"1f9d1-1f3fc-200d-1f9bc",shortnames:[":person_in_motorized_wheelchair_medium_light_skin_tone:"],category:"people"},":person_in_motorized_wheelchair_tone3:":{uc_base:"1f9d1-1f3fd-1f9bc",uc_full:"1f9d1-1f3fd-200d-1f9bc",shortnames:[":person_in_motorized_wheelchair_medium_skin_tone:"],category:"people"},":person_in_motorized_wheelchair_tone4:":{uc_base:"1f9d1-1f3fe-1f9bc",uc_full:"1f9d1-1f3fe-200d-1f9bc",shortnames:[":person_in_motorized_wheelchair_medium_dark_skin_tone:"],category:"people"},":person_in_motorized_wheelchair_tone5:":{uc_base:"1f9d1-1f3ff-1f9bc",uc_full:"1f9d1-1f3ff-200d-1f9bc",shortnames:[":person_in_motorized_wheelchair_dark_skin_tone:"],category:"people"},":person_tone1_bald:":{uc_base:"1f9d1-1f3fb-1f9b2",uc_full:"1f9d1-1f3fb-200d-1f9b2",shortnames:[":person_light_skin_tone_bald:"],category:"people"},":person_tone1_curly_hair:":{uc_base:"1f9d1-1f3fb-1f9b1",uc_full:"1f9d1-1f3fb-200d-1f9b1",shortnames:[":person_light_skin_tone_curly_hair:"],category:"people"},":person_tone1_red_hair:":{uc_base:"1f9d1-1f3fb-1f9b0",uc_full:"1f9d1-1f3fb-200d-1f9b0",shortnames:[":person_light_skin_tone_red_hair:"],category:"people"},":person_tone1_white_hair:":{uc_base:"1f9d1-1f3fb-1f9b3",uc_full:"1f9d1-1f3fb-200d-1f9b3",shortnames:[":person_light_skin_tone_white_hair:"],category:"people"},":person_tone2_bald:":{uc_base:"1f9d1-1f3fc-1f9b2",uc_full:"1f9d1-1f3fc-200d-1f9b2",shortnames:[":person_medium_light_skin_tone_bald:"],category:"people"},":person_tone2_curly_hair:":{uc_base:"1f9d1-1f3fc-1f9b1",uc_full:"1f9d1-1f3fc-200d-1f9b1",shortnames:[":person_medium_light_skin_tone_curly_hair:"],category:"people"},":person_tone2_red_hair:":{uc_base:"1f9d1-1f3fc-1f9b0",uc_full:"1f9d1-1f3fc-200d-1f9b0",shortnames:[":person_medium_light_skin_tone_red_hair:"],category:"people"},":person_tone2_white_hair:":{uc_base:"1f9d1-1f3fc-1f9b3",uc_full:"1f9d1-1f3fc-200d-1f9b3",shortnames:[":person_medium_light_skin_tone_white_hair:"],category:"people"},":person_tone3_bald:":{uc_base:"1f9d1-1f3fd-1f9b2",uc_full:"1f9d1-1f3fd-200d-1f9b2",shortnames:[":person_medium_skin_tone_bald:"],category:"people"},":person_tone3_curly_hair:":{uc_base:"1f9d1-1f3fd-1f9b1",uc_full:"1f9d1-1f3fd-200d-1f9b1",shortnames:[":person_medium_skin_tone_curly_hair:"],category:"people"},":person_tone3_red_hair:":{uc_base:"1f9d1-1f3fd-1f9b0",uc_full:"1f9d1-1f3fd-200d-1f9b0",shortnames:[":person_medium_skin_tone_red_hair:"],category:"people"},":person_tone3_white_hair:":{uc_base:"1f9d1-1f3fd-1f9b3",uc_full:"1f9d1-1f3fd-200d-1f9b3",shortnames:[":person_medium_skin_tone_white_hair:"],category:"people"},":person_tone4_bald:":{uc_base:"1f9d1-1f3fe-1f9b2",uc_full:"1f9d1-1f3fe-200d-1f9b2",shortnames:[":person_medium_dark_skin_tone_bald:"],category:"people"},":person_tone4_curly_hair:":{uc_base:"1f9d1-1f3fe-1f9b1",uc_full:"1f9d1-1f3fe-200d-1f9b1",shortnames:[":person_medium_dark_skin_tone_curly_hair:"],category:"people"},":person_tone4_red_hair:":{uc_base:"1f9d1-1f3fe-1f9b0",uc_full:"1f9d1-1f3fe-200d-1f9b0",shortnames:[":person_medium_dark_skin_tone_red_hair:"],category:"people"},":person_tone4_white_hair:":{uc_base:"1f9d1-1f3fe-1f9b3",uc_full:"1f9d1-1f3fe-200d-1f9b3",shortnames:[":person_medium_dark_skin_tone_white_hair:"],category:"people"},":person_tone5_bald:":{uc_base:"1f9d1-1f3ff-1f9b2",uc_full:"1f9d1-1f3ff-200d-1f9b2",shortnames:[":person_dark_skin_tone_bald:"],category:"people"},":person_tone5_curly_hair:":{uc_base:"1f9d1-1f3ff-1f9b1",uc_full:"1f9d1-1f3ff-200d-1f9b1",shortnames:[":person_dark_skin_tone_curly_hair:"],category:"people"},":person_tone5_red_hair:":{uc_base:"1f9d1-1f3ff-1f9b0",uc_full:"1f9d1-1f3ff-200d-1f9b0",shortnames:[":person_dark_skin_tone_red_hair:"],category:"people"},":person_tone5_white_hair:":{uc_base:"1f9d1-1f3ff-1f9b3",uc_full:"1f9d1-1f3ff-200d-1f9b3",shortnames:[":person_dark_skin_tone_white_hair:"],category:"people"},":person_with_probing_cane_tone1:":{uc_base:"1f9d1-1f3fb-1f9af",uc_full:"1f9d1-1f3fb-200d-1f9af",shortnames:[":person_with_probing_cane_light_skin_tone:"],category:"people"},":person_with_probing_cane_tone2:":{uc_base:"1f9d1-1f3fc-1f9af",uc_full:"1f9d1-1f3fc-200d-1f9af",shortnames:[":person_with_probing_cane_medium_light_skin_tone:"], -category:"people"},":person_with_probing_cane_tone3:":{uc_base:"1f9d1-1f3fd-1f9af",uc_full:"1f9d1-1f3fd-200d-1f9af",shortnames:[":person_with_probing_cane_medium_skin_tone:"],category:"people"},":person_with_probing_cane_tone4:":{uc_base:"1f9d1-1f3fe-1f9af",uc_full:"1f9d1-1f3fe-200d-1f9af",shortnames:[":person_with_probing_cane_medium_dark_skin_tone:"],category:"people"},":person_with_probing_cane_tone5:":{uc_base:"1f9d1-1f3ff-1f9af",uc_full:"1f9d1-1f3ff-200d-1f9af",shortnames:[":person_with_probing_cane_dark_skin_tone:"],category:"people"},":scientist_tone1:":{uc_base:"1f9d1-1f3fb-1f52c",uc_full:"1f9d1-1f3fb-200d-1f52c",shortnames:[":scientist_light_skin_tone:"],category:"people"},":scientist_tone2:":{uc_base:"1f9d1-1f3fc-1f52c",uc_full:"1f9d1-1f3fc-200d-1f52c",shortnames:[":scientist_medium_light_skin_tone:"],category:"people"},":scientist_tone3:":{uc_base:"1f9d1-1f3fd-1f52c",uc_full:"1f9d1-1f3fd-200d-1f52c",shortnames:[":scientist_medium_skin_tone:"],category:"people"},":scientist_tone4:":{uc_base:"1f9d1-1f3fe-1f52c",uc_full:"1f9d1-1f3fe-200d-1f52c",shortnames:[":scientist_medium_dark_skin_tone:"],category:"people"},":scientist_tone5:":{uc_base:"1f9d1-1f3ff-1f52c",uc_full:"1f9d1-1f3ff-200d-1f52c",shortnames:[":scientist_dark_skin_tone:"],category:"people"},":singer_tone1:":{uc_base:"1f9d1-1f3fb-1f3a4",uc_full:"1f9d1-1f3fb-200d-1f3a4",shortnames:[":singer_light_skin_tone:"],category:"people"},":singer_tone2:":{uc_base:"1f9d1-1f3fc-1f3a4",uc_full:"1f9d1-1f3fc-200d-1f3a4",shortnames:[":singer_medium_light_skin_tone:"],category:"people"},":singer_tone3:":{uc_base:"1f9d1-1f3fd-1f3a4",uc_full:"1f9d1-1f3fd-200d-1f3a4",shortnames:[":singer_medium_skin_tone:"],category:"people"},":singer_tone4:":{uc_base:"1f9d1-1f3fe-1f3a4",uc_full:"1f9d1-1f3fe-200d-1f3a4",shortnames:[":singer_medium_dark_skin_tone:"],category:"people"},":singer_tone5:":{uc_base:"1f9d1-1f3ff-1f3a4",uc_full:"1f9d1-1f3ff-200d-1f3a4",shortnames:[":singer_dark_skin_tone:"],category:"people"},":student_tone1:":{uc_base:"1f9d1-1f3fb-1f393",uc_full:"1f9d1-1f3fb-200d-1f393",shortnames:[":student_light_skin_tone:"],category:"people"},":student_tone2:":{uc_base:"1f9d1-1f3fc-1f393",uc_full:"1f9d1-1f3fc-200d-1f393",shortnames:[":student_medium_light_skin_tone:"],category:"people"},":student_tone3:":{uc_base:"1f9d1-1f3fd-1f393",uc_full:"1f9d1-1f3fd-200d-1f393",shortnames:[":student_medium_skin_tone:"],category:"people"},":student_tone4:":{uc_base:"1f9d1-1f3fe-1f393",uc_full:"1f9d1-1f3fe-200d-1f393",shortnames:[":student_medium_dark_skin_tone:"],category:"people"},":student_tone5:":{uc_base:"1f9d1-1f3ff-1f393",uc_full:"1f9d1-1f3ff-200d-1f393",shortnames:[":student_dark_skin_tone:"],category:"people"},":teacher_tone1:":{uc_base:"1f9d1-1f3fb-1f3eb",uc_full:"1f9d1-1f3fb-200d-1f3eb",shortnames:[":teacher_light_skin_tone:"],category:"people"},":teacher_tone2:":{uc_base:"1f9d1-1f3fc-1f3eb",uc_full:"1f9d1-1f3fc-200d-1f3eb",shortnames:[":teacher_medium_light_skin_tone:"],category:"people"},":teacher_tone3:":{uc_base:"1f9d1-1f3fd-1f3eb",uc_full:"1f9d1-1f3fd-200d-1f3eb",shortnames:[":teacher_medium_skin_tone:"],category:"people"},":teacher_tone4:":{uc_base:"1f9d1-1f3fe-1f3eb",uc_full:"1f9d1-1f3fe-200d-1f3eb",shortnames:[":teacher_medium_dark_skin_tone:"],category:"people"},":teacher_tone5:":{uc_base:"1f9d1-1f3ff-1f3eb",uc_full:"1f9d1-1f3ff-200d-1f3eb",shortnames:[":teacher_dark_skin_tone:"],category:"people"},":technologist_tone1:":{uc_base:"1f9d1-1f3fb-1f4bb",uc_full:"1f9d1-1f3fb-200d-1f4bb",shortnames:[":technologist_light_skin_tone:"],category:"people"},":technologist_tone2:":{uc_base:"1f9d1-1f3fc-1f4bb",uc_full:"1f9d1-1f3fc-200d-1f4bb",shortnames:[":technologist_medium_light_skin_tone:"],category:"people"},":technologist_tone3:":{uc_base:"1f9d1-1f3fd-1f4bb",uc_full:"1f9d1-1f3fd-200d-1f4bb",shortnames:[":technologist_medium_skin_tone:"],category:"people"},":technologist_tone4:":{uc_base:"1f9d1-1f3fe-1f4bb",uc_full:"1f9d1-1f3fe-200d-1f4bb",shortnames:[":technologist_medium_dark_skin_tone:"],category:"people"},":technologist_tone5:":{uc_base:"1f9d1-1f3ff-1f4bb",uc_full:"1f9d1-1f3ff-200d-1f4bb",shortnames:[":technologist_dark_skin_tone:"],category:"people"},":woman_artist_tone1:":{uc_base:"1f469-1f3fb-1f3a8",uc_full:"1f469-1f3fb-200d-1f3a8",shortnames:[":woman_artist_light_skin_tone:"],category:"people"},":woman_artist_tone2:":{uc_base:"1f469-1f3fc-1f3a8",uc_full:"1f469-1f3fc-200d-1f3a8",shortnames:[":woman_artist_medium_light_skin_tone:"],category:"people"},":woman_artist_tone3:":{uc_base:"1f469-1f3fd-1f3a8",uc_full:"1f469-1f3fd-200d-1f3a8",shortnames:[":woman_artist_medium_skin_tone:"],category:"people"},":woman_artist_tone4:":{uc_base:"1f469-1f3fe-1f3a8",uc_full:"1f469-1f3fe-200d-1f3a8",shortnames:[":woman_artist_medium_dark_skin_tone:"],category:"people"},":woman_artist_tone5:":{uc_base:"1f469-1f3ff-1f3a8",uc_full:"1f469-1f3ff-200d-1f3a8",shortnames:[":woman_artist_dark_skin_tone:"],category:"people"},":woman_astronaut_tone1:":{uc_base:"1f469-1f3fb-1f680",uc_full:"1f469-1f3fb-200d-1f680",shortnames:[":woman_astronaut_light_skin_tone:"],category:"people"},":woman_astronaut_tone2:":{uc_base:"1f469-1f3fc-1f680",uc_full:"1f469-1f3fc-200d-1f680",shortnames:[":woman_astronaut_medium_light_skin_tone:"],category:"people"},":woman_astronaut_tone3:":{uc_base:"1f469-1f3fd-1f680",uc_full:"1f469-1f3fd-200d-1f680",shortnames:[":woman_astronaut_medium_skin_tone:"],category:"people"},":woman_astronaut_tone4:":{uc_base:"1f469-1f3fe-1f680",uc_full:"1f469-1f3fe-200d-1f680",shortnames:[":woman_astronaut_medium_dark_skin_tone:"],category:"people"},":woman_astronaut_tone5:":{uc_base:"1f469-1f3ff-1f680",uc_full:"1f469-1f3ff-200d-1f680",shortnames:[":woman_astronaut_dark_skin_tone:"],category:"people"},":woman_bald_tone1:":{uc_base:"1f469-1f3fb-1f9b2",uc_full:"1f469-1f3fb-200d-1f9b2",shortnames:[":woman_bald_light_skin_tone:"],category:"people"},":woman_bald_tone2:":{uc_base:"1f469-1f3fc-1f9b2",uc_full:"1f469-1f3fc-200d-1f9b2",shortnames:[":woman_bald_medium_light_skin_tone:"],category:"people"},":woman_bald_tone3:":{uc_base:"1f469-1f3fd-1f9b2",uc_full:"1f469-1f3fd-200d-1f9b2",shortnames:[":woman_bald_medium_skin_tone:"],category:"people"},":woman_bald_tone4:":{uc_base:"1f469-1f3fe-1f9b2",uc_full:"1f469-1f3fe-200d-1f9b2",shortnames:[":woman_bald_medium_dark_skin_tone:"],category:"people"},":woman_bald_tone5:":{uc_base:"1f469-1f3ff-1f9b2",uc_full:"1f469-1f3ff-200d-1f9b2",shortnames:[":woman_bald_dark_skin_tone:"],category:"people"},":woman_cook_tone1:":{uc_base:"1f469-1f3fb-1f373",uc_full:"1f469-1f3fb-200d-1f373",shortnames:[":woman_cook_light_skin_tone:"],category:"people"},":woman_cook_tone2:":{uc_base:"1f469-1f3fc-1f373",uc_full:"1f469-1f3fc-200d-1f373",shortnames:[":woman_cook_medium_light_skin_tone:"],category:"people"},":woman_cook_tone3:":{uc_base:"1f469-1f3fd-1f373",uc_full:"1f469-1f3fd-200d-1f373",shortnames:[":woman_cook_medium_skin_tone:"],category:"people"},":woman_cook_tone4:":{uc_base:"1f469-1f3fe-1f373",uc_full:"1f469-1f3fe-200d-1f373",shortnames:[":woman_cook_medium_dark_skin_tone:"],category:"people"},":woman_cook_tone5:":{uc_base:"1f469-1f3ff-1f373",uc_full:"1f469-1f3ff-200d-1f373",shortnames:[":woman_cook_dark_skin_tone:"],category:"people"},":woman_curly_haired_tone1:":{uc_base:"1f469-1f3fb-1f9b1",uc_full:"1f469-1f3fb-200d-1f9b1",shortnames:[":woman_curly_haired_light_skin_tone:"],category:"people"},":woman_curly_haired_tone2:":{uc_base:"1f469-1f3fc-1f9b1",uc_full:"1f469-1f3fc-200d-1f9b1",shortnames:[":woman_curly_haired_medium_light_skin_tone:"],category:"people"},":woman_curly_haired_tone3:":{uc_base:"1f469-1f3fd-1f9b1",uc_full:"1f469-1f3fd-200d-1f9b1",shortnames:[":woman_curly_haired_medium_skin_tone:"],category:"people"},":woman_curly_haired_tone4:":{uc_base:"1f469-1f3fe-1f9b1",uc_full:"1f469-1f3fe-200d-1f9b1",shortnames:[":woman_curly_haired_medium_dark_skin_tone:"],category:"people"},":woman_curly_haired_tone5:":{uc_base:"1f469-1f3ff-1f9b1",uc_full:"1f469-1f3ff-200d-1f9b1",shortnames:[":woman_curly_haired_dark_skin_tone:"],category:"people"},":woman_factory_worker_tone1:":{uc_base:"1f469-1f3fb-1f3ed",uc_full:"1f469-1f3fb-200d-1f3ed",shortnames:[":woman_factory_worker_light_skin_tone:"],category:"people"},":woman_factory_worker_tone2:":{uc_base:"1f469-1f3fc-1f3ed",uc_full:"1f469-1f3fc-200d-1f3ed",shortnames:[":woman_factory_worker_medium_light_skin_tone:"],category:"people"},":woman_factory_worker_tone3:":{uc_base:"1f469-1f3fd-1f3ed",uc_full:"1f469-1f3fd-200d-1f3ed",shortnames:[":woman_factory_worker_medium_skin_tone:"],category:"people"},":woman_factory_worker_tone4:":{uc_base:"1f469-1f3fe-1f3ed",uc_full:"1f469-1f3fe-200d-1f3ed",shortnames:[":woman_factory_worker_medium_dark_skin_tone:"],category:"people"},":woman_factory_worker_tone5:":{uc_base:"1f469-1f3ff-1f3ed",uc_full:"1f469-1f3ff-200d-1f3ed",shortnames:[":woman_factory_worker_dark_skin_tone:"],category:"people"},":woman_farmer_tone1:":{uc_base:"1f469-1f3fb-1f33e",uc_full:"1f469-1f3fb-200d-1f33e",shortnames:[":woman_farmer_light_skin_tone:"],category:"people"},":woman_farmer_tone2:":{uc_base:"1f469-1f3fc-1f33e",uc_full:"1f469-1f3fc-200d-1f33e",shortnames:[":woman_farmer_medium_light_skin_tone:"],category:"people"},":woman_farmer_tone3:":{uc_base:"1f469-1f3fd-1f33e",uc_full:"1f469-1f3fd-200d-1f33e",shortnames:[":woman_farmer_medium_skin_tone:"],category:"people"},":woman_farmer_tone4:":{uc_base:"1f469-1f3fe-1f33e",uc_full:"1f469-1f3fe-200d-1f33e",shortnames:[":woman_farmer_medium_dark_skin_tone:"],category:"people"},":woman_farmer_tone5:":{uc_base:"1f469-1f3ff-1f33e",uc_full:"1f469-1f3ff-200d-1f33e",shortnames:[":woman_farmer_dark_skin_tone:"],category:"people"},":woman_feeding_baby_tone1:":{uc_base:"1f469-1f3fb-1f37c",uc_full:"1f469-1f3fb-200d-1f37c",shortnames:[":woman_feeding_baby_light_skin_tone:"],category:"people"},":woman_feeding_baby_tone2:":{uc_base:"1f469-1f3fc-1f37c",uc_full:"1f469-1f3fc-200d-1f37c",shortnames:[":woman_feeding_baby_medium_light_skin_tone:"],category:"people"},":woman_feeding_baby_tone3:":{uc_base:"1f469-1f3fd-1f37c",uc_full:"1f469-1f3fd-200d-1f37c",shortnames:[":woman_feeding_baby_medium_skin_tone:"],category:"people"},":woman_feeding_baby_tone4:":{uc_base:"1f469-1f3fe-1f37c",uc_full:"1f469-1f3fe-200d-1f37c",shortnames:[":woman_feeding_baby_medium_dark_skin_tone:"],category:"people"},":woman_feeding_baby_tone5:":{uc_base:"1f469-1f3ff-1f37c",uc_full:"1f469-1f3ff-200d-1f37c",shortnames:[":woman_feeding_baby_dark_skin_tone:"],category:"people"},":woman_firefighter_tone1:":{uc_base:"1f469-1f3fb-1f692",uc_full:"1f469-1f3fb-200d-1f692",shortnames:[":woman_firefighter_light_skin_tone:"],category:"people"},":woman_firefighter_tone2:":{uc_base:"1f469-1f3fc-1f692",uc_full:"1f469-1f3fc-200d-1f692",shortnames:[":woman_firefighter_medium_light_skin_tone:"],category:"people"},":woman_firefighter_tone3:":{uc_base:"1f469-1f3fd-1f692",uc_full:"1f469-1f3fd-200d-1f692",shortnames:[":woman_firefighter_medium_skin_tone:"],category:"people"},":woman_firefighter_tone4:":{uc_base:"1f469-1f3fe-1f692",uc_full:"1f469-1f3fe-200d-1f692",shortnames:[":woman_firefighter_medium_dark_skin_tone:"],category:"people"},":woman_firefighter_tone5:":{uc_base:"1f469-1f3ff-1f692",uc_full:"1f469-1f3ff-200d-1f692",shortnames:[":woman_firefighter_dark_skin_tone:"],category:"people"},":woman_in_manual_wheelchair_tone1:":{uc_base:"1f469-1f3fb-1f9bd",uc_full:"1f469-1f3fb-200d-1f9bd",shortnames:[":woman_in_manual_wheelchair_light_skin_tone:"],category:"people"},":woman_in_manual_wheelchair_tone2:":{uc_base:"1f469-1f3fc-1f9bd",uc_full:"1f469-1f3fc-200d-1f9bd",shortnames:[":woman_in_manual_wheelchair_medium_light_skin_tone:"],category:"people"},":woman_in_manual_wheelchair_tone3:":{uc_base:"1f469-1f3fd-1f9bd",uc_full:"1f469-1f3fd-200d-1f9bd",shortnames:[":woman_in_manual_wheelchair_medium_skin_tone:"],category:"people"},":woman_in_manual_wheelchair_tone4:":{uc_base:"1f469-1f3fe-1f9bd",uc_full:"1f469-1f3fe-200d-1f9bd",shortnames:[":woman_in_manual_wheelchair_medium_dark_skin_tone:"],category:"people"},":woman_in_manual_wheelchair_tone5:":{uc_base:"1f469-1f3ff-1f9bd",uc_full:"1f469-1f3ff-200d-1f9bd",shortnames:[":woman_in_manual_wheelchair_dark_skin_tone:"],category:"people"},":woman_in_motorized_wheelchair_tone1:":{uc_base:"1f469-1f3fb-1f9bc",uc_full:"1f469-1f3fb-200d-1f9bc",shortnames:[":woman_in_motorized_wheelchair_light_skin_tone:"],category:"people"},":woman_in_motorized_wheelchair_tone2:":{uc_base:"1f469-1f3fc-1f9bc",uc_full:"1f469-1f3fc-200d-1f9bc",shortnames:[":woman_in_motorized_wheelchair_medium_light_skin_tone:"],category:"people"},":woman_in_motorized_wheelchair_tone3:":{uc_base:"1f469-1f3fd-1f9bc",uc_full:"1f469-1f3fd-200d-1f9bc",shortnames:[":woman_in_motorized_wheelchair_medium_skin_tone:"],category:"people"},":woman_in_motorized_wheelchair_tone4:":{uc_base:"1f469-1f3fe-1f9bc",uc_full:"1f469-1f3fe-200d-1f9bc",shortnames:[":woman_in_motorized_wheelchair_medium_dark_skin_tone:"],category:"people"},":woman_in_motorized_wheelchair_tone5:":{uc_base:"1f469-1f3ff-1f9bc",uc_full:"1f469-1f3ff-200d-1f9bc",shortnames:[":woman_in_motorized_wheelchair_dark_skin_tone:"],category:"people"},":woman_mechanic_tone1:":{uc_base:"1f469-1f3fb-1f527",uc_full:"1f469-1f3fb-200d-1f527",shortnames:[":woman_mechanic_light_skin_tone:"],category:"people"},":woman_mechanic_tone2:":{uc_base:"1f469-1f3fc-1f527",uc_full:"1f469-1f3fc-200d-1f527",shortnames:[":woman_mechanic_medium_light_skin_tone:"],category:"people"},":woman_mechanic_tone3:":{uc_base:"1f469-1f3fd-1f527",uc_full:"1f469-1f3fd-200d-1f527",shortnames:[":woman_mechanic_medium_skin_tone:"],category:"people"},":woman_mechanic_tone4:":{uc_base:"1f469-1f3fe-1f527",uc_full:"1f469-1f3fe-200d-1f527",shortnames:[":woman_mechanic_medium_dark_skin_tone:"],category:"people"},":woman_mechanic_tone5:":{uc_base:"1f469-1f3ff-1f527",uc_full:"1f469-1f3ff-200d-1f527",shortnames:[":woman_mechanic_dark_skin_tone:"],category:"people"},":woman_office_worker_tone1:":{uc_base:"1f469-1f3fb-1f4bc",uc_full:"1f469-1f3fb-200d-1f4bc",shortnames:[":woman_office_worker_light_skin_tone:"],category:"people"},":woman_office_worker_tone2:":{uc_base:"1f469-1f3fc-1f4bc",uc_full:"1f469-1f3fc-200d-1f4bc",shortnames:[":woman_office_worker_medium_light_skin_tone:"],category:"people"},":woman_office_worker_tone3:":{uc_base:"1f469-1f3fd-1f4bc",uc_full:"1f469-1f3fd-200d-1f4bc",shortnames:[":woman_office_worker_medium_skin_tone:"],category:"people"},":woman_office_worker_tone4:":{uc_base:"1f469-1f3fe-1f4bc",uc_full:"1f469-1f3fe-200d-1f4bc",shortnames:[":woman_office_worker_medium_dark_skin_tone:"],category:"people"},":woman_office_worker_tone5:":{uc_base:"1f469-1f3ff-1f4bc",uc_full:"1f469-1f3ff-200d-1f4bc",shortnames:[":woman_office_worker_dark_skin_tone:"],category:"people"},":woman_red_haired_tone1:":{uc_base:"1f469-1f3fb-1f9b0",uc_full:"1f469-1f3fb-200d-1f9b0",shortnames:[":woman_red_haired_light_skin_tone:"],category:"people"},":woman_red_haired_tone2:":{uc_base:"1f469-1f3fc-1f9b0",uc_full:"1f469-1f3fc-200d-1f9b0",shortnames:[":woman_red_haired_medium_light_skin_tone:"],category:"people"},":woman_red_haired_tone3:":{uc_base:"1f469-1f3fd-1f9b0",uc_full:"1f469-1f3fd-200d-1f9b0",shortnames:[":woman_red_haired_medium_skin_tone:"],category:"people"},":woman_red_haired_tone4:":{uc_base:"1f469-1f3fe-1f9b0",uc_full:"1f469-1f3fe-200d-1f9b0",shortnames:[":woman_red_haired_medium_dark_skin_tone:"],category:"people"},":woman_red_haired_tone5:":{uc_base:"1f469-1f3ff-1f9b0",uc_full:"1f469-1f3ff-200d-1f9b0",shortnames:[":woman_red_haired_dark_skin_tone:"],category:"people"},":woman_scientist_tone1:":{uc_base:"1f469-1f3fb-1f52c",uc_full:"1f469-1f3fb-200d-1f52c",shortnames:[":woman_scientist_light_skin_tone:"],category:"people"},":woman_scientist_tone2:":{uc_base:"1f469-1f3fc-1f52c",uc_full:"1f469-1f3fc-200d-1f52c",shortnames:[":woman_scientist_medium_light_skin_tone:"],category:"people"},":woman_scientist_tone3:":{uc_base:"1f469-1f3fd-1f52c",uc_full:"1f469-1f3fd-200d-1f52c",shortnames:[":woman_scientist_medium_skin_tone:"],category:"people"},":woman_scientist_tone4:":{uc_base:"1f469-1f3fe-1f52c",uc_full:"1f469-1f3fe-200d-1f52c",shortnames:[":woman_scientist_medium_dark_skin_tone:"],category:"people"},":woman_scientist_tone5:":{uc_base:"1f469-1f3ff-1f52c",uc_full:"1f469-1f3ff-200d-1f52c",shortnames:[":woman_scientist_dark_skin_tone:"],category:"people"},":woman_singer_tone1:":{uc_base:"1f469-1f3fb-1f3a4",uc_full:"1f469-1f3fb-200d-1f3a4",shortnames:[":woman_singer_light_skin_tone:"],category:"people"},":woman_singer_tone2:":{uc_base:"1f469-1f3fc-1f3a4",uc_full:"1f469-1f3fc-200d-1f3a4",shortnames:[":woman_singer_medium_light_skin_tone:"],category:"people"},":woman_singer_tone3:":{uc_base:"1f469-1f3fd-1f3a4",uc_full:"1f469-1f3fd-200d-1f3a4",shortnames:[":woman_singer_medium_skin_tone:"],category:"people"},":woman_singer_tone4:":{uc_base:"1f469-1f3fe-1f3a4",uc_full:"1f469-1f3fe-200d-1f3a4",shortnames:[":woman_singer_medium_dark_skin_tone:"],category:"people"},":woman_singer_tone5:":{uc_base:"1f469-1f3ff-1f3a4",uc_full:"1f469-1f3ff-200d-1f3a4",shortnames:[":woman_singer_dark_skin_tone:"],category:"people"},":woman_student_tone1:":{uc_base:"1f469-1f3fb-1f393",uc_full:"1f469-1f3fb-200d-1f393",shortnames:[":woman_student_light_skin_tone:"],category:"people"},":woman_student_tone2:":{uc_base:"1f469-1f3fc-1f393",uc_full:"1f469-1f3fc-200d-1f393",shortnames:[":woman_student_medium_light_skin_tone:"],category:"people"},":woman_student_tone3:":{uc_base:"1f469-1f3fd-1f393",uc_full:"1f469-1f3fd-200d-1f393",shortnames:[":woman_student_medium_skin_tone:"],category:"people"},":woman_student_tone4:":{uc_base:"1f469-1f3fe-1f393",uc_full:"1f469-1f3fe-200d-1f393",shortnames:[":woman_student_medium_dark_skin_tone:"],category:"people"},":woman_student_tone5:":{uc_base:"1f469-1f3ff-1f393",uc_full:"1f469-1f3ff-200d-1f393",shortnames:[":woman_student_dark_skin_tone:"],category:"people"},":woman_teacher_tone1:":{uc_base:"1f469-1f3fb-1f3eb",uc_full:"1f469-1f3fb-200d-1f3eb",shortnames:[":woman_teacher_light_skin_tone:"],category:"people"},":woman_teacher_tone2:":{uc_base:"1f469-1f3fc-1f3eb",uc_full:"1f469-1f3fc-200d-1f3eb",shortnames:[":woman_teacher_medium_light_skin_tone:"],category:"people"},":woman_teacher_tone3:":{uc_base:"1f469-1f3fd-1f3eb",uc_full:"1f469-1f3fd-200d-1f3eb",shortnames:[":woman_teacher_medium_skin_tone:"],category:"people"},":woman_teacher_tone4:":{uc_base:"1f469-1f3fe-1f3eb",uc_full:"1f469-1f3fe-200d-1f3eb",shortnames:[":woman_teacher_medium_dark_skin_tone:"],category:"people"},":woman_teacher_tone5:":{uc_base:"1f469-1f3ff-1f3eb",uc_full:"1f469-1f3ff-200d-1f3eb",shortnames:[":woman_teacher_dark_skin_tone:"],category:"people"},":woman_technologist_tone1:":{uc_base:"1f469-1f3fb-1f4bb",uc_full:"1f469-1f3fb-200d-1f4bb",shortnames:[":woman_technologist_light_skin_tone:"],category:"people"},":woman_technologist_tone2:":{uc_base:"1f469-1f3fc-1f4bb",uc_full:"1f469-1f3fc-200d-1f4bb",shortnames:[":woman_technologist_medium_light_skin_tone:"],category:"people"},":woman_technologist_tone3:":{uc_base:"1f469-1f3fd-1f4bb",uc_full:"1f469-1f3fd-200d-1f4bb",shortnames:[":woman_technologist_medium_skin_tone:"],category:"people"},":woman_technologist_tone4:":{uc_base:"1f469-1f3fe-1f4bb",uc_full:"1f469-1f3fe-200d-1f4bb",shortnames:[":woman_technologist_medium_dark_skin_tone:"],category:"people"},":woman_technologist_tone5:":{uc_base:"1f469-1f3ff-1f4bb",uc_full:"1f469-1f3ff-200d-1f4bb",shortnames:[":woman_technologist_dark_skin_tone:"],category:"people"},":woman_white_haired_tone1:":{uc_base:"1f469-1f3fb-1f9b3",uc_full:"1f469-1f3fb-200d-1f9b3",shortnames:[":woman_white_haired_light_skin_tone:"],category:"people"},":woman_white_haired_tone2:":{uc_base:"1f469-1f3fc-1f9b3",uc_full:"1f469-1f3fc-200d-1f9b3",shortnames:[":woman_white_haired_medium_light_skin_tone:"],category:"people"},":woman_white_haired_tone3:":{uc_base:"1f469-1f3fd-1f9b3",uc_full:"1f469-1f3fd-200d-1f9b3",shortnames:[":woman_white_haired_medium_skin_tone:"],category:"people"},":woman_white_haired_tone4:":{uc_base:"1f469-1f3fe-1f9b3",uc_full:"1f469-1f3fe-200d-1f9b3",shortnames:[":woman_white_haired_medium_dark_skin_tone:"],category:"people"},":woman_white_haired_tone5:":{uc_base:"1f469-1f3ff-1f9b3",uc_full:"1f469-1f3ff-200d-1f9b3",shortnames:[":woman_white_haired_dark_skin_tone:"],category:"people"},":woman_with_probing_cane_tone1:":{uc_base:"1f469-1f3fb-1f9af",uc_full:"1f469-1f3fb-200d-1f9af",shortnames:[":woman_with_probing_cane_light_skin_tone:"],category:"people"},":woman_with_probing_cane_tone2:":{uc_base:"1f469-1f3fc-1f9af",uc_full:"1f469-1f3fc-200d-1f9af",shortnames:[":woman_with_probing_cane_medium_light_skin_tone:"],category:"people"},":woman_with_probing_cane_tone3:":{uc_base:"1f469-1f3fd-1f9af",uc_full:"1f469-1f3fd-200d-1f9af",shortnames:[":woman_with_probing_cane_medium_skin_tone:"],category:"people"},":woman_with_probing_cane_tone4:":{uc_base:"1f469-1f3fe-1f9af",uc_full:"1f469-1f3fe-200d-1f9af",shortnames:[":woman_with_probing_cane_medium_dark_skin_tone:"],category:"people"},":woman_with_probing_cane_tone5:":{uc_base:"1f469-1f3ff-1f9af",uc_full:"1f469-1f3ff-200d-1f9af",shortnames:[":woman_with_probing_cane_dark_skin_tone:"],category:"people"},":blond-haired_man_tone1:":{uc_base:"1f471-1f3fb-2642",uc_full:"1f471-1f3fb-200d-2642-fe0f",shortnames:[":blond-haired_man_light_skin_tone:"],category:"people"},":blond-haired_man_tone2:":{uc_base:"1f471-1f3fc-2642",uc_full:"1f471-1f3fc-200d-2642-fe0f",shortnames:[":blond-haired_man_medium_light_skin_tone:"],category:"people"},":blond-haired_man_tone3:":{uc_base:"1f471-1f3fd-2642",uc_full:"1f471-1f3fd-200d-2642-fe0f",shortnames:[":blond-haired_man_medium_skin_tone:"],category:"people"},":blond-haired_man_tone4:":{uc_base:"1f471-1f3fe-2642",uc_full:"1f471-1f3fe-200d-2642-fe0f",shortnames:[":blond-haired_man_medium_dark_skin_tone:"],category:"people"},":blond-haired_man_tone5:":{uc_base:"1f471-1f3ff-2642",uc_full:"1f471-1f3ff-200d-2642-fe0f",shortnames:[":blond-haired_man_dark_skin_tone:"],category:"people"},":blond-haired_woman_tone1:":{uc_base:"1f471-1f3fb-2640",uc_full:"1f471-1f3fb-200d-2640-fe0f",shortnames:[":blond-haired_woman_light_skin_tone:"],category:"people"},":blond-haired_woman_tone2:":{uc_base:"1f471-1f3fc-2640",uc_full:"1f471-1f3fc-200d-2640-fe0f",shortnames:[":blond-haired_woman_medium_light_skin_tone:"],category:"people"},":blond-haired_woman_tone3:":{uc_base:"1f471-1f3fd-2640",uc_full:"1f471-1f3fd-200d-2640-fe0f",shortnames:[":blond-haired_woman_medium_skin_tone:"],category:"people"},":blond-haired_woman_tone4:":{uc_base:"1f471-1f3fe-2640",uc_full:"1f471-1f3fe-200d-2640-fe0f",shortnames:[":blond-haired_woman_medium_dark_skin_tone:"],category:"people"},":blond-haired_woman_tone5:":{uc_base:"1f471-1f3ff-2640",uc_full:"1f471-1f3ff-200d-2640-fe0f",shortnames:[":blond-haired_woman_dark_skin_tone:"],category:"people"},":couple_mm:":{uc_base:"1f468-2764-1f468",uc_full:"1f468-200d-2764-fe0f-200d-1f468",shortnames:[":couple_with_heart_mm:"],category:"people"},":couple_with_heart_woman_man:":{uc_base:"1f469-2764-1f468",uc_full:"1f469-200d-2764-fe0f-200d-1f468",shortnames:[],category:"people"},":couple_ww:":{uc_base:"1f469-2764-1f469",uc_full:"1f469-200d-2764-fe0f-200d-1f469",shortnames:[":couple_with_heart_ww:"],category:"people"},":deaf_man_tone1:":{uc_base:"1f9cf-1f3fb-2642",uc_full:"1f9cf-1f3fb-200d-2642-fe0f",shortnames:[":deaf_man_light_skin_tone:"],category:"people"},":deaf_man_tone2:":{uc_base:"1f9cf-1f3fc-2642",uc_full:"1f9cf-1f3fc-200d-2642-fe0f",shortnames:[":deaf_man_medium_light_skin_tone:"],category:"people"},":deaf_man_tone3:":{uc_base:"1f9cf-1f3fd-2642",uc_full:"1f9cf-1f3fd-200d-2642-fe0f",shortnames:[":deaf_man_medium_skin_tone:"],category:"people"},":deaf_man_tone4:":{uc_base:"1f9cf-1f3fe-2642",uc_full:"1f9cf-1f3fe-200d-2642-fe0f",shortnames:[":deaf_man_medium_dark_skin_tone:"],category:"people"},":deaf_man_tone5:":{uc_base:"1f9cf-1f3ff-2642",uc_full:"1f9cf-1f3ff-200d-2642-fe0f",shortnames:[":deaf_man_dark_skin_tone:"],category:"people"},":deaf_woman_tone1:":{uc_base:"1f9cf-1f3fb-2640",uc_full:"1f9cf-1f3fb-200d-2640-fe0f",shortnames:[":deaf_woman_light_skin_tone:"],category:"people"},":deaf_woman_tone2:":{uc_base:"1f9cf-1f3fc-2640",uc_full:"1f9cf-1f3fc-200d-2640-fe0f",shortnames:[":deaf_woman_medium_light_skin_tone:"],category:"people"},":deaf_woman_tone3:":{uc_base:"1f9cf-1f3fd-2640",uc_full:"1f9cf-1f3fd-200d-2640-fe0f",shortnames:[":deaf_woman_medium_skin_tone:"],category:"people"},":deaf_woman_tone4:":{uc_base:"1f9cf-1f3fe-2640",uc_full:"1f9cf-1f3fe-200d-2640-fe0f",shortnames:[":deaf_woman_medium_dark_skin_tone:"],category:"people"},":deaf_woman_tone5:":{uc_base:"1f9cf-1f3ff-2640",uc_full:"1f9cf-1f3ff-200d-2640-fe0f",shortnames:[":deaf_woman_dark_skin_tone:"],category:"people"},":health_worker_tone1:":{uc_base:"1f9d1-1f3fb-2695",uc_full:"1f9d1-1f3fb-200d-2695-fe0f",shortnames:[":health_worker_light_skin_tone:"],category:"people"},":health_worker_tone2:":{uc_base:"1f9d1-1f3fc-2695",uc_full:"1f9d1-1f3fc-200d-2695-fe0f",shortnames:[":health_worker_medium_light_skin_tone:"],category:"people"},":health_worker_tone3:":{uc_base:"1f9d1-1f3fd-2695",uc_full:"1f9d1-1f3fd-200d-2695-fe0f",shortnames:[":health_worker_medium_skin_tone:"],category:"people"},":health_worker_tone4:":{uc_base:"1f9d1-1f3fe-2695",uc_full:"1f9d1-1f3fe-200d-2695-fe0f",shortnames:[":health_worker_medium_dark_skin_tone:"],category:"people"},":health_worker_tone5:":{uc_base:"1f9d1-1f3ff-2695",uc_full:"1f9d1-1f3ff-200d-2695-fe0f",shortnames:[":health_worker_dark_skin_tone:"],category:"people"},":judge_tone1:":{uc_base:"1f9d1-1f3fb-2696",uc_full:"1f9d1-1f3fb-200d-2696-fe0f",shortnames:[":judge_light_skin_tone:"],category:"people"},":judge_tone2:":{uc_base:"1f9d1-1f3fc-2696",uc_full:"1f9d1-1f3fc-200d-2696-fe0f",shortnames:[":judge_medium_light_skin_tone:"],category:"people"},":judge_tone3:":{uc_base:"1f9d1-1f3fd-2696",uc_full:"1f9d1-1f3fd-200d-2696-fe0f",shortnames:[":judge_medium_skin_tone:"],category:"people"},":judge_tone4:":{uc_base:"1f9d1-1f3fe-2696",uc_full:"1f9d1-1f3fe-200d-2696-fe0f",shortnames:[":judge_medium_dark_skin_tone:"],category:"people"},":judge_tone5:":{uc_base:"1f9d1-1f3ff-2696",uc_full:"1f9d1-1f3ff-200d-2696-fe0f",shortnames:[":judge_dark_skin_tone:"],category:"people"},":man_biking_tone1:":{uc_base:"1f6b4-1f3fb-2642",uc_full:"1f6b4-1f3fb-200d-2642-fe0f",shortnames:[":man_biking_light_skin_tone:"],category:"activity"},":man_biking_tone2:":{uc_base:"1f6b4-1f3fc-2642",uc_full:"1f6b4-1f3fc-200d-2642-fe0f",shortnames:[":man_biking_medium_light_skin_tone:"],category:"activity"},":man_biking_tone3:":{uc_base:"1f6b4-1f3fd-2642",uc_full:"1f6b4-1f3fd-200d-2642-fe0f",shortnames:[":man_biking_medium_skin_tone:"],category:"activity"},":man_biking_tone4:":{uc_base:"1f6b4-1f3fe-2642",uc_full:"1f6b4-1f3fe-200d-2642-fe0f",shortnames:[":man_biking_medium_dark_skin_tone:"],category:"activity"},":man_biking_tone5:":{uc_base:"1f6b4-1f3ff-2642",uc_full:"1f6b4-1f3ff-200d-2642-fe0f",shortnames:[":man_biking_dark_skin_tone:"],category:"activity"},":man_bowing_tone1:":{uc_base:"1f647-1f3fb-2642",uc_full:"1f647-1f3fb-200d-2642-fe0f",shortnames:[":man_bowing_light_skin_tone:"],category:"people"},":man_bowing_tone2:":{uc_base:"1f647-1f3fc-2642",uc_full:"1f647-1f3fc-200d-2642-fe0f",shortnames:[":man_bowing_medium_light_skin_tone:"],category:"people"},":man_bowing_tone3:":{uc_base:"1f647-1f3fd-2642",uc_full:"1f647-1f3fd-200d-2642-fe0f",shortnames:[":man_bowing_medium_skin_tone:"],category:"people"},":man_bowing_tone4:":{uc_base:"1f647-1f3fe-2642",uc_full:"1f647-1f3fe-200d-2642-fe0f",shortnames:[":man_bowing_medium_dark_skin_tone:"],category:"people"},":man_bowing_tone5:":{uc_base:"1f647-1f3ff-2642",uc_full:"1f647-1f3ff-200d-2642-fe0f",shortnames:[":man_bowing_dark_skin_tone:"],category:"people"},":man_cartwheeling_tone1:":{uc_base:"1f938-1f3fb-2642",uc_full:"1f938-1f3fb-200d-2642-fe0f",shortnames:[":man_cartwheeling_light_skin_tone:"],category:"activity"},":man_cartwheeling_tone2:":{uc_base:"1f938-1f3fc-2642",uc_full:"1f938-1f3fc-200d-2642-fe0f",shortnames:[":man_cartwheeling_medium_light_skin_tone:"],category:"activity"},":man_cartwheeling_tone3:":{uc_base:"1f938-1f3fd-2642",uc_full:"1f938-1f3fd-200d-2642-fe0f",shortnames:[":man_cartwheeling_medium_skin_tone:"],category:"activity"},":man_cartwheeling_tone4:":{uc_base:"1f938-1f3fe-2642",uc_full:"1f938-1f3fe-200d-2642-fe0f",shortnames:[":man_cartwheeling_medium_dark_skin_tone:"],category:"activity"},":man_cartwheeling_tone5:":{uc_base:"1f938-1f3ff-2642",uc_full:"1f938-1f3ff-200d-2642-fe0f",shortnames:[":man_cartwheeling_dark_skin_tone:"],category:"activity"},":man_climbing_tone1:":{uc_base:"1f9d7-1f3fb-2642",uc_full:"1f9d7-1f3fb-200d-2642-fe0f",shortnames:[":man_climbing_light_skin_tone:"],category:"activity"},":man_climbing_tone2:":{uc_base:"1f9d7-1f3fc-2642",uc_full:"1f9d7-1f3fc-200d-2642-fe0f",shortnames:[":man_climbing_medium_light_skin_tone:"],category:"activity"},":man_climbing_tone3:":{uc_base:"1f9d7-1f3fd-2642",uc_full:"1f9d7-1f3fd-200d-2642-fe0f",shortnames:[":man_climbing_medium_skin_tone:"],category:"activity"},":man_climbing_tone4:":{uc_base:"1f9d7-1f3fe-2642",uc_full:"1f9d7-1f3fe-200d-2642-fe0f",shortnames:[":man_climbing_medium_dark_skin_tone:"],category:"activity"},":man_climbing_tone5:":{uc_base:"1f9d7-1f3ff-2642",uc_full:"1f9d7-1f3ff-200d-2642-fe0f",shortnames:[":man_climbing_dark_skin_tone:"],category:"activity"},":man_construction_worker_tone1:":{uc_base:"1f477-1f3fb-2642",uc_full:"1f477-1f3fb-200d-2642-fe0f",shortnames:[":man_construction_worker_light_skin_tone:"],category:"people"},":man_construction_worker_tone2:":{uc_base:"1f477-1f3fc-2642",uc_full:"1f477-1f3fc-200d-2642-fe0f",shortnames:[":man_construction_worker_medium_light_skin_tone:"],category:"people"},":man_construction_worker_tone3:":{uc_base:"1f477-1f3fd-2642",uc_full:"1f477-1f3fd-200d-2642-fe0f",shortnames:[":man_construction_worker_medium_skin_tone:"],category:"people"},":man_construction_worker_tone4:":{uc_base:"1f477-1f3fe-2642",uc_full:"1f477-1f3fe-200d-2642-fe0f",shortnames:[":man_construction_worker_medium_dark_skin_tone:"],category:"people"},":man_construction_worker_tone5:":{uc_base:"1f477-1f3ff-2642",uc_full:"1f477-1f3ff-200d-2642-fe0f",shortnames:[":man_construction_worker_dark_skin_tone:"],category:"people"},":man_detective_tone1:":{uc_base:"1f575-1f3fb-2642",uc_full:"1f575-1f3fb-200d-2642-fe0f",shortnames:[":man_detective_light_skin_tone:"],category:"people"},":man_detective_tone2:":{uc_base:"1f575-1f3fc-2642",uc_full:"1f575-1f3fc-200d-2642-fe0f",shortnames:[":man_detective_medium_light_skin_tone:"],category:"people"},":man_detective_tone3:":{uc_base:"1f575-1f3fd-2642",uc_full:"1f575-1f3fd-200d-2642-fe0f",shortnames:[":man_detective_medium_skin_tone:"],category:"people"},":man_detective_tone4:":{uc_base:"1f575-1f3fe-2642",uc_full:"1f575-1f3fe-200d-2642-fe0f",shortnames:[":man_detective_medium_dark_skin_tone:"],category:"people"},":man_detective_tone5:":{uc_base:"1f575-1f3ff-2642",uc_full:"1f575-1f3ff-200d-2642-fe0f",shortnames:[":man_detective_dark_skin_tone:"],category:"people"},":man_elf_tone1:":{uc_base:"1f9dd-1f3fb-2642",uc_full:"1f9dd-1f3fb-200d-2642-fe0f",shortnames:[":man_elf_light_skin_tone:"],category:"people"},":man_elf_tone2:":{uc_base:"1f9dd-1f3fc-2642",uc_full:"1f9dd-1f3fc-200d-2642-fe0f",shortnames:[":man_elf_medium_light_skin_tone:"],category:"people"},":man_elf_tone3:":{uc_base:"1f9dd-1f3fd-2642",uc_full:"1f9dd-1f3fd-200d-2642-fe0f",shortnames:[":man_elf_medium_skin_tone:"],category:"people"},":man_elf_tone4:":{uc_base:"1f9dd-1f3fe-2642",uc_full:"1f9dd-1f3fe-200d-2642-fe0f",shortnames:[":man_elf_medium_dark_skin_tone:"],category:"people"},":man_elf_tone5:":{uc_base:"1f9dd-1f3ff-2642",uc_full:"1f9dd-1f3ff-200d-2642-fe0f",shortnames:[":man_elf_dark_skin_tone:"],category:"people"},":man_facepalming_tone1:":{uc_base:"1f926-1f3fb-2642",uc_full:"1f926-1f3fb-200d-2642-fe0f",shortnames:[":man_facepalming_light_skin_tone:"],category:"people"},":man_facepalming_tone2:":{uc_base:"1f926-1f3fc-2642",uc_full:"1f926-1f3fc-200d-2642-fe0f", -shortnames:[":man_facepalming_medium_light_skin_tone:"],category:"people"},":man_facepalming_tone3:":{uc_base:"1f926-1f3fd-2642",uc_full:"1f926-1f3fd-200d-2642-fe0f",shortnames:[":man_facepalming_medium_skin_tone:"],category:"people"},":man_facepalming_tone4:":{uc_base:"1f926-1f3fe-2642",uc_full:"1f926-1f3fe-200d-2642-fe0f",shortnames:[":man_facepalming_medium_dark_skin_tone:"],category:"people"},":man_facepalming_tone5:":{uc_base:"1f926-1f3ff-2642",uc_full:"1f926-1f3ff-200d-2642-fe0f",shortnames:[":man_facepalming_dark_skin_tone:"],category:"people"},":man_fairy_tone1:":{uc_base:"1f9da-1f3fb-2642",uc_full:"1f9da-1f3fb-200d-2642-fe0f",shortnames:[":man_fairy_light_skin_tone:"],category:"people"},":man_fairy_tone2:":{uc_base:"1f9da-1f3fc-2642",uc_full:"1f9da-1f3fc-200d-2642-fe0f",shortnames:[":man_fairy_medium_light_skin_tone:"],category:"people"},":man_fairy_tone3:":{uc_base:"1f9da-1f3fd-2642",uc_full:"1f9da-1f3fd-200d-2642-fe0f",shortnames:[":man_fairy_medium_skin_tone:"],category:"people"},":man_fairy_tone4:":{uc_base:"1f9da-1f3fe-2642",uc_full:"1f9da-1f3fe-200d-2642-fe0f",shortnames:[":man_fairy_medium_dark_skin_tone:"],category:"people"},":man_fairy_tone5:":{uc_base:"1f9da-1f3ff-2642",uc_full:"1f9da-1f3ff-200d-2642-fe0f",shortnames:[":man_fairy_dark_skin_tone:"],category:"people"},":man_frowning_tone1:":{uc_base:"1f64d-1f3fb-2642",uc_full:"1f64d-1f3fb-200d-2642-fe0f",shortnames:[":man_frowning_light_skin_tone:"],category:"people"},":man_frowning_tone2:":{uc_base:"1f64d-1f3fc-2642",uc_full:"1f64d-1f3fc-200d-2642-fe0f",shortnames:[":man_frowning_medium_light_skin_tone:"],category:"people"},":man_frowning_tone3:":{uc_base:"1f64d-1f3fd-2642",uc_full:"1f64d-1f3fd-200d-2642-fe0f",shortnames:[":man_frowning_medium_skin_tone:"],category:"people"},":man_frowning_tone4:":{uc_base:"1f64d-1f3fe-2642",uc_full:"1f64d-1f3fe-200d-2642-fe0f",shortnames:[":man_frowning_medium_dark_skin_tone:"],category:"people"},":man_frowning_tone5:":{uc_base:"1f64d-1f3ff-2642",uc_full:"1f64d-1f3ff-200d-2642-fe0f",shortnames:[":man_frowning_dark_skin_tone:"],category:"people"},":man_gesturing_no_tone1:":{uc_base:"1f645-1f3fb-2642",uc_full:"1f645-1f3fb-200d-2642-fe0f",shortnames:[":man_gesturing_no_light_skin_tone:"],category:"people"},":man_gesturing_no_tone2:":{uc_base:"1f645-1f3fc-2642",uc_full:"1f645-1f3fc-200d-2642-fe0f",shortnames:[":man_gesturing_no_medium_light_skin_tone:"],category:"people"},":man_gesturing_no_tone3:":{uc_base:"1f645-1f3fd-2642",uc_full:"1f645-1f3fd-200d-2642-fe0f",shortnames:[":man_gesturing_no_medium_skin_tone:"],category:"people"},":man_gesturing_no_tone4:":{uc_base:"1f645-1f3fe-2642",uc_full:"1f645-1f3fe-200d-2642-fe0f",shortnames:[":man_gesturing_no_medium_dark_skin_tone:"],category:"people"},":man_gesturing_no_tone5:":{uc_base:"1f645-1f3ff-2642",uc_full:"1f645-1f3ff-200d-2642-fe0f",shortnames:[":man_gesturing_no_dark_skin_tone:"],category:"people"},":man_gesturing_ok_tone1:":{uc_base:"1f646-1f3fb-2642",uc_full:"1f646-1f3fb-200d-2642-fe0f",shortnames:[":man_gesturing_ok_light_skin_tone:"],category:"people"},":man_gesturing_ok_tone2:":{uc_base:"1f646-1f3fc-2642",uc_full:"1f646-1f3fc-200d-2642-fe0f",shortnames:[":man_gesturing_ok_medium_light_skin_tone:"],category:"people"},":man_gesturing_ok_tone3:":{uc_base:"1f646-1f3fd-2642",uc_full:"1f646-1f3fd-200d-2642-fe0f",shortnames:[":man_gesturing_ok_medium_skin_tone:"],category:"people"},":man_gesturing_ok_tone4:":{uc_base:"1f646-1f3fe-2642",uc_full:"1f646-1f3fe-200d-2642-fe0f",shortnames:[":man_gesturing_ok_medium_dark_skin_tone:"],category:"people"},":man_gesturing_ok_tone5:":{uc_base:"1f646-1f3ff-2642",uc_full:"1f646-1f3ff-200d-2642-fe0f",shortnames:[":man_gesturing_ok_dark_skin_tone:"],category:"people"},":man_getting_face_massage_tone1:":{uc_base:"1f486-1f3fb-2642",uc_full:"1f486-1f3fb-200d-2642-fe0f",shortnames:[":man_getting_face_massage_light_skin_tone:"],category:"people"},":man_getting_face_massage_tone2:":{uc_base:"1f486-1f3fc-2642",uc_full:"1f486-1f3fc-200d-2642-fe0f",shortnames:[":man_getting_face_massage_medium_light_skin_tone:"],category:"people"},":man_getting_face_massage_tone3:":{uc_base:"1f486-1f3fd-2642",uc_full:"1f486-1f3fd-200d-2642-fe0f",shortnames:[":man_getting_face_massage_medium_skin_tone:"],category:"people"},":man_getting_face_massage_tone4:":{uc_base:"1f486-1f3fe-2642",uc_full:"1f486-1f3fe-200d-2642-fe0f",shortnames:[":man_getting_face_massage_medium_dark_skin_tone:"],category:"people"},":man_getting_face_massage_tone5:":{uc_base:"1f486-1f3ff-2642",uc_full:"1f486-1f3ff-200d-2642-fe0f",shortnames:[":man_getting_face_massage_dark_skin_tone:"],category:"people"},":man_getting_haircut_tone1:":{uc_base:"1f487-1f3fb-2642",uc_full:"1f487-1f3fb-200d-2642-fe0f",shortnames:[":man_getting_haircut_light_skin_tone:"],category:"people"},":man_getting_haircut_tone2:":{uc_base:"1f487-1f3fc-2642",uc_full:"1f487-1f3fc-200d-2642-fe0f",shortnames:[":man_getting_haircut_medium_light_skin_tone:"],category:"people"},":man_getting_haircut_tone3:":{uc_base:"1f487-1f3fd-2642",uc_full:"1f487-1f3fd-200d-2642-fe0f",shortnames:[":man_getting_haircut_medium_skin_tone:"],category:"people"},":man_getting_haircut_tone4:":{uc_base:"1f487-1f3fe-2642",uc_full:"1f487-1f3fe-200d-2642-fe0f",shortnames:[":man_getting_haircut_medium_dark_skin_tone:"],category:"people"},":man_getting_haircut_tone5:":{uc_base:"1f487-1f3ff-2642",uc_full:"1f487-1f3ff-200d-2642-fe0f",shortnames:[":man_getting_haircut_dark_skin_tone:"],category:"people"},":man_golfing_tone1:":{uc_base:"1f3cc-1f3fb-2642",uc_full:"1f3cc-1f3fb-200d-2642-fe0f",shortnames:[":man_golfing_light_skin_tone:"],category:"activity"},":man_golfing_tone2:":{uc_base:"1f3cc-1f3fc-2642",uc_full:"1f3cc-1f3fc-200d-2642-fe0f",shortnames:[":man_golfing_medium_light_skin_tone:"],category:"activity"},":man_golfing_tone3:":{uc_base:"1f3cc-1f3fd-2642",uc_full:"1f3cc-1f3fd-200d-2642-fe0f",shortnames:[":man_golfing_medium_skin_tone:"],category:"activity"},":man_golfing_tone4:":{uc_base:"1f3cc-1f3fe-2642",uc_full:"1f3cc-1f3fe-200d-2642-fe0f",shortnames:[":man_golfing_medium_dark_skin_tone:"],category:"activity"},":man_golfing_tone5:":{uc_base:"1f3cc-1f3ff-2642",uc_full:"1f3cc-1f3ff-200d-2642-fe0f",shortnames:[":man_golfing_dark_skin_tone:"],category:"activity"},":man_guard_tone1:":{uc_base:"1f482-1f3fb-2642",uc_full:"1f482-1f3fb-200d-2642-fe0f",shortnames:[":man_guard_light_skin_tone:"],category:"people"},":man_guard_tone2:":{uc_base:"1f482-1f3fc-2642",uc_full:"1f482-1f3fc-200d-2642-fe0f",shortnames:[":man_guard_medium_light_skin_tone:"],category:"people"},":man_guard_tone3:":{uc_base:"1f482-1f3fd-2642",uc_full:"1f482-1f3fd-200d-2642-fe0f",shortnames:[":man_guard_medium_skin_tone:"],category:"people"},":man_guard_tone4:":{uc_base:"1f482-1f3fe-2642",uc_full:"1f482-1f3fe-200d-2642-fe0f",shortnames:[":man_guard_medium_dark_skin_tone:"],category:"people"},":man_guard_tone5:":{uc_base:"1f482-1f3ff-2642",uc_full:"1f482-1f3ff-200d-2642-fe0f",shortnames:[":man_guard_dark_skin_tone:"],category:"people"},":man_health_worker_tone1:":{uc_base:"1f468-1f3fb-2695",uc_full:"1f468-1f3fb-200d-2695-fe0f",shortnames:[":man_health_worker_light_skin_tone:"],category:"people"},":man_health_worker_tone2:":{uc_base:"1f468-1f3fc-2695",uc_full:"1f468-1f3fc-200d-2695-fe0f",shortnames:[":man_health_worker_medium_light_skin_tone:"],category:"people"},":man_health_worker_tone3:":{uc_base:"1f468-1f3fd-2695",uc_full:"1f468-1f3fd-200d-2695-fe0f",shortnames:[":man_health_worker_medium_skin_tone:"],category:"people"},":man_health_worker_tone4:":{uc_base:"1f468-1f3fe-2695",uc_full:"1f468-1f3fe-200d-2695-fe0f",shortnames:[":man_health_worker_medium_dark_skin_tone:"],category:"people"},":man_health_worker_tone5:":{uc_base:"1f468-1f3ff-2695",uc_full:"1f468-1f3ff-200d-2695-fe0f",shortnames:[":man_health_worker_dark_skin_tone:"],category:"people"},":man_in_lotus_position_tone1:":{uc_base:"1f9d8-1f3fb-2642",uc_full:"1f9d8-1f3fb-200d-2642-fe0f",shortnames:[":man_in_lotus_position_light_skin_tone:"],category:"activity"},":man_in_lotus_position_tone2:":{uc_base:"1f9d8-1f3fc-2642",uc_full:"1f9d8-1f3fc-200d-2642-fe0f",shortnames:[":man_in_lotus_position_medium_light_skin_tone:"],category:"activity"},":man_in_lotus_position_tone3:":{uc_base:"1f9d8-1f3fd-2642",uc_full:"1f9d8-1f3fd-200d-2642-fe0f",shortnames:[":man_in_lotus_position_medium_skin_tone:"],category:"activity"},":man_in_lotus_position_tone4:":{uc_base:"1f9d8-1f3fe-2642",uc_full:"1f9d8-1f3fe-200d-2642-fe0f",shortnames:[":man_in_lotus_position_medium_dark_skin_tone:"],category:"activity"},":man_in_lotus_position_tone5:":{uc_base:"1f9d8-1f3ff-2642",uc_full:"1f9d8-1f3ff-200d-2642-fe0f",shortnames:[":man_in_lotus_position_dark_skin_tone:"],category:"activity"},":man_in_steamy_room_tone1:":{uc_base:"1f9d6-1f3fb-2642",uc_full:"1f9d6-1f3fb-200d-2642-fe0f",shortnames:[":man_in_steamy_room_light_skin_tone:"],category:"people"},":man_in_steamy_room_tone2:":{uc_base:"1f9d6-1f3fc-2642",uc_full:"1f9d6-1f3fc-200d-2642-fe0f",shortnames:[":man_in_steamy_room_medium_light_skin_tone:"],category:"people"},":man_in_steamy_room_tone3:":{uc_base:"1f9d6-1f3fd-2642",uc_full:"1f9d6-1f3fd-200d-2642-fe0f",shortnames:[":man_in_steamy_room_medium_skin_tone:"],category:"people"},":man_in_steamy_room_tone4:":{uc_base:"1f9d6-1f3fe-2642",uc_full:"1f9d6-1f3fe-200d-2642-fe0f",shortnames:[":man_in_steamy_room_medium_dark_skin_tone:"],category:"people"},":man_in_steamy_room_tone5:":{uc_base:"1f9d6-1f3ff-2642",uc_full:"1f9d6-1f3ff-200d-2642-fe0f",shortnames:[":man_in_steamy_room_dark_skin_tone:"],category:"people"},":man_in_tuxedo_tone1:":{uc_base:"1f935-1f3fb-2642",uc_full:"1f935-1f3fb-200d-2642-fe0f",shortnames:[":man_in_tuxedo_light_skin_tone:"],category:"people"},":man_in_tuxedo_tone2:":{uc_base:"1f935-1f3fc-2642",uc_full:"1f935-1f3fc-200d-2642-fe0f",shortnames:[":man_in_tuxedo_medium_light_skin_tone:"],category:"people"},":man_in_tuxedo_tone3:":{uc_base:"1f935-1f3fd-2642",uc_full:"1f935-1f3fd-200d-2642-fe0f",shortnames:[":man_in_tuxedo_medium_skin_tone:"],category:"people"},":man_in_tuxedo_tone4:":{uc_base:"1f935-1f3fe-2642",uc_full:"1f935-1f3fe-200d-2642-fe0f",shortnames:[":man_in_tuxedo_medium_dark_skin_tone:"],category:"people"},":man_in_tuxedo_tone5:":{uc_base:"1f935-1f3ff-2642",uc_full:"1f935-1f3ff-200d-2642-fe0f",shortnames:[":man_in_tuxedo_dark_skin_tone:"],category:"people"},":man_judge_tone1:":{uc_base:"1f468-1f3fb-2696",uc_full:"1f468-1f3fb-200d-2696-fe0f",shortnames:[":man_judge_light_skin_tone:"],category:"people"},":man_judge_tone2:":{uc_base:"1f468-1f3fc-2696",uc_full:"1f468-1f3fc-200d-2696-fe0f",shortnames:[":man_judge_medium_light_skin_tone:"],category:"people"},":man_judge_tone3:":{uc_base:"1f468-1f3fd-2696",uc_full:"1f468-1f3fd-200d-2696-fe0f",shortnames:[":man_judge_medium_skin_tone:"],category:"people"},":man_judge_tone4:":{uc_base:"1f468-1f3fe-2696",uc_full:"1f468-1f3fe-200d-2696-fe0f",shortnames:[":man_judge_medium_dark_skin_tone:"],category:"people"},":man_judge_tone5:":{uc_base:"1f468-1f3ff-2696",uc_full:"1f468-1f3ff-200d-2696-fe0f",shortnames:[":man_judge_dark_skin_tone:"],category:"people"},":man_juggling_tone1:":{uc_base:"1f939-1f3fb-2642",uc_full:"1f939-1f3fb-200d-2642-fe0f",shortnames:[":man_juggling_light_skin_tone:"],category:"activity"},":man_juggling_tone2:":{uc_base:"1f939-1f3fc-2642",uc_full:"1f939-1f3fc-200d-2642-fe0f",shortnames:[":man_juggling_medium_light_skin_tone:"],category:"activity"},":man_juggling_tone3:":{uc_base:"1f939-1f3fd-2642",uc_full:"1f939-1f3fd-200d-2642-fe0f",shortnames:[":man_juggling_medium_skin_tone:"],category:"activity"},":man_juggling_tone4:":{uc_base:"1f939-1f3fe-2642",uc_full:"1f939-1f3fe-200d-2642-fe0f",shortnames:[":man_juggling_medium_dark_skin_tone:"],category:"activity"},":man_juggling_tone5:":{uc_base:"1f939-1f3ff-2642",uc_full:"1f939-1f3ff-200d-2642-fe0f",shortnames:[":man_juggling_dark_skin_tone:"],category:"activity"},":man_kneeling_tone1:":{uc_base:"1f9ce-1f3fb-2642",uc_full:"1f9ce-1f3fb-200d-2642-fe0f",shortnames:[":man_kneeling_light_skin_tone:"],category:"people"},":man_kneeling_tone2:":{uc_base:"1f9ce-1f3fc-2642",uc_full:"1f9ce-1f3fc-200d-2642-fe0f",shortnames:[":man_kneeling_medium_light_skin_tone:"],category:"people"},":man_kneeling_tone3:":{uc_base:"1f9ce-1f3fd-2642",uc_full:"1f9ce-1f3fd-200d-2642-fe0f",shortnames:[":man_kneeling_medium_skin_tone:"],category:"people"},":man_kneeling_tone4:":{uc_base:"1f9ce-1f3fe-2642",uc_full:"1f9ce-1f3fe-200d-2642-fe0f",shortnames:[":man_kneeling_medium_dark_skin_tone:"],category:"people"},":man_kneeling_tone5:":{uc_base:"1f9ce-1f3ff-2642",uc_full:"1f9ce-1f3ff-200d-2642-fe0f",shortnames:[":man_kneeling_dark_skin_tone:"],category:"people"},":man_lifting_weights_tone1:":{uc_base:"1f3cb-1f3fb-2642",uc_full:"1f3cb-1f3fb-200d-2642-fe0f",shortnames:[":man_lifting_weights_light_skin_tone:"],category:"activity"},":man_lifting_weights_tone2:":{uc_base:"1f3cb-1f3fc-2642",uc_full:"1f3cb-1f3fc-200d-2642-fe0f",shortnames:[":man_lifting_weights_medium_light_skin_tone:"],category:"activity"},":man_lifting_weights_tone3:":{uc_base:"1f3cb-1f3fd-2642",uc_full:"1f3cb-1f3fd-200d-2642-fe0f",shortnames:[":man_lifting_weights_medium_skin_tone:"],category:"activity"},":man_lifting_weights_tone4:":{uc_base:"1f3cb-1f3fe-2642",uc_full:"1f3cb-1f3fe-200d-2642-fe0f",shortnames:[":man_lifting_weights_medium_dark_skin_tone:"],category:"activity"},":man_lifting_weights_tone5:":{uc_base:"1f3cb-1f3ff-2642",uc_full:"1f3cb-1f3ff-200d-2642-fe0f",shortnames:[":man_lifting_weights_dark_skin_tone:"],category:"activity"},":man_mage_tone1:":{uc_base:"1f9d9-1f3fb-2642",uc_full:"1f9d9-1f3fb-200d-2642-fe0f",shortnames:[":man_mage_light_skin_tone:"],category:"people"},":man_mage_tone2:":{uc_base:"1f9d9-1f3fc-2642",uc_full:"1f9d9-1f3fc-200d-2642-fe0f",shortnames:[":man_mage_medium_light_skin_tone:"],category:"people"},":man_mage_tone3:":{uc_base:"1f9d9-1f3fd-2642",uc_full:"1f9d9-1f3fd-200d-2642-fe0f",shortnames:[":man_mage_medium_skin_tone:"],category:"people"},":man_mage_tone4:":{uc_base:"1f9d9-1f3fe-2642",uc_full:"1f9d9-1f3fe-200d-2642-fe0f",shortnames:[":man_mage_medium_dark_skin_tone:"],category:"people"},":man_mage_tone5:":{uc_base:"1f9d9-1f3ff-2642",uc_full:"1f9d9-1f3ff-200d-2642-fe0f",shortnames:[":man_mage_dark_skin_tone:"],category:"people"},":man_mountain_biking_tone1:":{uc_base:"1f6b5-1f3fb-2642",uc_full:"1f6b5-1f3fb-200d-2642-fe0f",shortnames:[":man_mountain_biking_light_skin_tone:"],category:"activity"},":man_mountain_biking_tone2:":{uc_base:"1f6b5-1f3fc-2642",uc_full:"1f6b5-1f3fc-200d-2642-fe0f",shortnames:[":man_mountain_biking_medium_light_skin_tone:"],category:"activity"},":man_mountain_biking_tone3:":{uc_base:"1f6b5-1f3fd-2642",uc_full:"1f6b5-1f3fd-200d-2642-fe0f",shortnames:[":man_mountain_biking_medium_skin_tone:"],category:"activity"},":man_mountain_biking_tone4:":{uc_base:"1f6b5-1f3fe-2642",uc_full:"1f6b5-1f3fe-200d-2642-fe0f",shortnames:[":man_mountain_biking_medium_dark_skin_tone:"],category:"activity"},":man_mountain_biking_tone5:":{uc_base:"1f6b5-1f3ff-2642",uc_full:"1f6b5-1f3ff-200d-2642-fe0f",shortnames:[":man_mountain_biking_dark_skin_tone:"],category:"activity"},":man_pilot_tone1:":{uc_base:"1f468-1f3fb-2708",uc_full:"1f468-1f3fb-200d-2708-fe0f",shortnames:[":man_pilot_light_skin_tone:"],category:"people"},":man_pilot_tone2:":{uc_base:"1f468-1f3fc-2708",uc_full:"1f468-1f3fc-200d-2708-fe0f",shortnames:[":man_pilot_medium_light_skin_tone:"],category:"people"},":man_pilot_tone3:":{uc_base:"1f468-1f3fd-2708",uc_full:"1f468-1f3fd-200d-2708-fe0f",shortnames:[":man_pilot_medium_skin_tone:"],category:"people"},":man_pilot_tone4:":{uc_base:"1f468-1f3fe-2708",uc_full:"1f468-1f3fe-200d-2708-fe0f",shortnames:[":man_pilot_medium_dark_skin_tone:"],category:"people"},":man_pilot_tone5:":{uc_base:"1f468-1f3ff-2708",uc_full:"1f468-1f3ff-200d-2708-fe0f",shortnames:[":man_pilot_dark_skin_tone:"],category:"people"},":man_playing_handball_tone1:":{uc_base:"1f93e-1f3fb-2642",uc_full:"1f93e-1f3fb-200d-2642-fe0f",shortnames:[":man_playing_handball_light_skin_tone:"],category:"activity"},":man_playing_handball_tone2:":{uc_base:"1f93e-1f3fc-2642",uc_full:"1f93e-1f3fc-200d-2642-fe0f",shortnames:[":man_playing_handball_medium_light_skin_tone:"],category:"activity"},":man_playing_handball_tone3:":{uc_base:"1f93e-1f3fd-2642",uc_full:"1f93e-1f3fd-200d-2642-fe0f",shortnames:[":man_playing_handball_medium_skin_tone:"],category:"activity"},":man_playing_handball_tone4:":{uc_base:"1f93e-1f3fe-2642",uc_full:"1f93e-1f3fe-200d-2642-fe0f",shortnames:[":man_playing_handball_medium_dark_skin_tone:"],category:"activity"},":man_playing_handball_tone5:":{uc_base:"1f93e-1f3ff-2642",uc_full:"1f93e-1f3ff-200d-2642-fe0f",shortnames:[":man_playing_handball_dark_skin_tone:"],category:"activity"},":man_playing_water_polo_tone1:":{uc_base:"1f93d-1f3fb-2642",uc_full:"1f93d-1f3fb-200d-2642-fe0f",shortnames:[":man_playing_water_polo_light_skin_tone:"],category:"activity"},":man_playing_water_polo_tone2:":{uc_base:"1f93d-1f3fc-2642",uc_full:"1f93d-1f3fc-200d-2642-fe0f",shortnames:[":man_playing_water_polo_medium_light_skin_tone:"],category:"activity"},":man_playing_water_polo_tone3:":{uc_base:"1f93d-1f3fd-2642",uc_full:"1f93d-1f3fd-200d-2642-fe0f",shortnames:[":man_playing_water_polo_medium_skin_tone:"],category:"activity"},":man_playing_water_polo_tone4:":{uc_base:"1f93d-1f3fe-2642",uc_full:"1f93d-1f3fe-200d-2642-fe0f",shortnames:[":man_playing_water_polo_medium_dark_skin_tone:"],category:"activity"},":man_playing_water_polo_tone5:":{uc_base:"1f93d-1f3ff-2642",uc_full:"1f93d-1f3ff-200d-2642-fe0f",shortnames:[":man_playing_water_polo_dark_skin_tone:"],category:"activity"},":man_police_officer_tone1:":{uc_base:"1f46e-1f3fb-2642",uc_full:"1f46e-1f3fb-200d-2642-fe0f",shortnames:[":man_police_officer_light_skin_tone:"],category:"people"},":man_police_officer_tone2:":{uc_base:"1f46e-1f3fc-2642",uc_full:"1f46e-1f3fc-200d-2642-fe0f",shortnames:[":man_police_officer_medium_light_skin_tone:"],category:"people"},":man_police_officer_tone3:":{uc_base:"1f46e-1f3fd-2642",uc_full:"1f46e-1f3fd-200d-2642-fe0f",shortnames:[":man_police_officer_medium_skin_tone:"],category:"people"},":man_police_officer_tone4:":{uc_base:"1f46e-1f3fe-2642",uc_full:"1f46e-1f3fe-200d-2642-fe0f",shortnames:[":man_police_officer_medium_dark_skin_tone:"],category:"people"},":man_police_officer_tone5:":{uc_base:"1f46e-1f3ff-2642",uc_full:"1f46e-1f3ff-200d-2642-fe0f",shortnames:[":man_police_officer_dark_skin_tone:"],category:"people"},":man_pouting_tone1:":{uc_base:"1f64e-1f3fb-2642",uc_full:"1f64e-1f3fb-200d-2642-fe0f",shortnames:[":man_pouting_light_skin_tone:"],category:"people"},":man_pouting_tone2:":{uc_base:"1f64e-1f3fc-2642",uc_full:"1f64e-1f3fc-200d-2642-fe0f",shortnames:[":man_pouting_medium_light_skin_tone:"],category:"people"},":man_pouting_tone3:":{uc_base:"1f64e-1f3fd-2642",uc_full:"1f64e-1f3fd-200d-2642-fe0f",shortnames:[":man_pouting_medium_skin_tone:"],category:"people"},":man_pouting_tone4:":{uc_base:"1f64e-1f3fe-2642",uc_full:"1f64e-1f3fe-200d-2642-fe0f",shortnames:[":man_pouting_medium_dark_skin_tone:"],category:"people"},":man_pouting_tone5:":{uc_base:"1f64e-1f3ff-2642",uc_full:"1f64e-1f3ff-200d-2642-fe0f",shortnames:[":man_pouting_dark_skin_tone:"],category:"people"},":man_raising_hand_tone1:":{uc_base:"1f64b-1f3fb-2642",uc_full:"1f64b-1f3fb-200d-2642-fe0f",shortnames:[":man_raising_hand_light_skin_tone:"],category:"people"},":man_raising_hand_tone2:":{uc_base:"1f64b-1f3fc-2642",uc_full:"1f64b-1f3fc-200d-2642-fe0f",shortnames:[":man_raising_hand_medium_light_skin_tone:"],category:"people"},":man_raising_hand_tone3:":{uc_base:"1f64b-1f3fd-2642",uc_full:"1f64b-1f3fd-200d-2642-fe0f",shortnames:[":man_raising_hand_medium_skin_tone:"],category:"people"},":man_raising_hand_tone4:":{uc_base:"1f64b-1f3fe-2642",uc_full:"1f64b-1f3fe-200d-2642-fe0f",shortnames:[":man_raising_hand_medium_dark_skin_tone:"],category:"people"},":man_raising_hand_tone5:":{uc_base:"1f64b-1f3ff-2642",uc_full:"1f64b-1f3ff-200d-2642-fe0f",shortnames:[":man_raising_hand_dark_skin_tone:"],category:"people"},":man_rowing_boat_tone1:":{uc_base:"1f6a3-1f3fb-2642",uc_full:"1f6a3-1f3fb-200d-2642-fe0f",shortnames:[":man_rowing_boat_light_skin_tone:"],category:"activity"},":man_rowing_boat_tone2:":{uc_base:"1f6a3-1f3fc-2642",uc_full:"1f6a3-1f3fc-200d-2642-fe0f",shortnames:[":man_rowing_boat_medium_light_skin_tone:"],category:"activity"},":man_rowing_boat_tone3:":{uc_base:"1f6a3-1f3fd-2642",uc_full:"1f6a3-1f3fd-200d-2642-fe0f",shortnames:[":man_rowing_boat_medium_skin_tone:"],category:"activity"},":man_rowing_boat_tone4:":{uc_base:"1f6a3-1f3fe-2642",uc_full:"1f6a3-1f3fe-200d-2642-fe0f",shortnames:[":man_rowing_boat_medium_dark_skin_tone:"],category:"activity"},":man_rowing_boat_tone5:":{uc_base:"1f6a3-1f3ff-2642",uc_full:"1f6a3-1f3ff-200d-2642-fe0f",shortnames:[":man_rowing_boat_dark_skin_tone:"],category:"activity"},":man_running_tone1:":{uc_base:"1f3c3-1f3fb-2642",uc_full:"1f3c3-1f3fb-200d-2642-fe0f",shortnames:[":man_running_light_skin_tone:"],category:"people"},":man_running_tone2:":{uc_base:"1f3c3-1f3fc-2642",uc_full:"1f3c3-1f3fc-200d-2642-fe0f",shortnames:[":man_running_medium_light_skin_tone:"],category:"people"},":man_running_tone3:":{uc_base:"1f3c3-1f3fd-2642",uc_full:"1f3c3-1f3fd-200d-2642-fe0f",shortnames:[":man_running_medium_skin_tone:"],category:"people"},":man_running_tone4:":{uc_base:"1f3c3-1f3fe-2642",uc_full:"1f3c3-1f3fe-200d-2642-fe0f",shortnames:[":man_running_medium_dark_skin_tone:"],category:"people"},":man_running_tone5:":{uc_base:"1f3c3-1f3ff-2642",uc_full:"1f3c3-1f3ff-200d-2642-fe0f",shortnames:[":man_running_dark_skin_tone:"],category:"people"},":man_shrugging_tone1:":{uc_base:"1f937-1f3fb-2642",uc_full:"1f937-1f3fb-200d-2642-fe0f",shortnames:[":man_shrugging_light_skin_tone:"],category:"people"},":man_shrugging_tone2:":{uc_base:"1f937-1f3fc-2642",uc_full:"1f937-1f3fc-200d-2642-fe0f",shortnames:[":man_shrugging_medium_light_skin_tone:"],category:"people"},":man_shrugging_tone3:":{uc_base:"1f937-1f3fd-2642",uc_full:"1f937-1f3fd-200d-2642-fe0f",shortnames:[":man_shrugging_medium_skin_tone:"],category:"people"},":man_shrugging_tone4:":{uc_base:"1f937-1f3fe-2642",uc_full:"1f937-1f3fe-200d-2642-fe0f",shortnames:[":man_shrugging_medium_dark_skin_tone:"],category:"people"},":man_shrugging_tone5:":{uc_base:"1f937-1f3ff-2642",uc_full:"1f937-1f3ff-200d-2642-fe0f",shortnames:[":man_shrugging_dark_skin_tone:"],category:"people"},":man_standing_tone1:":{uc_base:"1f9cd-1f3fb-2642",uc_full:"1f9cd-1f3fb-200d-2642-fe0f",shortnames:[":man_standing_light_skin_tone:"],category:"people"},":man_standing_tone2:":{uc_base:"1f9cd-1f3fc-2642",uc_full:"1f9cd-1f3fc-200d-2642-fe0f",shortnames:[":man_standing_medium_light_skin_tone:"],category:"people"},":man_standing_tone3:":{uc_base:"1f9cd-1f3fd-2642",uc_full:"1f9cd-1f3fd-200d-2642-fe0f",shortnames:[":man_standing_medium_skin_tone:"],category:"people"},":man_standing_tone4:":{uc_base:"1f9cd-1f3fe-2642",uc_full:"1f9cd-1f3fe-200d-2642-fe0f",shortnames:[":man_standing_medium_dark_skin_tone:"],category:"people"},":man_standing_tone5:":{uc_base:"1f9cd-1f3ff-2642",uc_full:"1f9cd-1f3ff-200d-2642-fe0f",shortnames:[":man_standing_dark_skin_tone:"],category:"people"},":man_superhero_tone1:":{uc_base:"1f9b8-1f3fb-2642",uc_full:"1f9b8-1f3fb-200d-2642-fe0f",shortnames:[":man_superhero_light_skin_tone:"],category:"people"},":man_superhero_tone2:":{uc_base:"1f9b8-1f3fc-2642",uc_full:"1f9b8-1f3fc-200d-2642-fe0f",shortnames:[":man_superhero_medium_light_skin_tone:"],category:"people"},":man_superhero_tone3:":{uc_base:"1f9b8-1f3fd-2642",uc_full:"1f9b8-1f3fd-200d-2642-fe0f",shortnames:[":man_superhero_medium_skin_tone:"],category:"people"},":man_superhero_tone4:":{uc_base:"1f9b8-1f3fe-2642",uc_full:"1f9b8-1f3fe-200d-2642-fe0f",shortnames:[":man_superhero_medium_dark_skin_tone:"],category:"people"},":man_superhero_tone5:":{uc_base:"1f9b8-1f3ff-2642",uc_full:"1f9b8-1f3ff-200d-2642-fe0f",shortnames:[":man_superhero_dark_skin_tone:"],category:"people"},":man_supervillain_tone1:":{uc_base:"1f9b9-1f3fb-2642",uc_full:"1f9b9-1f3fb-200d-2642-fe0f",shortnames:[":man_supervillain_light_skin_tone:"],category:"people"},":man_supervillain_tone2:":{uc_base:"1f9b9-1f3fc-2642",uc_full:"1f9b9-1f3fc-200d-2642-fe0f",shortnames:[":man_supervillain_medium_light_skin_tone:"],category:"people"},":man_supervillain_tone3:":{uc_base:"1f9b9-1f3fd-2642",uc_full:"1f9b9-1f3fd-200d-2642-fe0f",shortnames:[":man_supervillain_medium_skin_tone:"],category:"people"},":man_supervillain_tone4:":{uc_base:"1f9b9-1f3fe-2642",uc_full:"1f9b9-1f3fe-200d-2642-fe0f",shortnames:[":man_supervillain_medium_dark_skin_tone:"],category:"people"},":man_supervillain_tone5:":{uc_base:"1f9b9-1f3ff-2642",uc_full:"1f9b9-1f3ff-200d-2642-fe0f",shortnames:[":man_supervillain_dark_skin_tone:"],category:"people"},":man_surfing_tone1:":{uc_base:"1f3c4-1f3fb-2642",uc_full:"1f3c4-1f3fb-200d-2642-fe0f",shortnames:[":man_surfing_light_skin_tone:"],category:"activity"},":man_surfing_tone2:":{uc_base:"1f3c4-1f3fc-2642",uc_full:"1f3c4-1f3fc-200d-2642-fe0f",shortnames:[":man_surfing_medium_light_skin_tone:"],category:"activity"},":man_surfing_tone3:":{uc_base:"1f3c4-1f3fd-2642",uc_full:"1f3c4-1f3fd-200d-2642-fe0f",shortnames:[":man_surfing_medium_skin_tone:"],category:"activity"},":man_surfing_tone4:":{uc_base:"1f3c4-1f3fe-2642",uc_full:"1f3c4-1f3fe-200d-2642-fe0f",shortnames:[":man_surfing_medium_dark_skin_tone:"],category:"activity"},":man_surfing_tone5:":{uc_base:"1f3c4-1f3ff-2642",uc_full:"1f3c4-1f3ff-200d-2642-fe0f",shortnames:[":man_surfing_dark_skin_tone:"],category:"activity"},":man_swimming_tone1:":{uc_base:"1f3ca-1f3fb-2642",uc_full:"1f3ca-1f3fb-200d-2642-fe0f",shortnames:[":man_swimming_light_skin_tone:"],category:"activity"},":man_swimming_tone2:":{uc_base:"1f3ca-1f3fc-2642",uc_full:"1f3ca-1f3fc-200d-2642-fe0f",shortnames:[":man_swimming_medium_light_skin_tone:"],category:"activity"},":man_swimming_tone3:":{uc_base:"1f3ca-1f3fd-2642",uc_full:"1f3ca-1f3fd-200d-2642-fe0f",shortnames:[":man_swimming_medium_skin_tone:"],category:"activity"},":man_swimming_tone4:":{uc_base:"1f3ca-1f3fe-2642",uc_full:"1f3ca-1f3fe-200d-2642-fe0f",shortnames:[":man_swimming_medium_dark_skin_tone:"],category:"activity"},":man_swimming_tone5:":{uc_base:"1f3ca-1f3ff-2642",uc_full:"1f3ca-1f3ff-200d-2642-fe0f",shortnames:[":man_swimming_dark_skin_tone:"],category:"activity"},":man_tipping_hand_tone1:":{uc_base:"1f481-1f3fb-2642",uc_full:"1f481-1f3fb-200d-2642-fe0f",shortnames:[":man_tipping_hand_light_skin_tone:"],category:"people"},":man_tipping_hand_tone2:":{uc_base:"1f481-1f3fc-2642",uc_full:"1f481-1f3fc-200d-2642-fe0f",shortnames:[":man_tipping_hand_medium_light_skin_tone:"],category:"people"},":man_tipping_hand_tone3:":{uc_base:"1f481-1f3fd-2642",uc_full:"1f481-1f3fd-200d-2642-fe0f",shortnames:[":man_tipping_hand_medium_skin_tone:"],category:"people"},":man_tipping_hand_tone4:":{uc_base:"1f481-1f3fe-2642",uc_full:"1f481-1f3fe-200d-2642-fe0f",shortnames:[":man_tipping_hand_medium_dark_skin_tone:"],category:"people"},":man_tipping_hand_tone5:":{uc_base:"1f481-1f3ff-2642",uc_full:"1f481-1f3ff-200d-2642-fe0f",shortnames:[":man_tipping_hand_dark_skin_tone:"],category:"people"},":man_tone1_beard:":{uc_base:"1f9d4-1f3fb-2642",uc_full:"1f9d4-1f3fb-200d-2642-fe0f",shortnames:[":man_light_skin_tone_beard:"],category:"people"},":man_tone2_beard:":{uc_base:"1f9d4-1f3fc-2642",uc_full:"1f9d4-1f3fc-200d-2642-fe0f",shortnames:[":man_medium_light_skin_tone_beard:"],category:"people"},":man_tone3_beard:":{uc_base:"1f9d4-1f3fd-2642",uc_full:"1f9d4-1f3fd-200d-2642-fe0f",shortnames:[":man_medium_skin_tone_beard:"],category:"people"},":man_tone4_beard:":{uc_base:"1f9d4-1f3fe-2642",uc_full:"1f9d4-1f3fe-200d-2642-fe0f",shortnames:[":man_medium_dark_skin_tone_beard:"],category:"people"},":man_tone5_beard:":{uc_base:"1f9d4-1f3ff-2642",uc_full:"1f9d4-1f3ff-200d-2642-fe0f",shortnames:[":man_dark_skin_tone_beard:"],category:"people"},":man_vampire_tone1:":{uc_base:"1f9db-1f3fb-2642",uc_full:"1f9db-1f3fb-200d-2642-fe0f",shortnames:[":man_vampire_light_skin_tone:"],category:"people"},":man_vampire_tone2:":{uc_base:"1f9db-1f3fc-2642",uc_full:"1f9db-1f3fc-200d-2642-fe0f",shortnames:[":man_vampire_medium_light_skin_tone:"],category:"people"},":man_vampire_tone3:":{uc_base:"1f9db-1f3fd-2642",uc_full:"1f9db-1f3fd-200d-2642-fe0f",shortnames:[":man_vampire_medium_skin_tone:"],category:"people"},":man_vampire_tone4:":{uc_base:"1f9db-1f3fe-2642",uc_full:"1f9db-1f3fe-200d-2642-fe0f",shortnames:[":man_vampire_medium_dark_skin_tone:"],category:"people"},":man_vampire_tone5:":{uc_base:"1f9db-1f3ff-2642",uc_full:"1f9db-1f3ff-200d-2642-fe0f",shortnames:[":man_vampire_dark_skin_tone:"],category:"people"},":man_walking_tone1:":{uc_base:"1f6b6-1f3fb-2642",uc_full:"1f6b6-1f3fb-200d-2642-fe0f",shortnames:[":man_walking_light_skin_tone:"],category:"people"},":man_walking_tone2:":{uc_base:"1f6b6-1f3fc-2642",uc_full:"1f6b6-1f3fc-200d-2642-fe0f",shortnames:[":man_walking_medium_light_skin_tone:"],category:"people"},":man_walking_tone3:":{uc_base:"1f6b6-1f3fd-2642",uc_full:"1f6b6-1f3fd-200d-2642-fe0f",shortnames:[":man_walking_medium_skin_tone:"],category:"people"},":man_walking_tone4:":{uc_base:"1f6b6-1f3fe-2642",uc_full:"1f6b6-1f3fe-200d-2642-fe0f",shortnames:[":man_walking_medium_dark_skin_tone:"],category:"people"},":man_walking_tone5:":{uc_base:"1f6b6-1f3ff-2642",uc_full:"1f6b6-1f3ff-200d-2642-fe0f",shortnames:[":man_walking_dark_skin_tone:"],category:"people"},":man_wearing_turban_tone1:":{uc_base:"1f473-1f3fb-2642",uc_full:"1f473-1f3fb-200d-2642-fe0f",shortnames:[":man_wearing_turban_light_skin_tone:"],category:"people"},":man_wearing_turban_tone2:":{uc_base:"1f473-1f3fc-2642",uc_full:"1f473-1f3fc-200d-2642-fe0f",shortnames:[":man_wearing_turban_medium_light_skin_tone:"],category:"people"},":man_wearing_turban_tone3:":{uc_base:"1f473-1f3fd-2642",uc_full:"1f473-1f3fd-200d-2642-fe0f",shortnames:[":man_wearing_turban_medium_skin_tone:"],category:"people"},":man_wearing_turban_tone4:":{uc_base:"1f473-1f3fe-2642",uc_full:"1f473-1f3fe-200d-2642-fe0f",shortnames:[":man_wearing_turban_medium_dark_skin_tone:"],category:"people"},":man_wearing_turban_tone5:":{uc_base:"1f473-1f3ff-2642",uc_full:"1f473-1f3ff-200d-2642-fe0f",shortnames:[":man_wearing_turban_dark_skin_tone:"],category:"people"},":man_with_veil_tone1:":{uc_base:"1f470-1f3fb-2642",uc_full:"1f470-1f3fb-200d-2642-fe0f",shortnames:[":man_with_veil_light_skin_tone:"],category:"people"},":man_with_veil_tone2:":{uc_base:"1f470-1f3fc-2642",uc_full:"1f470-1f3fc-200d-2642-fe0f",shortnames:[":man_with_veil_medium_light_skin_tone:"],category:"people"},":man_with_veil_tone3:":{uc_base:"1f470-1f3fd-2642",uc_full:"1f470-1f3fd-200d-2642-fe0f",shortnames:[":man_with_veil_medium_skin_tone:"],category:"people"},":man_with_veil_tone4:":{uc_base:"1f470-1f3fe-2642",uc_full:"1f470-1f3fe-200d-2642-fe0f",shortnames:[":man_with_veil_medium_dark_skin_tone:"],category:"people"},":man_with_veil_tone5:":{uc_base:"1f470-1f3ff-2642",uc_full:"1f470-1f3ff-200d-2642-fe0f",shortnames:[":man_with_veil_dark_skin_tone:"],category:"people"},":mermaid_tone1:":{uc_base:"1f9dc-1f3fb-2640",uc_full:"1f9dc-1f3fb-200d-2640-fe0f",shortnames:[":mermaid_light_skin_tone:"],category:"people"},":mermaid_tone2:":{uc_base:"1f9dc-1f3fc-2640",uc_full:"1f9dc-1f3fc-200d-2640-fe0f",shortnames:[":mermaid_medium_light_skin_tone:"],category:"people"},":mermaid_tone3:":{uc_base:"1f9dc-1f3fd-2640",uc_full:"1f9dc-1f3fd-200d-2640-fe0f",shortnames:[":mermaid_medium_skin_tone:"],category:"people"},":mermaid_tone4:":{uc_base:"1f9dc-1f3fe-2640",uc_full:"1f9dc-1f3fe-200d-2640-fe0f",shortnames:[":mermaid_medium_dark_skin_tone:"],category:"people"},":mermaid_tone5:":{uc_base:"1f9dc-1f3ff-2640",uc_full:"1f9dc-1f3ff-200d-2640-fe0f",shortnames:[":mermaid_dark_skin_tone:"],category:"people"},":merman_tone1:":{uc_base:"1f9dc-1f3fb-2642",uc_full:"1f9dc-1f3fb-200d-2642-fe0f",shortnames:[":merman_light_skin_tone:"],category:"people"},":merman_tone2:":{uc_base:"1f9dc-1f3fc-2642",uc_full:"1f9dc-1f3fc-200d-2642-fe0f", -shortnames:[":merman_medium_light_skin_tone:"],category:"people"},":merman_tone3:":{uc_base:"1f9dc-1f3fd-2642",uc_full:"1f9dc-1f3fd-200d-2642-fe0f",shortnames:[":merman_medium_skin_tone:"],category:"people"},":merman_tone4:":{uc_base:"1f9dc-1f3fe-2642",uc_full:"1f9dc-1f3fe-200d-2642-fe0f",shortnames:[":merman_medium_dark_skin_tone:"],category:"people"},":merman_tone5:":{uc_base:"1f9dc-1f3ff-2642",uc_full:"1f9dc-1f3ff-200d-2642-fe0f",shortnames:[":merman_dark_skin_tone:"],category:"people"},":pilot_tone1:":{uc_base:"1f9d1-1f3fb-2708",uc_full:"1f9d1-1f3fb-200d-2708-fe0f",shortnames:[":pilot_light_skin_tone:"],category:"people"},":pilot_tone2:":{uc_base:"1f9d1-1f3fc-2708",uc_full:"1f9d1-1f3fc-200d-2708-fe0f",shortnames:[":pilot_medium_light_skin_tone:"],category:"people"},":pilot_tone3:":{uc_base:"1f9d1-1f3fd-2708",uc_full:"1f9d1-1f3fd-200d-2708-fe0f",shortnames:[":pilot_medium_skin_tone:"],category:"people"},":pilot_tone4:":{uc_base:"1f9d1-1f3fe-2708",uc_full:"1f9d1-1f3fe-200d-2708-fe0f",shortnames:[":pilot_medium_dark_skin_tone:"],category:"people"},":pilot_tone5:":{uc_base:"1f9d1-1f3ff-2708",uc_full:"1f9d1-1f3ff-200d-2708-fe0f",shortnames:[":pilot_dark_skin_tone:"],category:"people"},":woman_biking_tone1:":{uc_base:"1f6b4-1f3fb-2640",uc_full:"1f6b4-1f3fb-200d-2640-fe0f",shortnames:[":woman_biking_light_skin_tone:"],category:"activity"},":woman_biking_tone2:":{uc_base:"1f6b4-1f3fc-2640",uc_full:"1f6b4-1f3fc-200d-2640-fe0f",shortnames:[":woman_biking_medium_light_skin_tone:"],category:"activity"},":woman_biking_tone3:":{uc_base:"1f6b4-1f3fd-2640",uc_full:"1f6b4-1f3fd-200d-2640-fe0f",shortnames:[":woman_biking_medium_skin_tone:"],category:"activity"},":woman_biking_tone4:":{uc_base:"1f6b4-1f3fe-2640",uc_full:"1f6b4-1f3fe-200d-2640-fe0f",shortnames:[":woman_biking_medium_dark_skin_tone:"],category:"activity"},":woman_biking_tone5:":{uc_base:"1f6b4-1f3ff-2640",uc_full:"1f6b4-1f3ff-200d-2640-fe0f",shortnames:[":woman_biking_dark_skin_tone:"],category:"activity"},":woman_bowing_tone1:":{uc_base:"1f647-1f3fb-2640",uc_full:"1f647-1f3fb-200d-2640-fe0f",shortnames:[":woman_bowing_light_skin_tone:"],category:"people"},":woman_bowing_tone2:":{uc_base:"1f647-1f3fc-2640",uc_full:"1f647-1f3fc-200d-2640-fe0f",shortnames:[":woman_bowing_medium_light_skin_tone:"],category:"people"},":woman_bowing_tone3:":{uc_base:"1f647-1f3fd-2640",uc_full:"1f647-1f3fd-200d-2640-fe0f",shortnames:[":woman_bowing_medium_skin_tone:"],category:"people"},":woman_bowing_tone4:":{uc_base:"1f647-1f3fe-2640",uc_full:"1f647-1f3fe-200d-2640-fe0f",shortnames:[":woman_bowing_medium_dark_skin_tone:"],category:"people"},":woman_bowing_tone5:":{uc_base:"1f647-1f3ff-2640",uc_full:"1f647-1f3ff-200d-2640-fe0f",shortnames:[":woman_bowing_dark_skin_tone:"],category:"people"},":woman_cartwheeling_tone1:":{uc_base:"1f938-1f3fb-2640",uc_full:"1f938-1f3fb-200d-2640-fe0f",shortnames:[":woman_cartwheeling_light_skin_tone:"],category:"activity"},":woman_cartwheeling_tone2:":{uc_base:"1f938-1f3fc-2640",uc_full:"1f938-1f3fc-200d-2640-fe0f",shortnames:[":woman_cartwheeling_medium_light_skin_tone:"],category:"activity"},":woman_cartwheeling_tone3:":{uc_base:"1f938-1f3fd-2640",uc_full:"1f938-1f3fd-200d-2640-fe0f",shortnames:[":woman_cartwheeling_medium_skin_tone:"],category:"activity"},":woman_cartwheeling_tone4:":{uc_base:"1f938-1f3fe-2640",uc_full:"1f938-1f3fe-200d-2640-fe0f",shortnames:[":woman_cartwheeling_medium_dark_skin_tone:"],category:"activity"},":woman_cartwheeling_tone5:":{uc_base:"1f938-1f3ff-2640",uc_full:"1f938-1f3ff-200d-2640-fe0f",shortnames:[":woman_cartwheeling_dark_skin_tone:"],category:"activity"},":woman_climbing_tone1:":{uc_base:"1f9d7-1f3fb-2640",uc_full:"1f9d7-1f3fb-200d-2640-fe0f",shortnames:[":woman_climbing_light_skin_tone:"],category:"activity"},":woman_climbing_tone2:":{uc_base:"1f9d7-1f3fc-2640",uc_full:"1f9d7-1f3fc-200d-2640-fe0f",shortnames:[":woman_climbing_medium_light_skin_tone:"],category:"activity"},":woman_climbing_tone3:":{uc_base:"1f9d7-1f3fd-2640",uc_full:"1f9d7-1f3fd-200d-2640-fe0f",shortnames:[":woman_climbing_medium_skin_tone:"],category:"activity"},":woman_climbing_tone4:":{uc_base:"1f9d7-1f3fe-2640",uc_full:"1f9d7-1f3fe-200d-2640-fe0f",shortnames:[":woman_climbing_medium_dark_skin_tone:"],category:"activity"},":woman_climbing_tone5:":{uc_base:"1f9d7-1f3ff-2640",uc_full:"1f9d7-1f3ff-200d-2640-fe0f",shortnames:[":woman_climbing_dark_skin_tone:"],category:"activity"},":woman_construction_worker_tone1:":{uc_base:"1f477-1f3fb-2640",uc_full:"1f477-1f3fb-200d-2640-fe0f",shortnames:[":woman_construction_worker_light_skin_tone:"],category:"people"},":woman_construction_worker_tone2:":{uc_base:"1f477-1f3fc-2640",uc_full:"1f477-1f3fc-200d-2640-fe0f",shortnames:[":woman_construction_worker_medium_light_skin_tone:"],category:"people"},":woman_construction_worker_tone3:":{uc_base:"1f477-1f3fd-2640",uc_full:"1f477-1f3fd-200d-2640-fe0f",shortnames:[":woman_construction_worker_medium_skin_tone:"],category:"people"},":woman_construction_worker_tone4:":{uc_base:"1f477-1f3fe-2640",uc_full:"1f477-1f3fe-200d-2640-fe0f",shortnames:[":woman_construction_worker_medium_dark_skin_tone:"],category:"people"},":woman_construction_worker_tone5:":{uc_base:"1f477-1f3ff-2640",uc_full:"1f477-1f3ff-200d-2640-fe0f",shortnames:[":woman_construction_worker_dark_skin_tone:"],category:"people"},":woman_detective_tone1:":{uc_base:"1f575-1f3fb-2640",uc_full:"1f575-1f3fb-200d-2640-fe0f",shortnames:[":woman_detective_light_skin_tone:"],category:"people"},":woman_detective_tone2:":{uc_base:"1f575-1f3fc-2640",uc_full:"1f575-1f3fc-200d-2640-fe0f",shortnames:[":woman_detective_medium_light_skin_tone:"],category:"people"},":woman_detective_tone3:":{uc_base:"1f575-1f3fd-2640",uc_full:"1f575-1f3fd-200d-2640-fe0f",shortnames:[":woman_detective_medium_skin_tone:"],category:"people"},":woman_detective_tone4:":{uc_base:"1f575-1f3fe-2640",uc_full:"1f575-1f3fe-200d-2640-fe0f",shortnames:[":woman_detective_medium_dark_skin_tone:"],category:"people"},":woman_detective_tone5:":{uc_base:"1f575-1f3ff-2640",uc_full:"1f575-1f3ff-200d-2640-fe0f",shortnames:[":woman_detective_dark_skin_tone:"],category:"people"},":woman_elf_tone1:":{uc_base:"1f9dd-1f3fb-2640",uc_full:"1f9dd-1f3fb-200d-2640-fe0f",shortnames:[":woman_elf_light_skin_tone:"],category:"people"},":woman_elf_tone2:":{uc_base:"1f9dd-1f3fc-2640",uc_full:"1f9dd-1f3fc-200d-2640-fe0f",shortnames:[":woman_elf_medium_light_skin_tone:"],category:"people"},":woman_elf_tone3:":{uc_base:"1f9dd-1f3fd-2640",uc_full:"1f9dd-1f3fd-200d-2640-fe0f",shortnames:[":woman_elf_medium_skin_tone:"],category:"people"},":woman_elf_tone4:":{uc_base:"1f9dd-1f3fe-2640",uc_full:"1f9dd-1f3fe-200d-2640-fe0f",shortnames:[":woman_elf_medium_dark_skin_tone:"],category:"people"},":woman_elf_tone5:":{uc_base:"1f9dd-1f3ff-2640",uc_full:"1f9dd-1f3ff-200d-2640-fe0f",shortnames:[":woman_elf_dark_skin_tone:"],category:"people"},":woman_facepalming_tone1:":{uc_base:"1f926-1f3fb-2640",uc_full:"1f926-1f3fb-200d-2640-fe0f",shortnames:[":woman_facepalming_light_skin_tone:"],category:"people"},":woman_facepalming_tone2:":{uc_base:"1f926-1f3fc-2640",uc_full:"1f926-1f3fc-200d-2640-fe0f",shortnames:[":woman_facepalming_medium_light_skin_tone:"],category:"people"},":woman_facepalming_tone3:":{uc_base:"1f926-1f3fd-2640",uc_full:"1f926-1f3fd-200d-2640-fe0f",shortnames:[":woman_facepalming_medium_skin_tone:"],category:"people"},":woman_facepalming_tone4:":{uc_base:"1f926-1f3fe-2640",uc_full:"1f926-1f3fe-200d-2640-fe0f",shortnames:[":woman_facepalming_medium_dark_skin_tone:"],category:"people"},":woman_facepalming_tone5:":{uc_base:"1f926-1f3ff-2640",uc_full:"1f926-1f3ff-200d-2640-fe0f",shortnames:[":woman_facepalming_dark_skin_tone:"],category:"people"},":woman_fairy_tone1:":{uc_base:"1f9da-1f3fb-2640",uc_full:"1f9da-1f3fb-200d-2640-fe0f",shortnames:[":woman_fairy_light_skin_tone:"],category:"people"},":woman_fairy_tone2:":{uc_base:"1f9da-1f3fc-2640",uc_full:"1f9da-1f3fc-200d-2640-fe0f",shortnames:[":woman_fairy_medium_light_skin_tone:"],category:"people"},":woman_fairy_tone3:":{uc_base:"1f9da-1f3fd-2640",uc_full:"1f9da-1f3fd-200d-2640-fe0f",shortnames:[":woman_fairy_medium_skin_tone:"],category:"people"},":woman_fairy_tone4:":{uc_base:"1f9da-1f3fe-2640",uc_full:"1f9da-1f3fe-200d-2640-fe0f",shortnames:[":woman_fairy_medium_dark_skin_tone:"],category:"people"},":woman_fairy_tone5:":{uc_base:"1f9da-1f3ff-2640",uc_full:"1f9da-1f3ff-200d-2640-fe0f",shortnames:[":woman_fairy_dark_skin_tone:"],category:"people"},":woman_frowning_tone1:":{uc_base:"1f64d-1f3fb-2640",uc_full:"1f64d-1f3fb-200d-2640-fe0f",shortnames:[":woman_frowning_light_skin_tone:"],category:"people"},":woman_frowning_tone2:":{uc_base:"1f64d-1f3fc-2640",uc_full:"1f64d-1f3fc-200d-2640-fe0f",shortnames:[":woman_frowning_medium_light_skin_tone:"],category:"people"},":woman_frowning_tone3:":{uc_base:"1f64d-1f3fd-2640",uc_full:"1f64d-1f3fd-200d-2640-fe0f",shortnames:[":woman_frowning_medium_skin_tone:"],category:"people"},":woman_frowning_tone4:":{uc_base:"1f64d-1f3fe-2640",uc_full:"1f64d-1f3fe-200d-2640-fe0f",shortnames:[":woman_frowning_medium_dark_skin_tone:"],category:"people"},":woman_frowning_tone5:":{uc_base:"1f64d-1f3ff-2640",uc_full:"1f64d-1f3ff-200d-2640-fe0f",shortnames:[":woman_frowning_dark_skin_tone:"],category:"people"},":woman_gesturing_no_tone1:":{uc_base:"1f645-1f3fb-2640",uc_full:"1f645-1f3fb-200d-2640-fe0f",shortnames:[":woman_gesturing_no_light_skin_tone:"],category:"people"},":woman_gesturing_no_tone2:":{uc_base:"1f645-1f3fc-2640",uc_full:"1f645-1f3fc-200d-2640-fe0f",shortnames:[":woman_gesturing_no_medium_light_skin_tone:"],category:"people"},":woman_gesturing_no_tone3:":{uc_base:"1f645-1f3fd-2640",uc_full:"1f645-1f3fd-200d-2640-fe0f",shortnames:[":woman_gesturing_no_medium_skin_tone:"],category:"people"},":woman_gesturing_no_tone4:":{uc_base:"1f645-1f3fe-2640",uc_full:"1f645-1f3fe-200d-2640-fe0f",shortnames:[":woman_gesturing_no_medium_dark_skin_tone:"],category:"people"},":woman_gesturing_no_tone5:":{uc_base:"1f645-1f3ff-2640",uc_full:"1f645-1f3ff-200d-2640-fe0f",shortnames:[":woman_gesturing_no_dark_skin_tone:"],category:"people"},":woman_gesturing_ok_tone1:":{uc_base:"1f646-1f3fb-2640",uc_full:"1f646-1f3fb-200d-2640-fe0f",shortnames:[":woman_gesturing_ok_light_skin_tone:"],category:"people"},":woman_gesturing_ok_tone2:":{uc_base:"1f646-1f3fc-2640",uc_full:"1f646-1f3fc-200d-2640-fe0f",shortnames:[":woman_gesturing_ok_medium_light_skin_tone:"],category:"people"},":woman_gesturing_ok_tone3:":{uc_base:"1f646-1f3fd-2640",uc_full:"1f646-1f3fd-200d-2640-fe0f",shortnames:[":woman_gesturing_ok_medium_skin_tone:"],category:"people"},":woman_gesturing_ok_tone4:":{uc_base:"1f646-1f3fe-2640",uc_full:"1f646-1f3fe-200d-2640-fe0f",shortnames:[":woman_gesturing_ok_medium_dark_skin_tone:"],category:"people"},":woman_gesturing_ok_tone5:":{uc_base:"1f646-1f3ff-2640",uc_full:"1f646-1f3ff-200d-2640-fe0f",shortnames:[":woman_gesturing_ok_dark_skin_tone:"],category:"people"},":woman_getting_face_massage_tone1:":{uc_base:"1f486-1f3fb-2640",uc_full:"1f486-1f3fb-200d-2640-fe0f",shortnames:[":woman_getting_face_massage_light_skin_tone:"],category:"people"},":woman_getting_face_massage_tone2:":{uc_base:"1f486-1f3fc-2640",uc_full:"1f486-1f3fc-200d-2640-fe0f",shortnames:[":woman_getting_face_massage_medium_light_skin_tone:"],category:"people"},":woman_getting_face_massage_tone3:":{uc_base:"1f486-1f3fd-2640",uc_full:"1f486-1f3fd-200d-2640-fe0f",shortnames:[":woman_getting_face_massage_medium_skin_tone:"],category:"people"},":woman_getting_face_massage_tone4:":{uc_base:"1f486-1f3fe-2640",uc_full:"1f486-1f3fe-200d-2640-fe0f",shortnames:[":woman_getting_face_massage_medium_dark_skin_tone:"],category:"people"},":woman_getting_face_massage_tone5:":{uc_base:"1f486-1f3ff-2640",uc_full:"1f486-1f3ff-200d-2640-fe0f",shortnames:[":woman_getting_face_massage_dark_skin_tone:"],category:"people"},":woman_getting_haircut_tone1:":{uc_base:"1f487-1f3fb-2640",uc_full:"1f487-1f3fb-200d-2640-fe0f",shortnames:[":woman_getting_haircut_light_skin_tone:"],category:"people"},":woman_getting_haircut_tone2:":{uc_base:"1f487-1f3fc-2640",uc_full:"1f487-1f3fc-200d-2640-fe0f",shortnames:[":woman_getting_haircut_medium_light_skin_tone:"],category:"people"},":woman_getting_haircut_tone3:":{uc_base:"1f487-1f3fd-2640",uc_full:"1f487-1f3fd-200d-2640-fe0f",shortnames:[":woman_getting_haircut_medium_skin_tone:"],category:"people"},":woman_getting_haircut_tone4:":{uc_base:"1f487-1f3fe-2640",uc_full:"1f487-1f3fe-200d-2640-fe0f",shortnames:[":woman_getting_haircut_medium_dark_skin_tone:"],category:"people"},":woman_getting_haircut_tone5:":{uc_base:"1f487-1f3ff-2640",uc_full:"1f487-1f3ff-200d-2640-fe0f",shortnames:[":woman_getting_haircut_dark_skin_tone:"],category:"people"},":woman_golfing_tone1:":{uc_base:"1f3cc-1f3fb-2640",uc_full:"1f3cc-1f3fb-200d-2640-fe0f",shortnames:[":woman_golfing_light_skin_tone:"],category:"activity"},":woman_golfing_tone2:":{uc_base:"1f3cc-1f3fc-2640",uc_full:"1f3cc-1f3fc-200d-2640-fe0f",shortnames:[":woman_golfing_medium_light_skin_tone:"],category:"activity"},":woman_golfing_tone3:":{uc_base:"1f3cc-1f3fd-2640",uc_full:"1f3cc-1f3fd-200d-2640-fe0f",shortnames:[":woman_golfing_medium_skin_tone:"],category:"activity"},":woman_golfing_tone4:":{uc_base:"1f3cc-1f3fe-2640",uc_full:"1f3cc-1f3fe-200d-2640-fe0f",shortnames:[":woman_golfing_medium_dark_skin_tone:"],category:"activity"},":woman_golfing_tone5:":{uc_base:"1f3cc-1f3ff-2640",uc_full:"1f3cc-1f3ff-200d-2640-fe0f",shortnames:[":woman_golfing_dark_skin_tone:"],category:"activity"},":woman_guard_tone1:":{uc_base:"1f482-1f3fb-2640",uc_full:"1f482-1f3fb-200d-2640-fe0f",shortnames:[":woman_guard_light_skin_tone:"],category:"people"},":woman_guard_tone2:":{uc_base:"1f482-1f3fc-2640",uc_full:"1f482-1f3fc-200d-2640-fe0f",shortnames:[":woman_guard_medium_light_skin_tone:"],category:"people"},":woman_guard_tone3:":{uc_base:"1f482-1f3fd-2640",uc_full:"1f482-1f3fd-200d-2640-fe0f",shortnames:[":woman_guard_medium_skin_tone:"],category:"people"},":woman_guard_tone4:":{uc_base:"1f482-1f3fe-2640",uc_full:"1f482-1f3fe-200d-2640-fe0f",shortnames:[":woman_guard_medium_dark_skin_tone:"],category:"people"},":woman_guard_tone5:":{uc_base:"1f482-1f3ff-2640",uc_full:"1f482-1f3ff-200d-2640-fe0f",shortnames:[":woman_guard_dark_skin_tone:"],category:"people"},":woman_health_worker_tone1:":{uc_base:"1f469-1f3fb-2695",uc_full:"1f469-1f3fb-200d-2695-fe0f",shortnames:[":woman_health_worker_light_skin_tone:"],category:"people"},":woman_health_worker_tone2:":{uc_base:"1f469-1f3fc-2695",uc_full:"1f469-1f3fc-200d-2695-fe0f",shortnames:[":woman_health_worker_medium_light_skin_tone:"],category:"people"},":woman_health_worker_tone3:":{uc_base:"1f469-1f3fd-2695",uc_full:"1f469-1f3fd-200d-2695-fe0f",shortnames:[":woman_health_worker_medium_skin_tone:"],category:"people"},":woman_health_worker_tone4:":{uc_base:"1f469-1f3fe-2695",uc_full:"1f469-1f3fe-200d-2695-fe0f",shortnames:[":woman_health_worker_medium_dark_skin_tone:"],category:"people"},":woman_health_worker_tone5:":{uc_base:"1f469-1f3ff-2695",uc_full:"1f469-1f3ff-200d-2695-fe0f",shortnames:[":woman_health_worker_dark_skin_tone:"],category:"people"},":woman_in_lotus_position_tone1:":{uc_base:"1f9d8-1f3fb-2640",uc_full:"1f9d8-1f3fb-200d-2640-fe0f",shortnames:[":woman_in_lotus_position_light_skin_tone:"],category:"activity"},":woman_in_lotus_position_tone2:":{uc_base:"1f9d8-1f3fc-2640",uc_full:"1f9d8-1f3fc-200d-2640-fe0f",shortnames:[":woman_in_lotus_position_medium_light_skin_tone:"],category:"activity"},":woman_in_lotus_position_tone3:":{uc_base:"1f9d8-1f3fd-2640",uc_full:"1f9d8-1f3fd-200d-2640-fe0f",shortnames:[":woman_in_lotus_position_medium_skin_tone:"],category:"activity"},":woman_in_lotus_position_tone4:":{uc_base:"1f9d8-1f3fe-2640",uc_full:"1f9d8-1f3fe-200d-2640-fe0f",shortnames:[":woman_in_lotus_position_medium_dark_skin_tone:"],category:"activity"},":woman_in_lotus_position_tone5:":{uc_base:"1f9d8-1f3ff-2640",uc_full:"1f9d8-1f3ff-200d-2640-fe0f",shortnames:[":woman_in_lotus_position_dark_skin_tone:"],category:"activity"},":woman_in_steamy_room_tone1:":{uc_base:"1f9d6-1f3fb-2640",uc_full:"1f9d6-1f3fb-200d-2640-fe0f",shortnames:[":woman_in_steamy_room_light_skin_tone:"],category:"people"},":woman_in_steamy_room_tone2:":{uc_base:"1f9d6-1f3fc-2640",uc_full:"1f9d6-1f3fc-200d-2640-fe0f",shortnames:[":woman_in_steamy_room_medium_light_skin_tone:"],category:"people"},":woman_in_steamy_room_tone3:":{uc_base:"1f9d6-1f3fd-2640",uc_full:"1f9d6-1f3fd-200d-2640-fe0f",shortnames:[":woman_in_steamy_room_medium_skin_tone:"],category:"people"},":woman_in_steamy_room_tone4:":{uc_base:"1f9d6-1f3fe-2640",uc_full:"1f9d6-1f3fe-200d-2640-fe0f",shortnames:[":woman_in_steamy_room_medium_dark_skin_tone:"],category:"people"},":woman_in_steamy_room_tone5:":{uc_base:"1f9d6-1f3ff-2640",uc_full:"1f9d6-1f3ff-200d-2640-fe0f",shortnames:[":woman_in_steamy_room_dark_skin_tone:"],category:"people"},":woman_in_tuxedo_tone1:":{uc_base:"1f935-1f3fb-2640",uc_full:"1f935-1f3fb-200d-2640-fe0f",shortnames:[":woman_in_tuxedo_light_skin_tone:"],category:"people"},":woman_in_tuxedo_tone2:":{uc_base:"1f935-1f3fc-2640",uc_full:"1f935-1f3fc-200d-2640-fe0f",shortnames:[":woman_in_tuxedo_medium_light_skin_tone:"],category:"people"},":woman_in_tuxedo_tone3:":{uc_base:"1f935-1f3fd-2640",uc_full:"1f935-1f3fd-200d-2640-fe0f",shortnames:[":woman_in_tuxedo_medium_skin_tone:"],category:"people"},":woman_in_tuxedo_tone4:":{uc_base:"1f935-1f3fe-2640",uc_full:"1f935-1f3fe-200d-2640-fe0f",shortnames:[":woman_in_tuxedo_medium_dark_skin_tone:"],category:"people"},":woman_in_tuxedo_tone5:":{uc_base:"1f935-1f3ff-2640",uc_full:"1f935-1f3ff-200d-2640-fe0f",shortnames:[":woman_in_tuxedo_dark_skin_tone:"],category:"people"},":woman_judge_tone1:":{uc_base:"1f469-1f3fb-2696",uc_full:"1f469-1f3fb-200d-2696-fe0f",shortnames:[":woman_judge_light_skin_tone:"],category:"people"},":woman_judge_tone2:":{uc_base:"1f469-1f3fc-2696",uc_full:"1f469-1f3fc-200d-2696-fe0f",shortnames:[":woman_judge_medium_light_skin_tone:"],category:"people"},":woman_judge_tone3:":{uc_base:"1f469-1f3fd-2696",uc_full:"1f469-1f3fd-200d-2696-fe0f",shortnames:[":woman_judge_medium_skin_tone:"],category:"people"},":woman_judge_tone4:":{uc_base:"1f469-1f3fe-2696",uc_full:"1f469-1f3fe-200d-2696-fe0f",shortnames:[":woman_judge_medium_dark_skin_tone:"],category:"people"},":woman_judge_tone5:":{uc_base:"1f469-1f3ff-2696",uc_full:"1f469-1f3ff-200d-2696-fe0f",shortnames:[":woman_judge_dark_skin_tone:"],category:"people"},":woman_juggling_tone1:":{uc_base:"1f939-1f3fb-2640",uc_full:"1f939-1f3fb-200d-2640-fe0f",shortnames:[":woman_juggling_light_skin_tone:"],category:"activity"},":woman_juggling_tone2:":{uc_base:"1f939-1f3fc-2640",uc_full:"1f939-1f3fc-200d-2640-fe0f",shortnames:[":woman_juggling_medium_light_skin_tone:"],category:"activity"},":woman_juggling_tone3:":{uc_base:"1f939-1f3fd-2640",uc_full:"1f939-1f3fd-200d-2640-fe0f",shortnames:[":woman_juggling_medium_skin_tone:"],category:"activity"},":woman_juggling_tone4:":{uc_base:"1f939-1f3fe-2640",uc_full:"1f939-1f3fe-200d-2640-fe0f",shortnames:[":woman_juggling_medium_dark_skin_tone:"],category:"activity"},":woman_juggling_tone5:":{uc_base:"1f939-1f3ff-2640",uc_full:"1f939-1f3ff-200d-2640-fe0f",shortnames:[":woman_juggling_dark_skin_tone:"],category:"activity"},":woman_kneeling_tone1:":{uc_base:"1f9ce-1f3fb-2640",uc_full:"1f9ce-1f3fb-200d-2640-fe0f",shortnames:[":woman_kneeling_light_skin_tone:"],category:"people"},":woman_kneeling_tone2:":{uc_base:"1f9ce-1f3fc-2640",uc_full:"1f9ce-1f3fc-200d-2640-fe0f",shortnames:[":woman_kneeling_medium_light_skin_tone:"],category:"people"},":woman_kneeling_tone3:":{uc_base:"1f9ce-1f3fd-2640",uc_full:"1f9ce-1f3fd-200d-2640-fe0f",shortnames:[":woman_kneeling_medium_skin_tone:"],category:"people"},":woman_kneeling_tone4:":{uc_base:"1f9ce-1f3fe-2640",uc_full:"1f9ce-1f3fe-200d-2640-fe0f",shortnames:[":woman_kneeling_medium_dark_skin_tone:"],category:"people"},":woman_kneeling_tone5:":{uc_base:"1f9ce-1f3ff-2640",uc_full:"1f9ce-1f3ff-200d-2640-fe0f",shortnames:[":woman_kneeling_dark_skin_tone:"],category:"people"},":woman_lifting_weights_tone1:":{uc_base:"1f3cb-1f3fb-2640",uc_full:"1f3cb-1f3fb-200d-2640-fe0f",shortnames:[":woman_lifting_weights_light_skin_tone:"],category:"activity"},":woman_lifting_weights_tone2:":{uc_base:"1f3cb-1f3fc-2640",uc_full:"1f3cb-1f3fc-200d-2640-fe0f",shortnames:[":woman_lifting_weights_medium_light_skin_tone:"],category:"activity"},":woman_lifting_weights_tone3:":{uc_base:"1f3cb-1f3fd-2640",uc_full:"1f3cb-1f3fd-200d-2640-fe0f",shortnames:[":woman_lifting_weights_medium_skin_tone:"],category:"activity"},":woman_lifting_weights_tone4:":{uc_base:"1f3cb-1f3fe-2640",uc_full:"1f3cb-1f3fe-200d-2640-fe0f",shortnames:[":woman_lifting_weights_medium_dark_skin_tone:"],category:"activity"},":woman_lifting_weights_tone5:":{uc_base:"1f3cb-1f3ff-2640",uc_full:"1f3cb-1f3ff-200d-2640-fe0f",shortnames:[":woman_lifting_weights_dark_skin_tone:"],category:"activity"},":woman_mage_tone1:":{uc_base:"1f9d9-1f3fb-2640",uc_full:"1f9d9-1f3fb-200d-2640-fe0f",shortnames:[":woman_mage_light_skin_tone:"],category:"people"},":woman_mage_tone2:":{uc_base:"1f9d9-1f3fc-2640",uc_full:"1f9d9-1f3fc-200d-2640-fe0f",shortnames:[":woman_mage_medium_light_skin_tone:"],category:"people"},":woman_mage_tone3:":{uc_base:"1f9d9-1f3fd-2640",uc_full:"1f9d9-1f3fd-200d-2640-fe0f",shortnames:[":woman_mage_medium_skin_tone:"],category:"people"},":woman_mage_tone4:":{uc_base:"1f9d9-1f3fe-2640",uc_full:"1f9d9-1f3fe-200d-2640-fe0f",shortnames:[":woman_mage_medium_dark_skin_tone:"],category:"people"},":woman_mage_tone5:":{uc_base:"1f9d9-1f3ff-2640",uc_full:"1f9d9-1f3ff-200d-2640-fe0f",shortnames:[":woman_mage_dark_skin_tone:"],category:"people"},":woman_mountain_biking_tone1:":{uc_base:"1f6b5-1f3fb-2640",uc_full:"1f6b5-1f3fb-200d-2640-fe0f",shortnames:[":woman_mountain_biking_light_skin_tone:"],category:"activity"},":woman_mountain_biking_tone2:":{uc_base:"1f6b5-1f3fc-2640",uc_full:"1f6b5-1f3fc-200d-2640-fe0f",shortnames:[":woman_mountain_biking_medium_light_skin_tone:"],category:"activity"},":woman_mountain_biking_tone3:":{uc_base:"1f6b5-1f3fd-2640",uc_full:"1f6b5-1f3fd-200d-2640-fe0f",shortnames:[":woman_mountain_biking_medium_skin_tone:"],category:"activity"},":woman_mountain_biking_tone4:":{uc_base:"1f6b5-1f3fe-2640",uc_full:"1f6b5-1f3fe-200d-2640-fe0f",shortnames:[":woman_mountain_biking_medium_dark_skin_tone:"],category:"activity"},":woman_mountain_biking_tone5:":{uc_base:"1f6b5-1f3ff-2640",uc_full:"1f6b5-1f3ff-200d-2640-fe0f",shortnames:[":woman_mountain_biking_dark_skin_tone:"],category:"activity"},":woman_pilot_tone1:":{uc_base:"1f469-1f3fb-2708",uc_full:"1f469-1f3fb-200d-2708-fe0f",shortnames:[":woman_pilot_light_skin_tone:"],category:"people"},":woman_pilot_tone2:":{uc_base:"1f469-1f3fc-2708",uc_full:"1f469-1f3fc-200d-2708-fe0f",shortnames:[":woman_pilot_medium_light_skin_tone:"],category:"people"},":woman_pilot_tone3:":{uc_base:"1f469-1f3fd-2708",uc_full:"1f469-1f3fd-200d-2708-fe0f",shortnames:[":woman_pilot_medium_skin_tone:"],category:"people"},":woman_pilot_tone4:":{uc_base:"1f469-1f3fe-2708",uc_full:"1f469-1f3fe-200d-2708-fe0f",shortnames:[":woman_pilot_medium_dark_skin_tone:"],category:"people"},":woman_pilot_tone5:":{uc_base:"1f469-1f3ff-2708",uc_full:"1f469-1f3ff-200d-2708-fe0f",shortnames:[":woman_pilot_dark_skin_tone:"],category:"people"},":woman_playing_handball_tone1:":{uc_base:"1f93e-1f3fb-2640",uc_full:"1f93e-1f3fb-200d-2640-fe0f",shortnames:[":woman_playing_handball_light_skin_tone:"],category:"activity"},":woman_playing_handball_tone2:":{uc_base:"1f93e-1f3fc-2640",uc_full:"1f93e-1f3fc-200d-2640-fe0f",shortnames:[":woman_playing_handball_medium_light_skin_tone:"],category:"activity"},":woman_playing_handball_tone3:":{uc_base:"1f93e-1f3fd-2640",uc_full:"1f93e-1f3fd-200d-2640-fe0f",shortnames:[":woman_playing_handball_medium_skin_tone:"],category:"activity"},":woman_playing_handball_tone4:":{uc_base:"1f93e-1f3fe-2640",uc_full:"1f93e-1f3fe-200d-2640-fe0f",shortnames:[":woman_playing_handball_medium_dark_skin_tone:"],category:"activity"},":woman_playing_handball_tone5:":{uc_base:"1f93e-1f3ff-2640",uc_full:"1f93e-1f3ff-200d-2640-fe0f",shortnames:[":woman_playing_handball_dark_skin_tone:"],category:"activity"},":woman_playing_water_polo_tone1:":{uc_base:"1f93d-1f3fb-2640",uc_full:"1f93d-1f3fb-200d-2640-fe0f",shortnames:[":woman_playing_water_polo_light_skin_tone:"],category:"activity"},":woman_playing_water_polo_tone2:":{uc_base:"1f93d-1f3fc-2640",uc_full:"1f93d-1f3fc-200d-2640-fe0f",shortnames:[":woman_playing_water_polo_medium_light_skin_tone:"],category:"activity"},":woman_playing_water_polo_tone3:":{uc_base:"1f93d-1f3fd-2640",uc_full:"1f93d-1f3fd-200d-2640-fe0f",shortnames:[":woman_playing_water_polo_medium_skin_tone:"],category:"activity"},":woman_playing_water_polo_tone4:":{uc_base:"1f93d-1f3fe-2640",uc_full:"1f93d-1f3fe-200d-2640-fe0f",shortnames:[":woman_playing_water_polo_medium_dark_skin_tone:"],category:"activity"},":woman_playing_water_polo_tone5:":{uc_base:"1f93d-1f3ff-2640",uc_full:"1f93d-1f3ff-200d-2640-fe0f",shortnames:[":woman_playing_water_polo_dark_skin_tone:"],category:"activity"},":woman_police_officer_tone1:":{uc_base:"1f46e-1f3fb-2640",uc_full:"1f46e-1f3fb-200d-2640-fe0f",shortnames:[":woman_police_officer_light_skin_tone:"],category:"people"},":woman_police_officer_tone2:":{uc_base:"1f46e-1f3fc-2640",uc_full:"1f46e-1f3fc-200d-2640-fe0f",shortnames:[":woman_police_officer_medium_light_skin_tone:"],category:"people"},":woman_police_officer_tone3:":{uc_base:"1f46e-1f3fd-2640",uc_full:"1f46e-1f3fd-200d-2640-fe0f",shortnames:[":woman_police_officer_medium_skin_tone:"],category:"people"},":woman_police_officer_tone4:":{uc_base:"1f46e-1f3fe-2640",uc_full:"1f46e-1f3fe-200d-2640-fe0f",shortnames:[":woman_police_officer_medium_dark_skin_tone:"],category:"people"},":woman_police_officer_tone5:":{uc_base:"1f46e-1f3ff-2640",uc_full:"1f46e-1f3ff-200d-2640-fe0f",shortnames:[":woman_police_officer_dark_skin_tone:"],category:"people"},":woman_pouting_tone1:":{uc_base:"1f64e-1f3fb-2640",uc_full:"1f64e-1f3fb-200d-2640-fe0f",shortnames:[":woman_pouting_light_skin_tone:"],category:"people"},":woman_pouting_tone2:":{uc_base:"1f64e-1f3fc-2640",uc_full:"1f64e-1f3fc-200d-2640-fe0f",shortnames:[":woman_pouting_medium_light_skin_tone:"],category:"people"},":woman_pouting_tone3:":{uc_base:"1f64e-1f3fd-2640",uc_full:"1f64e-1f3fd-200d-2640-fe0f",shortnames:[":woman_pouting_medium_skin_tone:"],category:"people"},":woman_pouting_tone4:":{uc_base:"1f64e-1f3fe-2640",uc_full:"1f64e-1f3fe-200d-2640-fe0f",shortnames:[":woman_pouting_medium_dark_skin_tone:"],category:"people"},":woman_pouting_tone5:":{uc_base:"1f64e-1f3ff-2640",uc_full:"1f64e-1f3ff-200d-2640-fe0f",shortnames:[":woman_pouting_dark_skin_tone:"],category:"people"},":woman_raising_hand_tone1:":{uc_base:"1f64b-1f3fb-2640",uc_full:"1f64b-1f3fb-200d-2640-fe0f",shortnames:[":woman_raising_hand_light_skin_tone:"],category:"people"},":woman_raising_hand_tone2:":{uc_base:"1f64b-1f3fc-2640",uc_full:"1f64b-1f3fc-200d-2640-fe0f",shortnames:[":woman_raising_hand_medium_light_skin_tone:"],category:"people"},":woman_raising_hand_tone3:":{uc_base:"1f64b-1f3fd-2640",uc_full:"1f64b-1f3fd-200d-2640-fe0f",shortnames:[":woman_raising_hand_medium_skin_tone:"],category:"people"},":woman_raising_hand_tone4:":{uc_base:"1f64b-1f3fe-2640",uc_full:"1f64b-1f3fe-200d-2640-fe0f",shortnames:[":woman_raising_hand_medium_dark_skin_tone:"],category:"people"},":woman_raising_hand_tone5:":{uc_base:"1f64b-1f3ff-2640",uc_full:"1f64b-1f3ff-200d-2640-fe0f",shortnames:[":woman_raising_hand_dark_skin_tone:"],category:"people"},":woman_rowing_boat_tone1:":{uc_base:"1f6a3-1f3fb-2640",uc_full:"1f6a3-1f3fb-200d-2640-fe0f",shortnames:[":woman_rowing_boat_light_skin_tone:"],category:"activity"},":woman_rowing_boat_tone2:":{uc_base:"1f6a3-1f3fc-2640",uc_full:"1f6a3-1f3fc-200d-2640-fe0f",shortnames:[":woman_rowing_boat_medium_light_skin_tone:"],category:"activity"},":woman_rowing_boat_tone3:":{uc_base:"1f6a3-1f3fd-2640",uc_full:"1f6a3-1f3fd-200d-2640-fe0f",shortnames:[":woman_rowing_boat_medium_skin_tone:"],category:"activity"},":woman_rowing_boat_tone4:":{uc_base:"1f6a3-1f3fe-2640",uc_full:"1f6a3-1f3fe-200d-2640-fe0f",shortnames:[":woman_rowing_boat_medium_dark_skin_tone:"],category:"activity"},":woman_rowing_boat_tone5:":{uc_base:"1f6a3-1f3ff-2640",uc_full:"1f6a3-1f3ff-200d-2640-fe0f",shortnames:[":woman_rowing_boat_dark_skin_tone:"],category:"activity"},":woman_running_tone1:":{uc_base:"1f3c3-1f3fb-2640",uc_full:"1f3c3-1f3fb-200d-2640-fe0f",shortnames:[":woman_running_light_skin_tone:"],category:"people"},":woman_running_tone2:":{uc_base:"1f3c3-1f3fc-2640",uc_full:"1f3c3-1f3fc-200d-2640-fe0f",shortnames:[":woman_running_medium_light_skin_tone:"],category:"people"},":woman_running_tone3:":{uc_base:"1f3c3-1f3fd-2640",uc_full:"1f3c3-1f3fd-200d-2640-fe0f",shortnames:[":woman_running_medium_skin_tone:"],category:"people"},":woman_running_tone4:":{uc_base:"1f3c3-1f3fe-2640",uc_full:"1f3c3-1f3fe-200d-2640-fe0f",shortnames:[":woman_running_medium_dark_skin_tone:"],category:"people"},":woman_running_tone5:":{uc_base:"1f3c3-1f3ff-2640",uc_full:"1f3c3-1f3ff-200d-2640-fe0f",shortnames:[":woman_running_dark_skin_tone:"],category:"people"},":woman_shrugging_tone1:":{uc_base:"1f937-1f3fb-2640",uc_full:"1f937-1f3fb-200d-2640-fe0f",shortnames:[":woman_shrugging_light_skin_tone:"],category:"people"},":woman_shrugging_tone2:":{uc_base:"1f937-1f3fc-2640",uc_full:"1f937-1f3fc-200d-2640-fe0f",shortnames:[":woman_shrugging_medium_light_skin_tone:"],category:"people"},":woman_shrugging_tone3:":{uc_base:"1f937-1f3fd-2640",uc_full:"1f937-1f3fd-200d-2640-fe0f",shortnames:[":woman_shrugging_medium_skin_tone:"],category:"people"},":woman_shrugging_tone4:":{uc_base:"1f937-1f3fe-2640",uc_full:"1f937-1f3fe-200d-2640-fe0f",shortnames:[":woman_shrugging_medium_dark_skin_tone:"],category:"people"},":woman_shrugging_tone5:":{uc_base:"1f937-1f3ff-2640",uc_full:"1f937-1f3ff-200d-2640-fe0f",shortnames:[":woman_shrugging_dark_skin_tone:"],category:"people"},":woman_standing_tone1:":{uc_base:"1f9cd-1f3fb-2640",uc_full:"1f9cd-1f3fb-200d-2640-fe0f",shortnames:[":woman_standing_light_skin_tone:"],category:"people"},":woman_standing_tone2:":{uc_base:"1f9cd-1f3fc-2640",uc_full:"1f9cd-1f3fc-200d-2640-fe0f",shortnames:[":woman_standing_medium_light_skin_tone:"],category:"people"},":woman_standing_tone3:":{uc_base:"1f9cd-1f3fd-2640",uc_full:"1f9cd-1f3fd-200d-2640-fe0f",shortnames:[":woman_standing_medium_skin_tone:"],category:"people"},":woman_standing_tone4:":{uc_base:"1f9cd-1f3fe-2640",uc_full:"1f9cd-1f3fe-200d-2640-fe0f",shortnames:[":woman_standing_medium_dark_skin_tone:"],category:"people"},":woman_standing_tone5:":{uc_base:"1f9cd-1f3ff-2640",uc_full:"1f9cd-1f3ff-200d-2640-fe0f",shortnames:[":woman_standing_dark_skin_tone:"],category:"people"},":woman_superhero_tone1:":{uc_base:"1f9b8-1f3fb-2640",uc_full:"1f9b8-1f3fb-200d-2640-fe0f",shortnames:[":woman_superhero_light_skin_tone:"],category:"people"},":woman_superhero_tone2:":{uc_base:"1f9b8-1f3fc-2640",uc_full:"1f9b8-1f3fc-200d-2640-fe0f",shortnames:[":woman_superhero_medium_light_skin_tone:"],category:"people"},":woman_superhero_tone3:":{uc_base:"1f9b8-1f3fd-2640",uc_full:"1f9b8-1f3fd-200d-2640-fe0f",shortnames:[":woman_superhero_medium_skin_tone:"],category:"people"},":woman_superhero_tone4:":{uc_base:"1f9b8-1f3fe-2640",uc_full:"1f9b8-1f3fe-200d-2640-fe0f",shortnames:[":woman_superhero_medium_dark_skin_tone:"],category:"people"},":woman_superhero_tone5:":{uc_base:"1f9b8-1f3ff-2640",uc_full:"1f9b8-1f3ff-200d-2640-fe0f",shortnames:[":woman_superhero_dark_skin_tone:"],category:"people"},":woman_supervillain_tone1:":{uc_base:"1f9b9-1f3fb-2640",uc_full:"1f9b9-1f3fb-200d-2640-fe0f",shortnames:[":woman_supervillain_light_skin_tone:"],category:"people"},":woman_supervillain_tone2:":{uc_base:"1f9b9-1f3fc-2640",uc_full:"1f9b9-1f3fc-200d-2640-fe0f",shortnames:[":woman_supervillain_medium_light_skin_tone:"], -category:"people"},":woman_supervillain_tone3:":{uc_base:"1f9b9-1f3fd-2640",uc_full:"1f9b9-1f3fd-200d-2640-fe0f",shortnames:[":woman_supervillain_medium_skin_tone:"],category:"people"},":woman_supervillain_tone4:":{uc_base:"1f9b9-1f3fe-2640",uc_full:"1f9b9-1f3fe-200d-2640-fe0f",shortnames:[":woman_supervillain_medium_dark_skin_tone:"],category:"people"},":woman_supervillain_tone5:":{uc_base:"1f9b9-1f3ff-2640",uc_full:"1f9b9-1f3ff-200d-2640-fe0f",shortnames:[":woman_supervillain_dark_skin_tone:"],category:"people"},":woman_surfing_tone1:":{uc_base:"1f3c4-1f3fb-2640",uc_full:"1f3c4-1f3fb-200d-2640-fe0f",shortnames:[":woman_surfing_light_skin_tone:"],category:"activity"},":woman_surfing_tone2:":{uc_base:"1f3c4-1f3fc-2640",uc_full:"1f3c4-1f3fc-200d-2640-fe0f",shortnames:[":woman_surfing_medium_light_skin_tone:"],category:"activity"},":woman_surfing_tone3:":{uc_base:"1f3c4-1f3fd-2640",uc_full:"1f3c4-1f3fd-200d-2640-fe0f",shortnames:[":woman_surfing_medium_skin_tone:"],category:"activity"},":woman_surfing_tone4:":{uc_base:"1f3c4-1f3fe-2640",uc_full:"1f3c4-1f3fe-200d-2640-fe0f",shortnames:[":woman_surfing_medium_dark_skin_tone:"],category:"activity"},":woman_surfing_tone5:":{uc_base:"1f3c4-1f3ff-2640",uc_full:"1f3c4-1f3ff-200d-2640-fe0f",shortnames:[":woman_surfing_dark_skin_tone:"],category:"activity"},":woman_swimming_tone1:":{uc_base:"1f3ca-1f3fb-2640",uc_full:"1f3ca-1f3fb-200d-2640-fe0f",shortnames:[":woman_swimming_light_skin_tone:"],category:"activity"},":woman_swimming_tone2:":{uc_base:"1f3ca-1f3fc-2640",uc_full:"1f3ca-1f3fc-200d-2640-fe0f",shortnames:[":woman_swimming_medium_light_skin_tone:"],category:"activity"},":woman_swimming_tone3:":{uc_base:"1f3ca-1f3fd-2640",uc_full:"1f3ca-1f3fd-200d-2640-fe0f",shortnames:[":woman_swimming_medium_skin_tone:"],category:"activity"},":woman_swimming_tone4:":{uc_base:"1f3ca-1f3fe-2640",uc_full:"1f3ca-1f3fe-200d-2640-fe0f",shortnames:[":woman_swimming_medium_dark_skin_tone:"],category:"activity"},":woman_swimming_tone5:":{uc_base:"1f3ca-1f3ff-2640",uc_full:"1f3ca-1f3ff-200d-2640-fe0f",shortnames:[":woman_swimming_dark_skin_tone:"],category:"activity"},":woman_tipping_hand_tone1:":{uc_base:"1f481-1f3fb-2640",uc_full:"1f481-1f3fb-200d-2640-fe0f",shortnames:[":woman_tipping_hand_light_skin_tone:"],category:"people"},":woman_tipping_hand_tone2:":{uc_base:"1f481-1f3fc-2640",uc_full:"1f481-1f3fc-200d-2640-fe0f",shortnames:[":woman_tipping_hand_medium_light_skin_tone:"],category:"people"},":woman_tipping_hand_tone3:":{uc_base:"1f481-1f3fd-2640",uc_full:"1f481-1f3fd-200d-2640-fe0f",shortnames:[":woman_tipping_hand_medium_skin_tone:"],category:"people"},":woman_tipping_hand_tone4:":{uc_base:"1f481-1f3fe-2640",uc_full:"1f481-1f3fe-200d-2640-fe0f",shortnames:[":woman_tipping_hand_medium_dark_skin_tone:"],category:"people"},":woman_tipping_hand_tone5:":{uc_base:"1f481-1f3ff-2640",uc_full:"1f481-1f3ff-200d-2640-fe0f",shortnames:[":woman_tipping_hand_dark_skin_tone:"],category:"people"},":woman_tone1_beard:":{uc_base:"1f9d4-1f3fb-2640",uc_full:"1f9d4-1f3fb-200d-2640-fe0f",shortnames:[":woman_light_skin_tone_beard:"],category:"people"},":woman_tone2_beard:":{uc_base:"1f9d4-1f3fc-2640",uc_full:"1f9d4-1f3fc-200d-2640-fe0f",shortnames:[":woman_medium_light_skin_tone_beard:"],category:"people"},":woman_tone3_beard:":{uc_base:"1f9d4-1f3fd-2640",uc_full:"1f9d4-1f3fd-200d-2640-fe0f",shortnames:[":woman_medium_skin_tone_beard:"],category:"people"},":woman_tone4_beard:":{uc_base:"1f9d4-1f3fe-2640",uc_full:"1f9d4-1f3fe-200d-2640-fe0f",shortnames:[":woman_medium_dark_skin_tone_beard:"],category:"people"},":woman_tone5_beard:":{uc_base:"1f9d4-1f3ff-2640",uc_full:"1f9d4-1f3ff-200d-2640-fe0f",shortnames:[":woman_dark_skin_tone_beard:"],category:"people"},":woman_vampire_tone1:":{uc_base:"1f9db-1f3fb-2640",uc_full:"1f9db-1f3fb-200d-2640-fe0f",shortnames:[":woman_vampire_light_skin_tone:"],category:"people"},":woman_vampire_tone2:":{uc_base:"1f9db-1f3fc-2640",uc_full:"1f9db-1f3fc-200d-2640-fe0f",shortnames:[":woman_vampire_medium_light_skin_tone:"],category:"people"},":woman_vampire_tone3:":{uc_base:"1f9db-1f3fd-2640",uc_full:"1f9db-1f3fd-200d-2640-fe0f",shortnames:[":woman_vampire_medium_skin_tone:"],category:"people"},":woman_vampire_tone4:":{uc_base:"1f9db-1f3fe-2640",uc_full:"1f9db-1f3fe-200d-2640-fe0f",shortnames:[":woman_vampire_medium_dark_skin_tone:"],category:"people"},":woman_vampire_tone5:":{uc_base:"1f9db-1f3ff-2640",uc_full:"1f9db-1f3ff-200d-2640-fe0f",shortnames:[":woman_vampire_dark_skin_tone:"],category:"people"},":woman_walking_tone1:":{uc_base:"1f6b6-1f3fb-2640",uc_full:"1f6b6-1f3fb-200d-2640-fe0f",shortnames:[":woman_walking_light_skin_tone:"],category:"people"},":woman_walking_tone2:":{uc_base:"1f6b6-1f3fc-2640",uc_full:"1f6b6-1f3fc-200d-2640-fe0f",shortnames:[":woman_walking_medium_light_skin_tone:"],category:"people"},":woman_walking_tone3:":{uc_base:"1f6b6-1f3fd-2640",uc_full:"1f6b6-1f3fd-200d-2640-fe0f",shortnames:[":woman_walking_medium_skin_tone:"],category:"people"},":woman_walking_tone4:":{uc_base:"1f6b6-1f3fe-2640",uc_full:"1f6b6-1f3fe-200d-2640-fe0f",shortnames:[":woman_walking_medium_dark_skin_tone:"],category:"people"},":woman_walking_tone5:":{uc_base:"1f6b6-1f3ff-2640",uc_full:"1f6b6-1f3ff-200d-2640-fe0f",shortnames:[":woman_walking_dark_skin_tone:"],category:"people"},":woman_wearing_turban_tone1:":{uc_base:"1f473-1f3fb-2640",uc_full:"1f473-1f3fb-200d-2640-fe0f",shortnames:[":woman_wearing_turban_light_skin_tone:"],category:"people"},":woman_wearing_turban_tone2:":{uc_base:"1f473-1f3fc-2640",uc_full:"1f473-1f3fc-200d-2640-fe0f",shortnames:[":woman_wearing_turban_medium_light_skin_tone:"],category:"people"},":woman_wearing_turban_tone3:":{uc_base:"1f473-1f3fd-2640",uc_full:"1f473-1f3fd-200d-2640-fe0f",shortnames:[":woman_wearing_turban_medium_skin_tone:"],category:"people"},":woman_wearing_turban_tone4:":{uc_base:"1f473-1f3fe-2640",uc_full:"1f473-1f3fe-200d-2640-fe0f",shortnames:[":woman_wearing_turban_medium_dark_skin_tone:"],category:"people"},":woman_wearing_turban_tone5:":{uc_base:"1f473-1f3ff-2640",uc_full:"1f473-1f3ff-200d-2640-fe0f",shortnames:[":woman_wearing_turban_dark_skin_tone:"],category:"people"},":woman_with_veil_tone1:":{uc_base:"1f470-1f3fb-2640",uc_full:"1f470-1f3fb-200d-2640-fe0f",shortnames:[":woman_with_veil_light_skin_tone:"],category:"people"},":woman_with_veil_tone2:":{uc_base:"1f470-1f3fc-2640",uc_full:"1f470-1f3fc-200d-2640-fe0f",shortnames:[":woman_with_veil_medium_light_skin_tone:"],category:"people"},":woman_with_veil_tone3:":{uc_base:"1f470-1f3fd-2640",uc_full:"1f470-1f3fd-200d-2640-fe0f",shortnames:[":woman_with_veil_medium_skin_tone:"],category:"people"},":woman_with_veil_tone4:":{uc_base:"1f470-1f3fe-2640",uc_full:"1f470-1f3fe-200d-2640-fe0f",shortnames:[":woman_with_veil_medium_dark_skin_tone:"],category:"people"},":woman_with_veil_tone5:":{uc_base:"1f470-1f3ff-2640",uc_full:"1f470-1f3ff-200d-2640-fe0f",shortnames:[":woman_with_veil_dark_skin_tone:"],category:"people"},":man_bouncing_ball_tone1:":{uc_base:"26f9-1f3fb-2642",uc_full:"26f9-1f3fb-200d-2642-fe0f",shortnames:[":man_bouncing_ball_light_skin_tone:"],category:"activity"},":man_bouncing_ball_tone2:":{uc_base:"26f9-1f3fc-2642",uc_full:"26f9-1f3fc-200d-2642-fe0f",shortnames:[":man_bouncing_ball_medium_light_skin_tone:"],category:"activity"},":man_bouncing_ball_tone3:":{uc_base:"26f9-1f3fd-2642",uc_full:"26f9-1f3fd-200d-2642-fe0f",shortnames:[":man_bouncing_ball_medium_skin_tone:"],category:"activity"},":man_bouncing_ball_tone4:":{uc_base:"26f9-1f3fe-2642",uc_full:"26f9-1f3fe-200d-2642-fe0f",shortnames:[":man_bouncing_ball_medium_dark_skin_tone:"],category:"activity"},":man_bouncing_ball_tone5:":{uc_base:"26f9-1f3ff-2642",uc_full:"26f9-1f3ff-200d-2642-fe0f",shortnames:[":man_bouncing_ball_dark_skin_tone:"],category:"activity"},":woman_bouncing_ball_tone1:":{uc_base:"26f9-1f3fb-2640",uc_full:"26f9-1f3fb-200d-2640-fe0f",shortnames:[":woman_bouncing_ball_light_skin_tone:"],category:"activity"},":woman_bouncing_ball_tone2:":{uc_base:"26f9-1f3fc-2640",uc_full:"26f9-1f3fc-200d-2640-fe0f",shortnames:[":woman_bouncing_ball_medium_light_skin_tone:"],category:"activity"},":woman_bouncing_ball_tone3:":{uc_base:"26f9-1f3fd-2640",uc_full:"26f9-1f3fd-200d-2640-fe0f",shortnames:[":woman_bouncing_ball_medium_skin_tone:"],category:"activity"},":woman_bouncing_ball_tone4:":{uc_base:"26f9-1f3fe-2640",uc_full:"26f9-1f3fe-200d-2640-fe0f",shortnames:[":woman_bouncing_ball_medium_dark_skin_tone:"],category:"activity"},":woman_bouncing_ball_tone5:":{uc_base:"26f9-1f3ff-2640",uc_full:"26f9-1f3ff-200d-2640-fe0f",shortnames:[":woman_bouncing_ball_dark_skin_tone:"],category:"activity"},":adult_tone1:":{uc_base:"1f9d1-1f3fb",uc_full:"1f9d1-1f3fb",shortnames:[":adult_light_skin_tone:"],category:"people"},":adult_tone2:":{uc_base:"1f9d1-1f3fc",uc_full:"1f9d1-1f3fc",shortnames:[":adult_medium_light_skin_tone:"],category:"people"},":adult_tone3:":{uc_base:"1f9d1-1f3fd",uc_full:"1f9d1-1f3fd",shortnames:[":adult_medium_skin_tone:"],category:"people"},":adult_tone4:":{uc_base:"1f9d1-1f3fe",uc_full:"1f9d1-1f3fe",shortnames:[":adult_medium_dark_skin_tone:"],category:"people"},":adult_tone5:":{uc_base:"1f9d1-1f3ff",uc_full:"1f9d1-1f3ff",shortnames:[":adult_dark_skin_tone:"],category:"people"},":angel_tone1:":{uc_base:"1f47c-1f3fb",uc_full:"1f47c-1f3fb",shortnames:[],category:"people"},":angel_tone2:":{uc_base:"1f47c-1f3fc",uc_full:"1f47c-1f3fc",shortnames:[],category:"people"},":angel_tone3:":{uc_base:"1f47c-1f3fd",uc_full:"1f47c-1f3fd",shortnames:[],category:"people"},":angel_tone4:":{uc_base:"1f47c-1f3fe",uc_full:"1f47c-1f3fe",shortnames:[],category:"people"},":angel_tone5:":{uc_base:"1f47c-1f3ff",uc_full:"1f47c-1f3ff",shortnames:[],category:"people"},":artist:":{uc_base:"1f9d1-1f3a8",uc_full:"1f9d1-200d-1f3a8",shortnames:[],category:"people"},":astronaut:":{uc_base:"1f9d1-1f680",uc_full:"1f9d1-200d-1f680",shortnames:[],category:"people"},":baby_tone1:":{uc_base:"1f476-1f3fb",uc_full:"1f476-1f3fb",shortnames:[],category:"people"},":baby_tone2:":{uc_base:"1f476-1f3fc",uc_full:"1f476-1f3fc",shortnames:[],category:"people"},":baby_tone3:":{uc_base:"1f476-1f3fd",uc_full:"1f476-1f3fd",shortnames:[],category:"people"},":baby_tone4:":{uc_base:"1f476-1f3fe",uc_full:"1f476-1f3fe",shortnames:[],category:"people"},":baby_tone5:":{uc_base:"1f476-1f3ff",uc_full:"1f476-1f3ff",shortnames:[],category:"people"},":bath_tone1:":{uc_base:"1f6c0-1f3fb",uc_full:"1f6c0-1f3fb",shortnames:[],category:"objects"},":bath_tone2:":{uc_base:"1f6c0-1f3fc",uc_full:"1f6c0-1f3fc",shortnames:[],category:"objects"},":bath_tone3:":{uc_base:"1f6c0-1f3fd",uc_full:"1f6c0-1f3fd",shortnames:[],category:"objects"},":bath_tone4:":{uc_base:"1f6c0-1f3fe",uc_full:"1f6c0-1f3fe",shortnames:[],category:"objects"},":bath_tone5:":{uc_base:"1f6c0-1f3ff",uc_full:"1f6c0-1f3ff",shortnames:[],category:"objects"},":bearded_person_tone1:":{uc_base:"1f9d4-1f3fb",uc_full:"1f9d4-1f3fb",shortnames:[":bearded_person_light_skin_tone:"],category:"people"},":bearded_person_tone2:":{uc_base:"1f9d4-1f3fc",uc_full:"1f9d4-1f3fc",shortnames:[":bearded_person_medium_light_skin_tone:"],category:"people"},":bearded_person_tone3:":{uc_base:"1f9d4-1f3fd",uc_full:"1f9d4-1f3fd",shortnames:[":bearded_person_medium_skin_tone:"],category:"people"},":bearded_person_tone4:":{uc_base:"1f9d4-1f3fe",uc_full:"1f9d4-1f3fe",shortnames:[":bearded_person_medium_dark_skin_tone:"],category:"people"},":bearded_person_tone5:":{uc_base:"1f9d4-1f3ff",uc_full:"1f9d4-1f3ff",shortnames:[":bearded_person_dark_skin_tone:"],category:"people"},":blond_haired_person_tone1:":{uc_base:"1f471-1f3fb",uc_full:"1f471-1f3fb",shortnames:[":person_with_blond_hair_tone1:"],category:"people"},":blond_haired_person_tone2:":{uc_base:"1f471-1f3fc",uc_full:"1f471-1f3fc",shortnames:[":person_with_blond_hair_tone2:"],category:"people"},":blond_haired_person_tone3:":{uc_base:"1f471-1f3fd",uc_full:"1f471-1f3fd",shortnames:[":person_with_blond_hair_tone3:"],category:"people"},":blond_haired_person_tone4:":{uc_base:"1f471-1f3fe",uc_full:"1f471-1f3fe",shortnames:[":person_with_blond_hair_tone4:"],category:"people"},":blond_haired_person_tone5:":{uc_base:"1f471-1f3ff",uc_full:"1f471-1f3ff",shortnames:[":person_with_blond_hair_tone5:"],category:"people"},":boy_tone1:":{uc_base:"1f466-1f3fb",uc_full:"1f466-1f3fb",shortnames:[],category:"people"},":boy_tone2:":{uc_base:"1f466-1f3fc",uc_full:"1f466-1f3fc",shortnames:[],category:"people"},":boy_tone3:":{uc_base:"1f466-1f3fd",uc_full:"1f466-1f3fd",shortnames:[],category:"people"},":boy_tone4:":{uc_base:"1f466-1f3fe",uc_full:"1f466-1f3fe",shortnames:[],category:"people"},":boy_tone5:":{uc_base:"1f466-1f3ff",uc_full:"1f466-1f3ff",shortnames:[],category:"people"},":breast_feeding_tone1:":{uc_base:"1f931-1f3fb",uc_full:"1f931-1f3fb",shortnames:[":breast_feeding_light_skin_tone:"],category:"people"},":breast_feeding_tone2:":{uc_base:"1f931-1f3fc",uc_full:"1f931-1f3fc",shortnames:[":breast_feeding_medium_light_skin_tone:"],category:"people"},":breast_feeding_tone3:":{uc_base:"1f931-1f3fd",uc_full:"1f931-1f3fd",shortnames:[":breast_feeding_medium_skin_tone:"],category:"people"},":breast_feeding_tone4:":{uc_base:"1f931-1f3fe",uc_full:"1f931-1f3fe",shortnames:[":breast_feeding_medium_dark_skin_tone:"],category:"people"},":breast_feeding_tone5:":{uc_base:"1f931-1f3ff",uc_full:"1f931-1f3ff",shortnames:[":breast_feeding_dark_skin_tone:"],category:"people"},":call_me_tone1:":{uc_base:"1f919-1f3fb",uc_full:"1f919-1f3fb",shortnames:[":call_me_hand_tone1:"],category:"people"},":call_me_tone2:":{uc_base:"1f919-1f3fc",uc_full:"1f919-1f3fc",shortnames:[":call_me_hand_tone2:"],category:"people"},":call_me_tone3:":{uc_base:"1f919-1f3fd",uc_full:"1f919-1f3fd",shortnames:[":call_me_hand_tone3:"],category:"people"},":call_me_tone4:":{uc_base:"1f919-1f3fe",uc_full:"1f919-1f3fe",shortnames:[":call_me_hand_tone4:"],category:"people"},":call_me_tone5:":{uc_base:"1f919-1f3ff",uc_full:"1f919-1f3ff",shortnames:[":call_me_hand_tone5:"],category:"people"},":child_tone1:":{uc_base:"1f9d2-1f3fb",uc_full:"1f9d2-1f3fb",shortnames:[":child_light_skin_tone:"],category:"people"},":child_tone2:":{uc_base:"1f9d2-1f3fc",uc_full:"1f9d2-1f3fc",shortnames:[":child_medium_light_skin_tone:"],category:"people"},":child_tone3:":{uc_base:"1f9d2-1f3fd",uc_full:"1f9d2-1f3fd",shortnames:[":child_medium_skin_tone:"],category:"people"},":child_tone4:":{uc_base:"1f9d2-1f3fe",uc_full:"1f9d2-1f3fe",shortnames:[":child_medium_dark_skin_tone:"],category:"people"},":child_tone5:":{uc_base:"1f9d2-1f3ff",uc_full:"1f9d2-1f3ff",shortnames:[":child_dark_skin_tone:"],category:"people"},":clap_tone1:":{uc_base:"1f44f-1f3fb",uc_full:"1f44f-1f3fb",shortnames:[],category:"people"},":clap_tone2:":{uc_base:"1f44f-1f3fc",uc_full:"1f44f-1f3fc",shortnames:[],category:"people"},":clap_tone3:":{uc_base:"1f44f-1f3fd",uc_full:"1f44f-1f3fd",shortnames:[],category:"people"},":clap_tone4:":{uc_base:"1f44f-1f3fe",uc_full:"1f44f-1f3fe",shortnames:[],category:"people"},":clap_tone5:":{uc_base:"1f44f-1f3ff",uc_full:"1f44f-1f3ff",shortnames:[],category:"people"},":construction_worker_tone1:":{uc_base:"1f477-1f3fb",uc_full:"1f477-1f3fb",shortnames:[],category:"people"},":construction_worker_tone2:":{uc_base:"1f477-1f3fc",uc_full:"1f477-1f3fc",shortnames:[],category:"people"},":construction_worker_tone3:":{uc_base:"1f477-1f3fd",uc_full:"1f477-1f3fd",shortnames:[],category:"people"},":construction_worker_tone4:":{uc_base:"1f477-1f3fe",uc_full:"1f477-1f3fe",shortnames:[],category:"people"},":construction_worker_tone5:":{uc_base:"1f477-1f3ff",uc_full:"1f477-1f3ff",shortnames:[],category:"people"},":cook:":{uc_base:"1f9d1-1f373",uc_full:"1f9d1-200d-1f373",shortnames:[],category:"people"},":couple_with_heart_tone1:":{uc_base:"1f491-1f3fb",uc_full:"1f491-1f3fb",shortnames:[":couple_with_heart_light_skin_tone:"],category:"people"},":couple_with_heart_tone2:":{uc_base:"1f491-1f3fc",uc_full:"1f491-1f3fc",shortnames:[":couple_with_heart_medium_light_skin_tone:"],category:"people"},":couple_with_heart_tone3:":{uc_base:"1f491-1f3fd",uc_full:"1f491-1f3fd",shortnames:[":couple_with_heart_medium_skin_tone:"],category:"people"},":couple_with_heart_tone4:":{uc_base:"1f491-1f3fe",uc_full:"1f491-1f3fe",shortnames:[":couple_with_heart_medium_dark_skin_tone:"],category:"people"},":couple_with_heart_tone5:":{uc_base:"1f491-1f3ff",uc_full:"1f491-1f3ff",shortnames:[":couple_with_heart_dark_skin_tone:"],category:"people"},":dancer_tone1:":{uc_base:"1f483-1f3fb",uc_full:"1f483-1f3fb",shortnames:[],category:"people"},":dancer_tone2:":{uc_base:"1f483-1f3fc",uc_full:"1f483-1f3fc",shortnames:[],category:"people"},":dancer_tone3:":{uc_base:"1f483-1f3fd",uc_full:"1f483-1f3fd",shortnames:[],category:"people"},":dancer_tone4:":{uc_base:"1f483-1f3fe",uc_full:"1f483-1f3fe",shortnames:[],category:"people"},":dancer_tone5:":{uc_base:"1f483-1f3ff",uc_full:"1f483-1f3ff",shortnames:[],category:"people"},":deaf_person_tone1:":{uc_base:"1f9cf-1f3fb",uc_full:"1f9cf-1f3fb",shortnames:[":deaf_person_light_skin_tone:"],category:"people"},":deaf_person_tone2:":{uc_base:"1f9cf-1f3fc",uc_full:"1f9cf-1f3fc",shortnames:[":deaf_person_medium_light_skin_tone:"],category:"people"},":deaf_person_tone3:":{uc_base:"1f9cf-1f3fd",uc_full:"1f9cf-1f3fd",shortnames:[":deaf_person_medium_skin_tone:"],category:"people"},":deaf_person_tone4:":{uc_base:"1f9cf-1f3fe",uc_full:"1f9cf-1f3fe",shortnames:[":deaf_person_medium_dark_skin_tone:"],category:"people"},":deaf_person_tone5:":{uc_base:"1f9cf-1f3ff",uc_full:"1f9cf-1f3ff",shortnames:[":deaf_person_dark_skin_tone:"],category:"people"},":detective_tone1:":{uc_base:"1f575-1f3fb",uc_full:"1f575-1f3fb",shortnames:[":spy_tone1:",":sleuth_or_spy_tone1:"],category:"people"},":detective_tone2:":{uc_base:"1f575-1f3fc",uc_full:"1f575-1f3fc",shortnames:[":spy_tone2:",":sleuth_or_spy_tone2:"],category:"people"},":detective_tone3:":{uc_base:"1f575-1f3fd",uc_full:"1f575-1f3fd",shortnames:[":spy_tone3:",":sleuth_or_spy_tone3:"],category:"people"},":detective_tone4:":{uc_base:"1f575-1f3fe",uc_full:"1f575-1f3fe",shortnames:[":spy_tone4:",":sleuth_or_spy_tone4:"],category:"people"},":detective_tone5:":{uc_base:"1f575-1f3ff",uc_full:"1f575-1f3ff",shortnames:[":spy_tone5:",":sleuth_or_spy_tone5:"],category:"people"},":ear_tone1:":{uc_base:"1f442-1f3fb",uc_full:"1f442-1f3fb",shortnames:[],category:"people"},":ear_tone2:":{uc_base:"1f442-1f3fc",uc_full:"1f442-1f3fc",shortnames:[],category:"people"},":ear_tone3:":{uc_base:"1f442-1f3fd",uc_full:"1f442-1f3fd",shortnames:[],category:"people"},":ear_tone4:":{uc_base:"1f442-1f3fe",uc_full:"1f442-1f3fe",shortnames:[],category:"people"},":ear_tone5:":{uc_base:"1f442-1f3ff",uc_full:"1f442-1f3ff",shortnames:[],category:"people"},":ear_with_hearing_aid_tone1:":{uc_base:"1f9bb-1f3fb",uc_full:"1f9bb-1f3fb",shortnames:[":ear_with_hearing_aid_light_skin_tone:"],category:"people"},":ear_with_hearing_aid_tone2:":{uc_base:"1f9bb-1f3fc",uc_full:"1f9bb-1f3fc",shortnames:[":ear_with_hearing_aid_medium_light_skin_tone:"],category:"people"},":ear_with_hearing_aid_tone3:":{uc_base:"1f9bb-1f3fd",uc_full:"1f9bb-1f3fd",shortnames:[":ear_with_hearing_aid_medium_skin_tone:"],category:"people"},":ear_with_hearing_aid_tone4:":{uc_base:"1f9bb-1f3fe",uc_full:"1f9bb-1f3fe",shortnames:[":ear_with_hearing_aid_medium_dark_skin_tone:"],category:"people"},":ear_with_hearing_aid_tone5:":{uc_base:"1f9bb-1f3ff",uc_full:"1f9bb-1f3ff",shortnames:[":ear_with_hearing_aid_dark_skin_tone:"],category:"people"},":elf_tone1:":{uc_base:"1f9dd-1f3fb",uc_full:"1f9dd-1f3fb",shortnames:[":elf_light_skin_tone:"],category:"people"},":elf_tone2:":{uc_base:"1f9dd-1f3fc",uc_full:"1f9dd-1f3fc",shortnames:[":elf_medium_light_skin_tone:"],category:"people"},":elf_tone3:":{uc_base:"1f9dd-1f3fd",uc_full:"1f9dd-1f3fd",shortnames:[":elf_medium_skin_tone:"],category:"people"},":elf_tone4:":{uc_base:"1f9dd-1f3fe",uc_full:"1f9dd-1f3fe",shortnames:[":elf_medium_dark_skin_tone:"],category:"people"},":elf_tone5:":{uc_base:"1f9dd-1f3ff",uc_full:"1f9dd-1f3ff",shortnames:[":elf_dark_skin_tone:"],category:"people"},":eye_in_speech_bubble:":{uc_base:"1f441-1f5e8",uc_full:"1f441-fe0f-200d-1f5e8-fe0f",shortnames:[],category:"symbols"},":face_exhaling:":{uc_base:"1f62e-1f4a8",uc_full:"1f62e-200d-1f4a8",shortnames:[],category:"people"},":face_in_clouds:":{uc_base:"1f636-1f32b",uc_full:"1f636-200d-1f32b-fe0f",shortnames:[],category:"people"},":face_with_spiral_eyes:":{uc_base:"1f635-1f4ab",uc_full:"1f635-200d-1f4ab",shortnames:[],category:"people"},":factory_worker:":{uc_base:"1f9d1-1f3ed",uc_full:"1f9d1-200d-1f3ed",shortnames:[],category:"people"},":fairy_tone1:":{uc_base:"1f9da-1f3fb",uc_full:"1f9da-1f3fb",shortnames:[":fairy_light_skin_tone:"],category:"people"},":fairy_tone2:":{uc_base:"1f9da-1f3fc",uc_full:"1f9da-1f3fc",shortnames:[":fairy_medium_light_skin_tone:"],category:"people"},":fairy_tone3:":{uc_base:"1f9da-1f3fd",uc_full:"1f9da-1f3fd",shortnames:[":fairy_medium_skin_tone:"],category:"people"},":fairy_tone4:":{uc_base:"1f9da-1f3fe",uc_full:"1f9da-1f3fe",shortnames:[":fairy_medium_dark_skin_tone:"],category:"people"},":fairy_tone5:":{uc_base:"1f9da-1f3ff",uc_full:"1f9da-1f3ff",shortnames:[":fairy_dark_skin_tone:"],category:"people"},":family_man_boy:":{uc_base:"1f468-1f466",uc_full:"1f468-200d-1f466",shortnames:[],category:"people"},":family_man_girl:":{uc_base:"1f468-1f467",uc_full:"1f468-200d-1f467",shortnames:[],category:"people"},":family_woman_boy:":{uc_base:"1f469-1f466",uc_full:"1f469-200d-1f466",shortnames:[],category:"people"},":family_woman_girl:":{uc_base:"1f469-1f467",uc_full:"1f469-200d-1f467",shortnames:[],category:"people"},":farmer:":{uc_base:"1f9d1-1f33e",uc_full:"1f9d1-200d-1f33e",shortnames:[],category:"people"},":fingers_crossed_tone1:":{uc_base:"1f91e-1f3fb",uc_full:"1f91e-1f3fb",shortnames:[":hand_with_index_and_middle_fingers_crossed_tone1:"],category:"people"},":fingers_crossed_tone2:":{uc_base:"1f91e-1f3fc",uc_full:"1f91e-1f3fc",shortnames:[":hand_with_index_and_middle_fingers_crossed_tone2:"],category:"people"},":fingers_crossed_tone3:":{uc_base:"1f91e-1f3fd",uc_full:"1f91e-1f3fd",shortnames:[":hand_with_index_and_middle_fingers_crossed_tone3:"],category:"people"},":fingers_crossed_tone4:":{uc_base:"1f91e-1f3fe",uc_full:"1f91e-1f3fe",shortnames:[":hand_with_index_and_middle_fingers_crossed_tone4:"],category:"people"},":fingers_crossed_tone5:":{uc_base:"1f91e-1f3ff",uc_full:"1f91e-1f3ff",shortnames:[":hand_with_index_and_middle_fingers_crossed_tone5:"],category:"people"},":firefighter:":{uc_base:"1f9d1-1f692",uc_full:"1f9d1-200d-1f692",shortnames:[],category:"people"},":flag_ac:":{uc_base:"1f1e6-1f1e8",uc_full:"1f1e6-1f1e8",shortnames:[":ac:"],category:"flags"},":flag_ad:":{uc_base:"1f1e6-1f1e9",uc_full:"1f1e6-1f1e9",shortnames:[":ad:"],category:"flags"},":flag_ae:":{uc_base:"1f1e6-1f1ea",uc_full:"1f1e6-1f1ea",shortnames:[":ae:"],category:"flags"},":flag_af:":{uc_base:"1f1e6-1f1eb",uc_full:"1f1e6-1f1eb",shortnames:[":af:"],category:"flags"},":flag_ag:":{uc_base:"1f1e6-1f1ec",uc_full:"1f1e6-1f1ec",shortnames:[":ag:"],category:"flags"},":flag_ai:":{uc_base:"1f1e6-1f1ee",uc_full:"1f1e6-1f1ee",shortnames:[":ai:"],category:"flags"},":flag_al:":{uc_base:"1f1e6-1f1f1",uc_full:"1f1e6-1f1f1",shortnames:[":al:"],category:"flags"},":flag_am:":{uc_base:"1f1e6-1f1f2",uc_full:"1f1e6-1f1f2",shortnames:[":am:"],category:"flags"},":flag_ao:":{uc_base:"1f1e6-1f1f4",uc_full:"1f1e6-1f1f4",shortnames:[":ao:"],category:"flags"},":flag_aq:":{uc_base:"1f1e6-1f1f6",uc_full:"1f1e6-1f1f6",shortnames:[":aq:"],category:"flags"},":flag_ar:":{uc_base:"1f1e6-1f1f7",uc_full:"1f1e6-1f1f7",shortnames:[":ar:"],category:"flags"},":flag_as:":{uc_base:"1f1e6-1f1f8",uc_full:"1f1e6-1f1f8",shortnames:[":as:"],category:"flags"},":flag_at:":{uc_base:"1f1e6-1f1f9",uc_full:"1f1e6-1f1f9",shortnames:[":at:"],category:"flags"},":flag_au:":{uc_base:"1f1e6-1f1fa",uc_full:"1f1e6-1f1fa",shortnames:[":au:"],category:"flags"},":flag_aw:":{uc_base:"1f1e6-1f1fc",uc_full:"1f1e6-1f1fc",shortnames:[":aw:"],category:"flags"},":flag_ax:":{uc_base:"1f1e6-1f1fd",uc_full:"1f1e6-1f1fd",shortnames:[":ax:"],category:"flags"},":flag_az:":{uc_base:"1f1e6-1f1ff",uc_full:"1f1e6-1f1ff",shortnames:[":az:"],category:"flags"},":flag_ba:":{uc_base:"1f1e7-1f1e6",uc_full:"1f1e7-1f1e6",shortnames:[":ba:"],category:"flags"},":flag_bb:":{uc_base:"1f1e7-1f1e7",uc_full:"1f1e7-1f1e7",shortnames:[":bb:"],category:"flags"},":flag_bd:":{uc_base:"1f1e7-1f1e9",uc_full:"1f1e7-1f1e9",shortnames:[":bd:"],category:"flags"},":flag_be:":{uc_base:"1f1e7-1f1ea",uc_full:"1f1e7-1f1ea",shortnames:[":be:"],category:"flags"},":flag_bf:":{uc_base:"1f1e7-1f1eb",uc_full:"1f1e7-1f1eb",shortnames:[":bf:"],category:"flags"},":flag_bg:":{uc_base:"1f1e7-1f1ec",uc_full:"1f1e7-1f1ec",shortnames:[":bg:"],category:"flags"},":flag_bh:":{uc_base:"1f1e7-1f1ed",uc_full:"1f1e7-1f1ed",shortnames:[":bh:"],category:"flags"},":flag_bi:":{uc_base:"1f1e7-1f1ee",uc_full:"1f1e7-1f1ee",shortnames:[":bi:"],category:"flags"},":flag_bj:":{uc_base:"1f1e7-1f1ef",uc_full:"1f1e7-1f1ef",shortnames:[":bj:"],category:"flags"},":flag_bl:":{uc_base:"1f1e7-1f1f1",uc_full:"1f1e7-1f1f1",shortnames:[":bl:"],category:"flags"},":flag_bm:":{uc_base:"1f1e7-1f1f2",uc_full:"1f1e7-1f1f2",shortnames:[":bm:"],category:"flags"},":flag_bn:":{uc_base:"1f1e7-1f1f3",uc_full:"1f1e7-1f1f3",shortnames:[":bn:"],category:"flags"},":flag_bo:":{uc_base:"1f1e7-1f1f4",uc_full:"1f1e7-1f1f4",shortnames:[":bo:"],category:"flags"},":flag_bq:":{uc_base:"1f1e7-1f1f6",uc_full:"1f1e7-1f1f6",shortnames:[":bq:"],category:"flags"},":flag_br:":{uc_base:"1f1e7-1f1f7",uc_full:"1f1e7-1f1f7",shortnames:[":br:"],category:"flags"},":flag_bs:":{uc_base:"1f1e7-1f1f8",uc_full:"1f1e7-1f1f8",shortnames:[":bs:"],category:"flags"},":flag_bt:":{uc_base:"1f1e7-1f1f9",uc_full:"1f1e7-1f1f9",shortnames:[":bt:"],category:"flags"},":flag_bv:":{uc_base:"1f1e7-1f1fb",uc_full:"1f1e7-1f1fb",shortnames:[":bv:"],category:"flags"},":flag_bw:":{uc_base:"1f1e7-1f1fc",uc_full:"1f1e7-1f1fc",shortnames:[":bw:"],category:"flags"},":flag_by:":{uc_base:"1f1e7-1f1fe",uc_full:"1f1e7-1f1fe",shortnames:[":by:"],category:"flags"},":flag_bz:":{uc_base:"1f1e7-1f1ff",uc_full:"1f1e7-1f1ff",shortnames:[":bz:"],category:"flags"},":flag_ca:":{uc_base:"1f1e8-1f1e6",uc_full:"1f1e8-1f1e6",shortnames:[":ca:"],category:"flags"},":flag_cc:":{uc_base:"1f1e8-1f1e8",uc_full:"1f1e8-1f1e8",shortnames:[":cc:"],category:"flags"},":flag_cd:":{uc_base:"1f1e8-1f1e9",uc_full:"1f1e8-1f1e9",shortnames:[":congo:"],category:"flags"},":flag_cf:":{uc_base:"1f1e8-1f1eb",uc_full:"1f1e8-1f1eb",shortnames:[":cf:"],category:"flags"},":flag_cg:":{uc_base:"1f1e8-1f1ec",uc_full:"1f1e8-1f1ec",shortnames:[":cg:"],category:"flags"},":flag_ch:":{uc_base:"1f1e8-1f1ed",uc_full:"1f1e8-1f1ed",shortnames:[":ch:"],category:"flags"},":flag_ci:":{uc_base:"1f1e8-1f1ee",uc_full:"1f1e8-1f1ee",shortnames:[":ci:"],category:"flags"},":flag_ck:":{uc_base:"1f1e8-1f1f0",uc_full:"1f1e8-1f1f0",shortnames:[":ck:"],category:"flags"},":flag_cl:":{uc_base:"1f1e8-1f1f1",uc_full:"1f1e8-1f1f1",shortnames:[":chile:"],category:"flags"},":flag_cm:":{uc_base:"1f1e8-1f1f2",uc_full:"1f1e8-1f1f2",shortnames:[":cm:"],category:"flags"},":flag_cn:":{uc_base:"1f1e8-1f1f3",uc_full:"1f1e8-1f1f3",shortnames:[":cn:"],category:"flags"},":flag_co:":{uc_base:"1f1e8-1f1f4",uc_full:"1f1e8-1f1f4",shortnames:[":co:"],category:"flags"},":flag_cp:":{uc_base:"1f1e8-1f1f5",uc_full:"1f1e8-1f1f5",shortnames:[":cp:"],category:"flags"},":flag_cr:":{uc_base:"1f1e8-1f1f7",uc_full:"1f1e8-1f1f7",shortnames:[":cr:"],category:"flags"},":flag_cu:":{uc_base:"1f1e8-1f1fa",uc_full:"1f1e8-1f1fa",shortnames:[":cu:"],category:"flags"},":flag_cv:":{uc_base:"1f1e8-1f1fb",uc_full:"1f1e8-1f1fb",shortnames:[":cv:"],category:"flags"},":flag_cw:":{uc_base:"1f1e8-1f1fc",uc_full:"1f1e8-1f1fc",shortnames:[":cw:"],category:"flags"},":flag_cx:":{uc_base:"1f1e8-1f1fd",uc_full:"1f1e8-1f1fd",shortnames:[":cx:"],category:"flags"},":flag_cy:":{uc_base:"1f1e8-1f1fe",uc_full:"1f1e8-1f1fe",shortnames:[":cy:"],category:"flags"},":flag_cz:":{uc_base:"1f1e8-1f1ff",uc_full:"1f1e8-1f1ff",shortnames:[":cz:"],category:"flags"},":flag_de:":{uc_base:"1f1e9-1f1ea",uc_full:"1f1e9-1f1ea",shortnames:[":de:"],category:"flags"},":flag_dg:":{uc_base:"1f1e9-1f1ec",uc_full:"1f1e9-1f1ec",shortnames:[":dg:"],category:"flags"},":flag_dj:":{uc_base:"1f1e9-1f1ef",uc_full:"1f1e9-1f1ef",shortnames:[":dj:"],category:"flags"},":flag_dk:":{uc_base:"1f1e9-1f1f0",uc_full:"1f1e9-1f1f0",shortnames:[":dk:"],category:"flags"},":flag_dm:":{uc_base:"1f1e9-1f1f2",uc_full:"1f1e9-1f1f2",shortnames:[":dm:"],category:"flags"},":flag_do:":{uc_base:"1f1e9-1f1f4",uc_full:"1f1e9-1f1f4",shortnames:[":do:"],category:"flags"},":flag_dz:":{uc_base:"1f1e9-1f1ff",uc_full:"1f1e9-1f1ff",shortnames:[":dz:"],category:"flags"},":flag_ea:":{uc_base:"1f1ea-1f1e6",uc_full:"1f1ea-1f1e6",shortnames:[":ea:"],category:"flags"},":flag_ec:":{uc_base:"1f1ea-1f1e8",uc_full:"1f1ea-1f1e8",shortnames:[":ec:"],category:"flags"},":flag_ee:":{uc_base:"1f1ea-1f1ea",uc_full:"1f1ea-1f1ea",shortnames:[":ee:"],category:"flags"},":flag_eg:":{uc_base:"1f1ea-1f1ec",uc_full:"1f1ea-1f1ec",shortnames:[":eg:"],category:"flags"},":flag_eh:":{uc_base:"1f1ea-1f1ed",uc_full:"1f1ea-1f1ed",shortnames:[":eh:"],category:"flags"},":flag_er:":{uc_base:"1f1ea-1f1f7",uc_full:"1f1ea-1f1f7",shortnames:[":er:"],category:"flags"},":flag_es:":{uc_base:"1f1ea-1f1f8",uc_full:"1f1ea-1f1f8",shortnames:[":es:"],category:"flags"},":flag_et:":{uc_base:"1f1ea-1f1f9",uc_full:"1f1ea-1f1f9",shortnames:[":et:"],category:"flags"},":flag_eu:":{uc_base:"1f1ea-1f1fa",uc_full:"1f1ea-1f1fa",shortnames:[":eu:"],category:"flags"},":flag_fi:":{uc_base:"1f1eb-1f1ee",uc_full:"1f1eb-1f1ee",shortnames:[":fi:"],category:"flags"},":flag_fj:":{uc_base:"1f1eb-1f1ef",uc_full:"1f1eb-1f1ef",shortnames:[":fj:"],category:"flags"},":flag_fk:":{uc_base:"1f1eb-1f1f0",uc_full:"1f1eb-1f1f0",shortnames:[":fk:"],category:"flags"},":flag_fm:":{uc_base:"1f1eb-1f1f2",uc_full:"1f1eb-1f1f2",shortnames:[":fm:"],category:"flags"},":flag_fo:":{uc_base:"1f1eb-1f1f4",uc_full:"1f1eb-1f1f4",shortnames:[":fo:"],category:"flags"},":flag_fr:":{uc_base:"1f1eb-1f1f7",uc_full:"1f1eb-1f1f7",shortnames:[":fr:"],category:"flags"},":flag_ga:":{uc_base:"1f1ec-1f1e6",uc_full:"1f1ec-1f1e6",shortnames:[":ga:"],category:"flags"},":flag_gb:":{uc_base:"1f1ec-1f1e7",uc_full:"1f1ec-1f1e7",shortnames:[":gb:"],category:"flags"},":flag_gd:":{uc_base:"1f1ec-1f1e9",uc_full:"1f1ec-1f1e9",shortnames:[":gd:"],category:"flags"},":flag_ge:":{uc_base:"1f1ec-1f1ea",uc_full:"1f1ec-1f1ea",shortnames:[":ge:"],category:"flags"},":flag_gf:":{uc_base:"1f1ec-1f1eb",uc_full:"1f1ec-1f1eb",shortnames:[":gf:"],category:"flags"},":flag_gg:":{uc_base:"1f1ec-1f1ec",uc_full:"1f1ec-1f1ec",shortnames:[":gg:"],category:"flags"},":flag_gh:":{uc_base:"1f1ec-1f1ed",uc_full:"1f1ec-1f1ed",shortnames:[":gh:"],category:"flags"},":flag_gi:":{uc_base:"1f1ec-1f1ee",uc_full:"1f1ec-1f1ee",shortnames:[":gi:"],category:"flags"},":flag_gl:":{uc_base:"1f1ec-1f1f1",uc_full:"1f1ec-1f1f1",shortnames:[":gl:"],category:"flags"},":flag_gm:":{uc_base:"1f1ec-1f1f2",uc_full:"1f1ec-1f1f2",shortnames:[":gm:"],category:"flags"},":flag_gn:":{uc_base:"1f1ec-1f1f3",uc_full:"1f1ec-1f1f3",shortnames:[":gn:"],category:"flags"},":flag_gp:":{uc_base:"1f1ec-1f1f5",uc_full:"1f1ec-1f1f5",shortnames:[":gp:"],category:"flags"},":flag_gq:":{uc_base:"1f1ec-1f1f6",uc_full:"1f1ec-1f1f6",shortnames:[":gq:"],category:"flags"},":flag_gr:":{uc_base:"1f1ec-1f1f7",uc_full:"1f1ec-1f1f7",shortnames:[":gr:"],category:"flags"},":flag_gs:":{uc_base:"1f1ec-1f1f8",uc_full:"1f1ec-1f1f8",shortnames:[":gs:"],category:"flags"},":flag_gt:":{uc_base:"1f1ec-1f1f9",uc_full:"1f1ec-1f1f9",shortnames:[":gt:"],category:"flags"},":flag_gu:":{uc_base:"1f1ec-1f1fa",uc_full:"1f1ec-1f1fa",shortnames:[":gu:"],category:"flags"},":flag_gw:":{uc_base:"1f1ec-1f1fc",uc_full:"1f1ec-1f1fc",shortnames:[":gw:"],category:"flags"},":flag_gy:":{uc_base:"1f1ec-1f1fe",uc_full:"1f1ec-1f1fe",shortnames:[":gy:"],category:"flags"}, -":flag_hk:":{uc_base:"1f1ed-1f1f0",uc_full:"1f1ed-1f1f0",shortnames:[":hk:"],category:"flags"},":flag_hm:":{uc_base:"1f1ed-1f1f2",uc_full:"1f1ed-1f1f2",shortnames:[":hm:"],category:"flags"},":flag_hn:":{uc_base:"1f1ed-1f1f3",uc_full:"1f1ed-1f1f3",shortnames:[":hn:"],category:"flags"},":flag_hr:":{uc_base:"1f1ed-1f1f7",uc_full:"1f1ed-1f1f7",shortnames:[":hr:"],category:"flags"},":flag_ht:":{uc_base:"1f1ed-1f1f9",uc_full:"1f1ed-1f1f9",shortnames:[":ht:"],category:"flags"},":flag_hu:":{uc_base:"1f1ed-1f1fa",uc_full:"1f1ed-1f1fa",shortnames:[":hu:"],category:"flags"},":flag_ic:":{uc_base:"1f1ee-1f1e8",uc_full:"1f1ee-1f1e8",shortnames:[":ic:"],category:"flags"},":flag_id:":{uc_base:"1f1ee-1f1e9",uc_full:"1f1ee-1f1e9",shortnames:[":indonesia:"],category:"flags"},":flag_ie:":{uc_base:"1f1ee-1f1ea",uc_full:"1f1ee-1f1ea",shortnames:[":ie:"],category:"flags"},":flag_il:":{uc_base:"1f1ee-1f1f1",uc_full:"1f1ee-1f1f1",shortnames:[":il:"],category:"flags"},":flag_im:":{uc_base:"1f1ee-1f1f2",uc_full:"1f1ee-1f1f2",shortnames:[":im:"],category:"flags"},":flag_in:":{uc_base:"1f1ee-1f1f3",uc_full:"1f1ee-1f1f3",shortnames:[":in:"],category:"flags"},":flag_io:":{uc_base:"1f1ee-1f1f4",uc_full:"1f1ee-1f1f4",shortnames:[":io:"],category:"flags"},":flag_iq:":{uc_base:"1f1ee-1f1f6",uc_full:"1f1ee-1f1f6",shortnames:[":iq:"],category:"flags"},":flag_ir:":{uc_base:"1f1ee-1f1f7",uc_full:"1f1ee-1f1f7",shortnames:[":ir:"],category:"flags"},":flag_is:":{uc_base:"1f1ee-1f1f8",uc_full:"1f1ee-1f1f8",shortnames:[":is:"],category:"flags"},":flag_it:":{uc_base:"1f1ee-1f1f9",uc_full:"1f1ee-1f1f9",shortnames:[":it:"],category:"flags"},":flag_je:":{uc_base:"1f1ef-1f1ea",uc_full:"1f1ef-1f1ea",shortnames:[":je:"],category:"flags"},":flag_jm:":{uc_base:"1f1ef-1f1f2",uc_full:"1f1ef-1f1f2",shortnames:[":jm:"],category:"flags"},":flag_jo:":{uc_base:"1f1ef-1f1f4",uc_full:"1f1ef-1f1f4",shortnames:[":jo:"],category:"flags"},":flag_jp:":{uc_base:"1f1ef-1f1f5",uc_full:"1f1ef-1f1f5",shortnames:[":jp:"],category:"flags"},":flag_ke:":{uc_base:"1f1f0-1f1ea",uc_full:"1f1f0-1f1ea",shortnames:[":ke:"],category:"flags"},":flag_kg:":{uc_base:"1f1f0-1f1ec",uc_full:"1f1f0-1f1ec",shortnames:[":kg:"],category:"flags"},":flag_kh:":{uc_base:"1f1f0-1f1ed",uc_full:"1f1f0-1f1ed",shortnames:[":kh:"],category:"flags"},":flag_ki:":{uc_base:"1f1f0-1f1ee",uc_full:"1f1f0-1f1ee",shortnames:[":ki:"],category:"flags"},":flag_km:":{uc_base:"1f1f0-1f1f2",uc_full:"1f1f0-1f1f2",shortnames:[":km:"],category:"flags"},":flag_kn:":{uc_base:"1f1f0-1f1f3",uc_full:"1f1f0-1f1f3",shortnames:[":kn:"],category:"flags"},":flag_kp:":{uc_base:"1f1f0-1f1f5",uc_full:"1f1f0-1f1f5",shortnames:[":kp:"],category:"flags"},":flag_kr:":{uc_base:"1f1f0-1f1f7",uc_full:"1f1f0-1f1f7",shortnames:[":kr:"],category:"flags"},":flag_kw:":{uc_base:"1f1f0-1f1fc",uc_full:"1f1f0-1f1fc",shortnames:[":kw:"],category:"flags"},":flag_ky:":{uc_base:"1f1f0-1f1fe",uc_full:"1f1f0-1f1fe",shortnames:[":ky:"],category:"flags"},":flag_kz:":{uc_base:"1f1f0-1f1ff",uc_full:"1f1f0-1f1ff",shortnames:[":kz:"],category:"flags"},":flag_la:":{uc_base:"1f1f1-1f1e6",uc_full:"1f1f1-1f1e6",shortnames:[":la:"],category:"flags"},":flag_lb:":{uc_base:"1f1f1-1f1e7",uc_full:"1f1f1-1f1e7",shortnames:[":lb:"],category:"flags"},":flag_lc:":{uc_base:"1f1f1-1f1e8",uc_full:"1f1f1-1f1e8",shortnames:[":lc:"],category:"flags"},":flag_li:":{uc_base:"1f1f1-1f1ee",uc_full:"1f1f1-1f1ee",shortnames:[":li:"],category:"flags"},":flag_lk:":{uc_base:"1f1f1-1f1f0",uc_full:"1f1f1-1f1f0",shortnames:[":lk:"],category:"flags"},":flag_lr:":{uc_base:"1f1f1-1f1f7",uc_full:"1f1f1-1f1f7",shortnames:[":lr:"],category:"flags"},":flag_ls:":{uc_base:"1f1f1-1f1f8",uc_full:"1f1f1-1f1f8",shortnames:[":ls:"],category:"flags"},":flag_lt:":{uc_base:"1f1f1-1f1f9",uc_full:"1f1f1-1f1f9",shortnames:[":lt:"],category:"flags"},":flag_lu:":{uc_base:"1f1f1-1f1fa",uc_full:"1f1f1-1f1fa",shortnames:[":lu:"],category:"flags"},":flag_lv:":{uc_base:"1f1f1-1f1fb",uc_full:"1f1f1-1f1fb",shortnames:[":lv:"],category:"flags"},":flag_ly:":{uc_base:"1f1f1-1f1fe",uc_full:"1f1f1-1f1fe",shortnames:[":ly:"],category:"flags"},":flag_ma:":{uc_base:"1f1f2-1f1e6",uc_full:"1f1f2-1f1e6",shortnames:[":ma:"],category:"flags"},":flag_mc:":{uc_base:"1f1f2-1f1e8",uc_full:"1f1f2-1f1e8",shortnames:[":mc:"],category:"flags"},":flag_md:":{uc_base:"1f1f2-1f1e9",uc_full:"1f1f2-1f1e9",shortnames:[":md:"],category:"flags"},":flag_me:":{uc_base:"1f1f2-1f1ea",uc_full:"1f1f2-1f1ea",shortnames:[":me:"],category:"flags"},":flag_mf:":{uc_base:"1f1f2-1f1eb",uc_full:"1f1f2-1f1eb",shortnames:[":mf:"],category:"flags"},":flag_mg:":{uc_base:"1f1f2-1f1ec",uc_full:"1f1f2-1f1ec",shortnames:[":mg:"],category:"flags"},":flag_mh:":{uc_base:"1f1f2-1f1ed",uc_full:"1f1f2-1f1ed",shortnames:[":mh:"],category:"flags"},":flag_mk:":{uc_base:"1f1f2-1f1f0",uc_full:"1f1f2-1f1f0",shortnames:[":mk:"],category:"flags"},":flag_ml:":{uc_base:"1f1f2-1f1f1",uc_full:"1f1f2-1f1f1",shortnames:[":ml:"],category:"flags"},":flag_mm:":{uc_base:"1f1f2-1f1f2",uc_full:"1f1f2-1f1f2",shortnames:[":mm:"],category:"flags"},":flag_mn:":{uc_base:"1f1f2-1f1f3",uc_full:"1f1f2-1f1f3",shortnames:[":mn:"],category:"flags"},":flag_mo:":{uc_base:"1f1f2-1f1f4",uc_full:"1f1f2-1f1f4",shortnames:[":mo:"],category:"flags"},":flag_mp:":{uc_base:"1f1f2-1f1f5",uc_full:"1f1f2-1f1f5",shortnames:[":mp:"],category:"flags"},":flag_mq:":{uc_base:"1f1f2-1f1f6",uc_full:"1f1f2-1f1f6",shortnames:[":mq:"],category:"flags"},":flag_mr:":{uc_base:"1f1f2-1f1f7",uc_full:"1f1f2-1f1f7",shortnames:[":mr:"],category:"flags"},":flag_ms:":{uc_base:"1f1f2-1f1f8",uc_full:"1f1f2-1f1f8",shortnames:[":ms:"],category:"flags"},":flag_mt:":{uc_base:"1f1f2-1f1f9",uc_full:"1f1f2-1f1f9",shortnames:[":mt:"],category:"flags"},":flag_mu:":{uc_base:"1f1f2-1f1fa",uc_full:"1f1f2-1f1fa",shortnames:[":mu:"],category:"flags"},":flag_mv:":{uc_base:"1f1f2-1f1fb",uc_full:"1f1f2-1f1fb",shortnames:[":mv:"],category:"flags"},":flag_mw:":{uc_base:"1f1f2-1f1fc",uc_full:"1f1f2-1f1fc",shortnames:[":mw:"],category:"flags"},":flag_mx:":{uc_base:"1f1f2-1f1fd",uc_full:"1f1f2-1f1fd",shortnames:[":mx:"],category:"flags"},":flag_my:":{uc_base:"1f1f2-1f1fe",uc_full:"1f1f2-1f1fe",shortnames:[":my:"],category:"flags"},":flag_mz:":{uc_base:"1f1f2-1f1ff",uc_full:"1f1f2-1f1ff",shortnames:[":mz:"],category:"flags"},":flag_na:":{uc_base:"1f1f3-1f1e6",uc_full:"1f1f3-1f1e6",shortnames:[":na:"],category:"flags"},":flag_nc:":{uc_base:"1f1f3-1f1e8",uc_full:"1f1f3-1f1e8",shortnames:[":nc:"],category:"flags"},":flag_ne:":{uc_base:"1f1f3-1f1ea",uc_full:"1f1f3-1f1ea",shortnames:[":ne:"],category:"flags"},":flag_nf:":{uc_base:"1f1f3-1f1eb",uc_full:"1f1f3-1f1eb",shortnames:[":nf:"],category:"flags"},":flag_ng:":{uc_base:"1f1f3-1f1ec",uc_full:"1f1f3-1f1ec",shortnames:[":nigeria:"],category:"flags"},":flag_ni:":{uc_base:"1f1f3-1f1ee",uc_full:"1f1f3-1f1ee",shortnames:[":ni:"],category:"flags"},":flag_nl:":{uc_base:"1f1f3-1f1f1",uc_full:"1f1f3-1f1f1",shortnames:[":nl:"],category:"flags"},":flag_no:":{uc_base:"1f1f3-1f1f4",uc_full:"1f1f3-1f1f4",shortnames:[":no:"],category:"flags"},":flag_np:":{uc_base:"1f1f3-1f1f5",uc_full:"1f1f3-1f1f5",shortnames:[":np:"],category:"flags"},":flag_nr:":{uc_base:"1f1f3-1f1f7",uc_full:"1f1f3-1f1f7",shortnames:[":nr:"],category:"flags"},":flag_nu:":{uc_base:"1f1f3-1f1fa",uc_full:"1f1f3-1f1fa",shortnames:[":nu:"],category:"flags"},":flag_nz:":{uc_base:"1f1f3-1f1ff",uc_full:"1f1f3-1f1ff",shortnames:[":nz:"],category:"flags"},":flag_om:":{uc_base:"1f1f4-1f1f2",uc_full:"1f1f4-1f1f2",shortnames:[":om:"],category:"flags"},":flag_pa:":{uc_base:"1f1f5-1f1e6",uc_full:"1f1f5-1f1e6",shortnames:[":pa:"],category:"flags"},":flag_pe:":{uc_base:"1f1f5-1f1ea",uc_full:"1f1f5-1f1ea",shortnames:[":pe:"],category:"flags"},":flag_pf:":{uc_base:"1f1f5-1f1eb",uc_full:"1f1f5-1f1eb",shortnames:[":pf:"],category:"flags"},":flag_pg:":{uc_base:"1f1f5-1f1ec",uc_full:"1f1f5-1f1ec",shortnames:[":pg:"],category:"flags"},":flag_ph:":{uc_base:"1f1f5-1f1ed",uc_full:"1f1f5-1f1ed",shortnames:[":ph:"],category:"flags"},":flag_pk:":{uc_base:"1f1f5-1f1f0",uc_full:"1f1f5-1f1f0",shortnames:[":pk:"],category:"flags"},":flag_pl:":{uc_base:"1f1f5-1f1f1",uc_full:"1f1f5-1f1f1",shortnames:[":pl:"],category:"flags"},":flag_pm:":{uc_base:"1f1f5-1f1f2",uc_full:"1f1f5-1f1f2",shortnames:[":pm:"],category:"flags"},":flag_pn:":{uc_base:"1f1f5-1f1f3",uc_full:"1f1f5-1f1f3",shortnames:[":pn:"],category:"flags"},":flag_pr:":{uc_base:"1f1f5-1f1f7",uc_full:"1f1f5-1f1f7",shortnames:[":pr:"],category:"flags"},":flag_ps:":{uc_base:"1f1f5-1f1f8",uc_full:"1f1f5-1f1f8",shortnames:[":ps:"],category:"flags"},":flag_pt:":{uc_base:"1f1f5-1f1f9",uc_full:"1f1f5-1f1f9",shortnames:[":pt:"],category:"flags"},":flag_pw:":{uc_base:"1f1f5-1f1fc",uc_full:"1f1f5-1f1fc",shortnames:[":pw:"],category:"flags"},":flag_py:":{uc_base:"1f1f5-1f1fe",uc_full:"1f1f5-1f1fe",shortnames:[":py:"],category:"flags"},":flag_qa:":{uc_base:"1f1f6-1f1e6",uc_full:"1f1f6-1f1e6",shortnames:[":qa:"],category:"flags"},":flag_re:":{uc_base:"1f1f7-1f1ea",uc_full:"1f1f7-1f1ea",shortnames:[":re:"],category:"flags"},":flag_ro:":{uc_base:"1f1f7-1f1f4",uc_full:"1f1f7-1f1f4",shortnames:[":ro:"],category:"flags"},":flag_rs:":{uc_base:"1f1f7-1f1f8",uc_full:"1f1f7-1f1f8",shortnames:[":rs:"],category:"flags"},":flag_ru:":{uc_base:"1f1f7-1f1fa",uc_full:"1f1f7-1f1fa",shortnames:[":ru:"],category:"flags"},":flag_rw:":{uc_base:"1f1f7-1f1fc",uc_full:"1f1f7-1f1fc",shortnames:[":rw:"],category:"flags"},":flag_sa:":{uc_base:"1f1f8-1f1e6",uc_full:"1f1f8-1f1e6",shortnames:[":saudiarabia:",":saudi:"],category:"flags"},":flag_sb:":{uc_base:"1f1f8-1f1e7",uc_full:"1f1f8-1f1e7",shortnames:[":sb:"],category:"flags"},":flag_sc:":{uc_base:"1f1f8-1f1e8",uc_full:"1f1f8-1f1e8",shortnames:[":sc:"],category:"flags"},":flag_sd:":{uc_base:"1f1f8-1f1e9",uc_full:"1f1f8-1f1e9",shortnames:[":sd:"],category:"flags"},":flag_se:":{uc_base:"1f1f8-1f1ea",uc_full:"1f1f8-1f1ea",shortnames:[":se:"],category:"flags"},":flag_sg:":{uc_base:"1f1f8-1f1ec",uc_full:"1f1f8-1f1ec",shortnames:[":sg:"],category:"flags"},":flag_sh:":{uc_base:"1f1f8-1f1ed",uc_full:"1f1f8-1f1ed",shortnames:[":sh:"],category:"flags"},":flag_si:":{uc_base:"1f1f8-1f1ee",uc_full:"1f1f8-1f1ee",shortnames:[":si:"],category:"flags"},":flag_sj:":{uc_base:"1f1f8-1f1ef",uc_full:"1f1f8-1f1ef",shortnames:[":sj:"],category:"flags"},":flag_sk:":{uc_base:"1f1f8-1f1f0",uc_full:"1f1f8-1f1f0",shortnames:[":sk:"],category:"flags"},":flag_sl:":{uc_base:"1f1f8-1f1f1",uc_full:"1f1f8-1f1f1",shortnames:[":sl:"],category:"flags"},":flag_sm:":{uc_base:"1f1f8-1f1f2",uc_full:"1f1f8-1f1f2",shortnames:[":sm:"],category:"flags"},":flag_sn:":{uc_base:"1f1f8-1f1f3",uc_full:"1f1f8-1f1f3",shortnames:[":sn:"],category:"flags"},":flag_so:":{uc_base:"1f1f8-1f1f4",uc_full:"1f1f8-1f1f4",shortnames:[":so:"],category:"flags"},":flag_sr:":{uc_base:"1f1f8-1f1f7",uc_full:"1f1f8-1f1f7",shortnames:[":sr:"],category:"flags"},":flag_ss:":{uc_base:"1f1f8-1f1f8",uc_full:"1f1f8-1f1f8",shortnames:[":ss:"],category:"flags"},":flag_st:":{uc_base:"1f1f8-1f1f9",uc_full:"1f1f8-1f1f9",shortnames:[":st:"],category:"flags"},":flag_sv:":{uc_base:"1f1f8-1f1fb",uc_full:"1f1f8-1f1fb",shortnames:[":sv:"],category:"flags"},":flag_sx:":{uc_base:"1f1f8-1f1fd",uc_full:"1f1f8-1f1fd",shortnames:[":sx:"],category:"flags"},":flag_sy:":{uc_base:"1f1f8-1f1fe",uc_full:"1f1f8-1f1fe",shortnames:[":sy:"],category:"flags"},":flag_sz:":{uc_base:"1f1f8-1f1ff",uc_full:"1f1f8-1f1ff",shortnames:[":sz:"],category:"flags"},":flag_ta:":{uc_base:"1f1f9-1f1e6",uc_full:"1f1f9-1f1e6",shortnames:[":ta:"],category:"flags"},":flag_tc:":{uc_base:"1f1f9-1f1e8",uc_full:"1f1f9-1f1e8",shortnames:[":tc:"],category:"flags"},":flag_td:":{uc_base:"1f1f9-1f1e9",uc_full:"1f1f9-1f1e9",shortnames:[":td:"],category:"flags"},":flag_tf:":{uc_base:"1f1f9-1f1eb",uc_full:"1f1f9-1f1eb",shortnames:[":tf:"],category:"flags"},":flag_tg:":{uc_base:"1f1f9-1f1ec",uc_full:"1f1f9-1f1ec",shortnames:[":tg:"],category:"flags"},":flag_th:":{uc_base:"1f1f9-1f1ed",uc_full:"1f1f9-1f1ed",shortnames:[":th:"],category:"flags"},":flag_tj:":{uc_base:"1f1f9-1f1ef",uc_full:"1f1f9-1f1ef",shortnames:[":tj:"],category:"flags"},":flag_tk:":{uc_base:"1f1f9-1f1f0",uc_full:"1f1f9-1f1f0",shortnames:[":tk:"],category:"flags"},":flag_tl:":{uc_base:"1f1f9-1f1f1",uc_full:"1f1f9-1f1f1",shortnames:[":tl:"],category:"flags"},":flag_tm:":{uc_base:"1f1f9-1f1f2",uc_full:"1f1f9-1f1f2",shortnames:[":turkmenistan:"],category:"flags"},":flag_tn:":{uc_base:"1f1f9-1f1f3",uc_full:"1f1f9-1f1f3",shortnames:[":tn:"],category:"flags"},":flag_to:":{uc_base:"1f1f9-1f1f4",uc_full:"1f1f9-1f1f4",shortnames:[":to:"],category:"flags"},":flag_tr:":{uc_base:"1f1f9-1f1f7",uc_full:"1f1f9-1f1f7",shortnames:[":tr:"],category:"flags"},":flag_tt:":{uc_base:"1f1f9-1f1f9",uc_full:"1f1f9-1f1f9",shortnames:[":tt:"],category:"flags"},":flag_tv:":{uc_base:"1f1f9-1f1fb",uc_full:"1f1f9-1f1fb",shortnames:[":tuvalu:"],category:"flags"},":flag_tw:":{uc_base:"1f1f9-1f1fc",uc_full:"1f1f9-1f1fc",shortnames:[":tw:"],category:"flags"},":flag_tz:":{uc_base:"1f1f9-1f1ff",uc_full:"1f1f9-1f1ff",shortnames:[":tz:"],category:"flags"},":flag_ua:":{uc_base:"1f1fa-1f1e6",uc_full:"1f1fa-1f1e6",shortnames:[":ua:"],category:"flags"},":flag_ug:":{uc_base:"1f1fa-1f1ec",uc_full:"1f1fa-1f1ec",shortnames:[":ug:"],category:"flags"},":flag_um:":{uc_base:"1f1fa-1f1f2",uc_full:"1f1fa-1f1f2",shortnames:[":um:"],category:"flags"},":flag_us:":{uc_base:"1f1fa-1f1f8",uc_full:"1f1fa-1f1f8",shortnames:[":us:"],category:"flags"},":flag_uy:":{uc_base:"1f1fa-1f1fe",uc_full:"1f1fa-1f1fe",shortnames:[":uy:"],category:"flags"},":flag_uz:":{uc_base:"1f1fa-1f1ff",uc_full:"1f1fa-1f1ff",shortnames:[":uz:"],category:"flags"},":flag_va:":{uc_base:"1f1fb-1f1e6",uc_full:"1f1fb-1f1e6",shortnames:[":va:"],category:"flags"},":flag_vc:":{uc_base:"1f1fb-1f1e8",uc_full:"1f1fb-1f1e8",shortnames:[":vc:"],category:"flags"},":flag_ve:":{uc_base:"1f1fb-1f1ea",uc_full:"1f1fb-1f1ea",shortnames:[":ve:"],category:"flags"},":flag_vg:":{uc_base:"1f1fb-1f1ec",uc_full:"1f1fb-1f1ec",shortnames:[":vg:"],category:"flags"},":flag_vi:":{uc_base:"1f1fb-1f1ee",uc_full:"1f1fb-1f1ee",shortnames:[":vi:"],category:"flags"},":flag_vn:":{uc_base:"1f1fb-1f1f3",uc_full:"1f1fb-1f1f3",shortnames:[":vn:"],category:"flags"},":flag_vu:":{uc_base:"1f1fb-1f1fa",uc_full:"1f1fb-1f1fa",shortnames:[":vu:"],category:"flags"},":flag_wf:":{uc_base:"1f1fc-1f1eb",uc_full:"1f1fc-1f1eb",shortnames:[":wf:"],category:"flags"},":flag_ws:":{uc_base:"1f1fc-1f1f8",uc_full:"1f1fc-1f1f8",shortnames:[":ws:"],category:"flags"},":flag_xk:":{uc_base:"1f1fd-1f1f0",uc_full:"1f1fd-1f1f0",shortnames:[":xk:"],category:"flags"},":flag_ye:":{uc_base:"1f1fe-1f1ea",uc_full:"1f1fe-1f1ea",shortnames:[":ye:"],category:"flags"},":flag_yt:":{uc_base:"1f1fe-1f1f9",uc_full:"1f1fe-1f1f9",shortnames:[":yt:"],category:"flags"},":flag_za:":{uc_base:"1f1ff-1f1e6",uc_full:"1f1ff-1f1e6",shortnames:[":za:"],category:"flags"},":flag_zm:":{uc_base:"1f1ff-1f1f2",uc_full:"1f1ff-1f1f2",shortnames:[":zm:"],category:"flags"},":flag_zw:":{uc_base:"1f1ff-1f1fc",uc_full:"1f1ff-1f1fc",shortnames:[":zw:"],category:"flags"},":foot_tone1:":{uc_base:"1f9b6-1f3fb",uc_full:"1f9b6-1f3fb",shortnames:[":foot_light_skin_tone:"],category:"people"},":foot_tone2:":{uc_base:"1f9b6-1f3fc",uc_full:"1f9b6-1f3fc",shortnames:[":foot_medium_light_skin_tone:"],category:"people"},":foot_tone3:":{uc_base:"1f9b6-1f3fd",uc_full:"1f9b6-1f3fd",shortnames:[":foot_medium_skin_tone:"],category:"people"},":foot_tone4:":{uc_base:"1f9b6-1f3fe",uc_full:"1f9b6-1f3fe",shortnames:[":foot_medium_dark_skin_tone:"],category:"people"},":foot_tone5:":{uc_base:"1f9b6-1f3ff",uc_full:"1f9b6-1f3ff",shortnames:[":foot_dark_skin_tone:"],category:"people"},":girl_tone1:":{uc_base:"1f467-1f3fb",uc_full:"1f467-1f3fb",shortnames:[],category:"people"},":girl_tone2:":{uc_base:"1f467-1f3fc",uc_full:"1f467-1f3fc",shortnames:[],category:"people"},":girl_tone3:":{uc_base:"1f467-1f3fd",uc_full:"1f467-1f3fd",shortnames:[],category:"people"},":girl_tone4:":{uc_base:"1f467-1f3fe",uc_full:"1f467-1f3fe",shortnames:[],category:"people"},":girl_tone5:":{uc_base:"1f467-1f3ff",uc_full:"1f467-1f3ff",shortnames:[],category:"people"},":guard_tone1:":{uc_base:"1f482-1f3fb",uc_full:"1f482-1f3fb",shortnames:[":guardsman_tone1:"],category:"people"},":guard_tone2:":{uc_base:"1f482-1f3fc",uc_full:"1f482-1f3fc",shortnames:[":guardsman_tone2:"],category:"people"},":guard_tone3:":{uc_base:"1f482-1f3fd",uc_full:"1f482-1f3fd",shortnames:[":guardsman_tone3:"],category:"people"},":guard_tone4:":{uc_base:"1f482-1f3fe",uc_full:"1f482-1f3fe",shortnames:[":guardsman_tone4:"],category:"people"},":guard_tone5:":{uc_base:"1f482-1f3ff",uc_full:"1f482-1f3ff",shortnames:[":guardsman_tone5:"],category:"people"},":hand_splayed_tone1:":{uc_base:"1f590-1f3fb",uc_full:"1f590-1f3fb",shortnames:[":raised_hand_with_fingers_splayed_tone1:"],category:"people"},":hand_splayed_tone2:":{uc_base:"1f590-1f3fc",uc_full:"1f590-1f3fc",shortnames:[":raised_hand_with_fingers_splayed_tone2:"],category:"people"},":hand_splayed_tone3:":{uc_base:"1f590-1f3fd",uc_full:"1f590-1f3fd",shortnames:[":raised_hand_with_fingers_splayed_tone3:"],category:"people"},":hand_splayed_tone4:":{uc_base:"1f590-1f3fe",uc_full:"1f590-1f3fe",shortnames:[":raised_hand_with_fingers_splayed_tone4:"],category:"people"},":hand_splayed_tone5:":{uc_base:"1f590-1f3ff",uc_full:"1f590-1f3ff",shortnames:[":raised_hand_with_fingers_splayed_tone5:"],category:"people"},":horse_racing_tone1:":{uc_base:"1f3c7-1f3fb",uc_full:"1f3c7-1f3fb",shortnames:[],category:"activity"},":horse_racing_tone2:":{uc_base:"1f3c7-1f3fc",uc_full:"1f3c7-1f3fc",shortnames:[],category:"activity"},":horse_racing_tone3:":{uc_base:"1f3c7-1f3fd",uc_full:"1f3c7-1f3fd",shortnames:[],category:"activity"},":horse_racing_tone4:":{uc_base:"1f3c7-1f3fe",uc_full:"1f3c7-1f3fe",shortnames:[],category:"activity"},":horse_racing_tone5:":{uc_base:"1f3c7-1f3ff",uc_full:"1f3c7-1f3ff",shortnames:[],category:"activity"},":kiss_tone1:":{uc_base:"1f48f-1f3fb",uc_full:"1f48f-1f3fb",shortnames:[":kiss_light_skin_tone:"],category:"people"},":kiss_tone2:":{uc_base:"1f48f-1f3fc",uc_full:"1f48f-1f3fc",shortnames:[":kiss_medium_light_skin_tone:"],category:"people"},":kiss_tone3:":{uc_base:"1f48f-1f3fd",uc_full:"1f48f-1f3fd",shortnames:[":kiss_medium_skin_tone:"],category:"people"},":kiss_tone4:":{uc_base:"1f48f-1f3fe",uc_full:"1f48f-1f3fe",shortnames:[":kiss_medium_dark_skin_tone:"],category:"people"},":kiss_tone5:":{uc_base:"1f48f-1f3ff",uc_full:"1f48f-1f3ff",shortnames:[":kiss_dark_skin_tone:"],category:"people"},":left_facing_fist_tone1:":{uc_base:"1f91b-1f3fb",uc_full:"1f91b-1f3fb",shortnames:[":left_fist_tone1:"],category:"people"},":left_facing_fist_tone2:":{uc_base:"1f91b-1f3fc",uc_full:"1f91b-1f3fc",shortnames:[":left_fist_tone2:"],category:"people"},":left_facing_fist_tone3:":{uc_base:"1f91b-1f3fd",uc_full:"1f91b-1f3fd",shortnames:[":left_fist_tone3:"],category:"people"},":left_facing_fist_tone4:":{uc_base:"1f91b-1f3fe",uc_full:"1f91b-1f3fe",shortnames:[":left_fist_tone4:"],category:"people"},":left_facing_fist_tone5:":{uc_base:"1f91b-1f3ff",uc_full:"1f91b-1f3ff",shortnames:[":left_fist_tone5:"],category:"people"},":leg_tone1:":{uc_base:"1f9b5-1f3fb",uc_full:"1f9b5-1f3fb",shortnames:[":leg_light_skin_tone:"],category:"people"},":leg_tone2:":{uc_base:"1f9b5-1f3fc",uc_full:"1f9b5-1f3fc",shortnames:[":leg_medium_light_skin_tone:"],category:"people"},":leg_tone3:":{uc_base:"1f9b5-1f3fd",uc_full:"1f9b5-1f3fd",shortnames:[":leg_medium_skin_tone:"],category:"people"},":leg_tone4:":{uc_base:"1f9b5-1f3fe",uc_full:"1f9b5-1f3fe",shortnames:[":leg_medium_dark_skin_tone:"],category:"people"},":leg_tone5:":{uc_base:"1f9b5-1f3ff",uc_full:"1f9b5-1f3ff",shortnames:[":leg_dark_skin_tone:"],category:"people"},":levitate_tone1:":{uc_base:"1f574-1f3fb",uc_full:"1f574-1f3fb",shortnames:[":man_in_business_suit_levitating_tone1:",":man_in_business_suit_levitating_light_skin_tone:"],category:"people"},":levitate_tone2:":{uc_base:"1f574-1f3fc",uc_full:"1f574-1f3fc",shortnames:[":man_in_business_suit_levitating_tone2:",":man_in_business_suit_levitating_medium_light_skin_tone:"],category:"people"},":levitate_tone3:":{uc_base:"1f574-1f3fd",uc_full:"1f574-1f3fd",shortnames:[":man_in_business_suit_levitating_tone3:",":man_in_business_suit_levitating_medium_skin_tone:"],category:"people"},":levitate_tone4:":{uc_base:"1f574-1f3fe",uc_full:"1f574-1f3fe",shortnames:[":man_in_business_suit_levitating_tone4:",":man_in_business_suit_levitating_medium_dark_skin_tone:"],category:"people"},":levitate_tone5:":{uc_base:"1f574-1f3ff",uc_full:"1f574-1f3ff",shortnames:[":man_in_business_suit_levitating_tone5:",":man_in_business_suit_levitating_dark_skin_tone:"],category:"people"},":love_you_gesture_tone1:":{uc_base:"1f91f-1f3fb",uc_full:"1f91f-1f3fb",shortnames:[":love_you_gesture_light_skin_tone:"],category:"people"},":love_you_gesture_tone2:":{uc_base:"1f91f-1f3fc",uc_full:"1f91f-1f3fc",shortnames:[":love_you_gesture_medium_light_skin_tone:"],category:"people"},":love_you_gesture_tone3:":{uc_base:"1f91f-1f3fd",uc_full:"1f91f-1f3fd",shortnames:[":love_you_gesture_medium_skin_tone:"],category:"people"},":love_you_gesture_tone4:":{uc_base:"1f91f-1f3fe",uc_full:"1f91f-1f3fe",shortnames:[":love_you_gesture_medium_dark_skin_tone:"],category:"people"},":love_you_gesture_tone5:":{uc_base:"1f91f-1f3ff",uc_full:"1f91f-1f3ff",shortnames:[":love_you_gesture_dark_skin_tone:"],category:"people"},":mage_tone1:":{uc_base:"1f9d9-1f3fb",uc_full:"1f9d9-1f3fb",shortnames:[":mage_light_skin_tone:"],category:"people"},":mage_tone2:":{uc_base:"1f9d9-1f3fc",uc_full:"1f9d9-1f3fc",shortnames:[":mage_medium_light_skin_tone:"],category:"people"},":mage_tone3:":{uc_base:"1f9d9-1f3fd",uc_full:"1f9d9-1f3fd",shortnames:[":mage_medium_skin_tone:"],category:"people"},":mage_tone4:":{uc_base:"1f9d9-1f3fe",uc_full:"1f9d9-1f3fe",shortnames:[":mage_medium_dark_skin_tone:"],category:"people"},":mage_tone5:":{uc_base:"1f9d9-1f3ff",uc_full:"1f9d9-1f3ff",shortnames:[":mage_dark_skin_tone:"],category:"people"},":man_artist:":{uc_base:"1f468-1f3a8",uc_full:"1f468-200d-1f3a8",shortnames:[],category:"people"},":man_astronaut:":{uc_base:"1f468-1f680",uc_full:"1f468-200d-1f680",shortnames:[],category:"people"},":man_bald:":{uc_base:"1f468-1f9b2",uc_full:"1f468-200d-1f9b2",shortnames:[],category:"people"},":man_cook:":{uc_base:"1f468-1f373",uc_full:"1f468-200d-1f373",shortnames:[],category:"people"},":man_curly_haired:":{uc_base:"1f468-1f9b1",uc_full:"1f468-200d-1f9b1",shortnames:[],category:"people"},":man_dancing_tone1:":{uc_base:"1f57a-1f3fb",uc_full:"1f57a-1f3fb",shortnames:[":male_dancer_tone1:"],category:"people"},":man_dancing_tone2:":{uc_base:"1f57a-1f3fc",uc_full:"1f57a-1f3fc",shortnames:[":male_dancer_tone2:"],category:"people"},":man_dancing_tone3:":{uc_base:"1f57a-1f3fd",uc_full:"1f57a-1f3fd",shortnames:[":male_dancer_tone3:"],category:"people"},":man_dancing_tone4:":{uc_base:"1f57a-1f3fe",uc_full:"1f57a-1f3fe",shortnames:[":male_dancer_tone4:"],category:"people"},":man_dancing_tone5:":{uc_base:"1f57a-1f3ff",uc_full:"1f57a-1f3ff",shortnames:[":male_dancer_tone5:"],category:"people"},":man_factory_worker:":{uc_base:"1f468-1f3ed",uc_full:"1f468-200d-1f3ed",shortnames:[],category:"people"},":man_farmer:":{uc_base:"1f468-1f33e",uc_full:"1f468-200d-1f33e",shortnames:[],category:"people"},":man_feeding_baby:":{uc_base:"1f468-1f37c",uc_full:"1f468-200d-1f37c",shortnames:[],category:"people"},":man_firefighter:":{uc_base:"1f468-1f692",uc_full:"1f468-200d-1f692",shortnames:[],category:"people"},":man_in_manual_wheelchair:":{uc_base:"1f468-1f9bd",uc_full:"1f468-200d-1f9bd",shortnames:[],category:"people"},":man_in_motorized_wheelchair:":{uc_base:"1f468-1f9bc",uc_full:"1f468-200d-1f9bc",shortnames:[],category:"people"},":man_mechanic:":{uc_base:"1f468-1f527",uc_full:"1f468-200d-1f527",shortnames:[],category:"people"},":man_office_worker:":{uc_base:"1f468-1f4bc",uc_full:"1f468-200d-1f4bc",shortnames:[],category:"people"},":man_red_haired:":{uc_base:"1f468-1f9b0",uc_full:"1f468-200d-1f9b0",shortnames:[],category:"people"},":man_scientist:":{uc_base:"1f468-1f52c",uc_full:"1f468-200d-1f52c",shortnames:[],category:"people"},":man_singer:":{uc_base:"1f468-1f3a4",uc_full:"1f468-200d-1f3a4",shortnames:[],category:"people"},":man_student:":{uc_base:"1f468-1f393",uc_full:"1f468-200d-1f393",shortnames:[],category:"people"},":man_teacher:":{uc_base:"1f468-1f3eb",uc_full:"1f468-200d-1f3eb",shortnames:[],category:"people"},":man_technologist:":{uc_base:"1f468-1f4bb",uc_full:"1f468-200d-1f4bb",shortnames:[],category:"people"},":man_tone1:":{uc_base:"1f468-1f3fb",uc_full:"1f468-1f3fb",shortnames:[],category:"people"},":man_tone2:":{uc_base:"1f468-1f3fc",uc_full:"1f468-1f3fc",shortnames:[],category:"people"},":man_tone3:":{uc_base:"1f468-1f3fd",uc_full:"1f468-1f3fd",shortnames:[],category:"people"},":man_tone4:":{uc_base:"1f468-1f3fe",uc_full:"1f468-1f3fe",shortnames:[],category:"people"},":man_tone5:":{uc_base:"1f468-1f3ff",uc_full:"1f468-1f3ff",shortnames:[],category:"people"},":man_white_haired:":{uc_base:"1f468-1f9b3",uc_full:"1f468-200d-1f9b3",shortnames:[],category:"people"},":man_with_chinese_cap_tone1:":{uc_base:"1f472-1f3fb",uc_full:"1f472-1f3fb",shortnames:[":man_with_gua_pi_mao_tone1:"],category:"people"},":man_with_chinese_cap_tone2:":{uc_base:"1f472-1f3fc",uc_full:"1f472-1f3fc",shortnames:[":man_with_gua_pi_mao_tone2:"],category:"people"},":man_with_chinese_cap_tone3:":{uc_base:"1f472-1f3fd",uc_full:"1f472-1f3fd",shortnames:[":man_with_gua_pi_mao_tone3:"],category:"people"},":man_with_chinese_cap_tone4:":{uc_base:"1f472-1f3fe",uc_full:"1f472-1f3fe",shortnames:[":man_with_gua_pi_mao_tone4:"],category:"people"},":man_with_chinese_cap_tone5:":{uc_base:"1f472-1f3ff",uc_full:"1f472-1f3ff",shortnames:[":man_with_gua_pi_mao_tone5:"],category:"people"},":man_with_probing_cane:":{uc_base:"1f468-1f9af",uc_full:"1f468-200d-1f9af",shortnames:[],category:"people"},":mechanic:":{uc_base:"1f9d1-1f527",uc_full:"1f9d1-200d-1f527",shortnames:[],category:"people"},":men_holding_hands_tone1:":{uc_base:"1f46c-1f3fb",uc_full:"1f46c-1f3fb",shortnames:[":men_holding_hands_light_skin_tone:"],category:"people"},":men_holding_hands_tone2:":{uc_base:"1f46c-1f3fc",uc_full:"1f46c-1f3fc",shortnames:[":men_holding_hands_medium_light_skin_tone:"],category:"people"},":men_holding_hands_tone3:":{uc_base:"1f46c-1f3fd",uc_full:"1f46c-1f3fd",shortnames:[":men_holding_hands_medium_skin_tone:"],category:"people"},":men_holding_hands_tone4:":{uc_base:"1f46c-1f3fe",uc_full:"1f46c-1f3fe",shortnames:[":men_holding_hands_medium_dark_skin_tone:"],category:"people"},":men_holding_hands_tone5:":{uc_base:"1f46c-1f3ff",uc_full:"1f46c-1f3ff",shortnames:[":men_holding_hands_dark_skin_tone:"],category:"people"},":merperson_tone1:":{uc_base:"1f9dc-1f3fb",uc_full:"1f9dc-1f3fb",shortnames:[":merperson_light_skin_tone:"],category:"people"},":merperson_tone2:":{uc_base:"1f9dc-1f3fc",uc_full:"1f9dc-1f3fc",shortnames:[":merperson_medium_light_skin_tone:"],category:"people"},":merperson_tone3:":{uc_base:"1f9dc-1f3fd",uc_full:"1f9dc-1f3fd",shortnames:[":merperson_medium_skin_tone:"],category:"people"},":merperson_tone4:":{uc_base:"1f9dc-1f3fe",uc_full:"1f9dc-1f3fe",shortnames:[":merperson_medium_dark_skin_tone:"],category:"people"},":merperson_tone5:":{uc_base:"1f9dc-1f3ff",uc_full:"1f9dc-1f3ff",shortnames:[":merperson_dark_skin_tone:"],category:"people"},":metal_tone1:":{uc_base:"1f918-1f3fb",uc_full:"1f918-1f3fb",shortnames:[":sign_of_the_horns_tone1:"],category:"people"},":metal_tone2:":{uc_base:"1f918-1f3fc",uc_full:"1f918-1f3fc",shortnames:[":sign_of_the_horns_tone2:"],category:"people"},":metal_tone3:":{uc_base:"1f918-1f3fd",uc_full:"1f918-1f3fd",shortnames:[":sign_of_the_horns_tone3:"],category:"people"},":metal_tone4:":{uc_base:"1f918-1f3fe",uc_full:"1f918-1f3fe",shortnames:[":sign_of_the_horns_tone4:"],category:"people"},":metal_tone5:":{uc_base:"1f918-1f3ff",uc_full:"1f918-1f3ff",shortnames:[":sign_of_the_horns_tone5:"],category:"people"},":middle_finger_tone1:":{uc_base:"1f595-1f3fb",uc_full:"1f595-1f3fb",shortnames:[":reversed_hand_with_middle_finger_extended_tone1:"],category:"people"},":middle_finger_tone2:":{uc_base:"1f595-1f3fc",uc_full:"1f595-1f3fc",shortnames:[":reversed_hand_with_middle_finger_extended_tone2:"],category:"people"},":middle_finger_tone3:":{uc_base:"1f595-1f3fd",uc_full:"1f595-1f3fd",shortnames:[":reversed_hand_with_middle_finger_extended_tone3:"],category:"people"},":middle_finger_tone4:":{uc_base:"1f595-1f3fe",uc_full:"1f595-1f3fe",shortnames:[":reversed_hand_with_middle_finger_extended_tone4:"],category:"people"},":middle_finger_tone5:":{uc_base:"1f595-1f3ff",uc_full:"1f595-1f3ff",shortnames:[":reversed_hand_with_middle_finger_extended_tone5:"],category:"people"},":mrs_claus_tone1:":{uc_base:"1f936-1f3fb",uc_full:"1f936-1f3fb",shortnames:[":mother_christmas_tone1:"],category:"people"},":mrs_claus_tone2:":{uc_base:"1f936-1f3fc",uc_full:"1f936-1f3fc",shortnames:[":mother_christmas_tone2:"],category:"people"},":mrs_claus_tone3:":{uc_base:"1f936-1f3fd",uc_full:"1f936-1f3fd",shortnames:[":mother_christmas_tone3:"],category:"people"},":mrs_claus_tone4:":{uc_base:"1f936-1f3fe",uc_full:"1f936-1f3fe",shortnames:[":mother_christmas_tone4:"],category:"people"},":mrs_claus_tone5:":{uc_base:"1f936-1f3ff",uc_full:"1f936-1f3ff",shortnames:[":mother_christmas_tone5:"],category:"people"},":muscle_tone1:":{uc_base:"1f4aa-1f3fb",uc_full:"1f4aa-1f3fb",shortnames:[],category:"people"},":muscle_tone2:":{uc_base:"1f4aa-1f3fc",uc_full:"1f4aa-1f3fc",shortnames:[],category:"people"},":muscle_tone3:":{uc_base:"1f4aa-1f3fd",uc_full:"1f4aa-1f3fd",shortnames:[],category:"people"},":muscle_tone4:":{uc_base:"1f4aa-1f3fe",uc_full:"1f4aa-1f3fe",shortnames:[],category:"people"},":muscle_tone5:":{uc_base:"1f4aa-1f3ff",uc_full:"1f4aa-1f3ff",shortnames:[],category:"people"},":mx_claus:":{uc_base:"1f9d1-1f384",uc_full:"1f9d1-200d-1f384",shortnames:[],category:"people"},":nail_care_tone1:":{uc_base:"1f485-1f3fb",uc_full:"1f485-1f3fb",shortnames:[],category:"people"},":nail_care_tone2:":{uc_base:"1f485-1f3fc",uc_full:"1f485-1f3fc",shortnames:[],category:"people"},":nail_care_tone3:":{uc_base:"1f485-1f3fd",uc_full:"1f485-1f3fd",shortnames:[],category:"people"},":nail_care_tone4:":{uc_base:"1f485-1f3fe",uc_full:"1f485-1f3fe",shortnames:[],category:"people"},":nail_care_tone5:":{uc_base:"1f485-1f3ff",uc_full:"1f485-1f3ff",shortnames:[],category:"people"},":ninja_tone1:":{uc_base:"1f977-1f3fb",uc_full:"1f977-1f3fb",shortnames:[":ninja_light_skin_tone:"],category:"people"},":ninja_tone2:":{uc_base:"1f977-1f3fc",uc_full:"1f977-1f3fc",shortnames:[":ninja_medium_light_skin_tone:"],category:"people"},":ninja_tone3:":{uc_base:"1f977-1f3fd",uc_full:"1f977-1f3fd",shortnames:[":ninja_medium_skin_tone:"],category:"people"},":ninja_tone4:":{uc_base:"1f977-1f3fe",uc_full:"1f977-1f3fe",shortnames:[":ninja_medium_dark_skin_tone:"],category:"people"},":ninja_tone5:":{uc_base:"1f977-1f3ff",uc_full:"1f977-1f3ff",shortnames:[":ninja_dark_skin_tone:"],category:"people"},":nose_tone1:":{uc_base:"1f443-1f3fb",uc_full:"1f443-1f3fb",shortnames:[],category:"people"},":nose_tone2:":{uc_base:"1f443-1f3fc",uc_full:"1f443-1f3fc",shortnames:[],category:"people"},":nose_tone3:":{uc_base:"1f443-1f3fd",uc_full:"1f443-1f3fd",shortnames:[],category:"people"},":nose_tone4:":{uc_base:"1f443-1f3fe",uc_full:"1f443-1f3fe",shortnames:[],category:"people"},":nose_tone5:":{uc_base:"1f443-1f3ff",uc_full:"1f443-1f3ff",shortnames:[],category:"people"},":office_worker:":{uc_base:"1f9d1-1f4bc",uc_full:"1f9d1-200d-1f4bc",shortnames:[],category:"people"},":ok_hand_tone1:":{uc_base:"1f44c-1f3fb",uc_full:"1f44c-1f3fb",shortnames:[],category:"people"},":ok_hand_tone2:":{uc_base:"1f44c-1f3fc",uc_full:"1f44c-1f3fc",shortnames:[],category:"people"},":ok_hand_tone3:":{uc_base:"1f44c-1f3fd",uc_full:"1f44c-1f3fd",shortnames:[],category:"people"},":ok_hand_tone4:":{uc_base:"1f44c-1f3fe",uc_full:"1f44c-1f3fe",shortnames:[],category:"people"},":ok_hand_tone5:":{ -uc_base:"1f44c-1f3ff",uc_full:"1f44c-1f3ff",shortnames:[],category:"people"},":older_adult_tone1:":{uc_base:"1f9d3-1f3fb",uc_full:"1f9d3-1f3fb",shortnames:[":older_adult_light_skin_tone:"],category:"people"},":older_adult_tone2:":{uc_base:"1f9d3-1f3fc",uc_full:"1f9d3-1f3fc",shortnames:[":older_adult_medium_light_skin_tone:"],category:"people"},":older_adult_tone3:":{uc_base:"1f9d3-1f3fd",uc_full:"1f9d3-1f3fd",shortnames:[":older_adult_medium_skin_tone:"],category:"people"},":older_adult_tone4:":{uc_base:"1f9d3-1f3fe",uc_full:"1f9d3-1f3fe",shortnames:[":older_adult_medium_dark_skin_tone:"],category:"people"},":older_adult_tone5:":{uc_base:"1f9d3-1f3ff",uc_full:"1f9d3-1f3ff",shortnames:[":older_adult_dark_skin_tone:"],category:"people"},":older_man_tone1:":{uc_base:"1f474-1f3fb",uc_full:"1f474-1f3fb",shortnames:[],category:"people"},":older_man_tone2:":{uc_base:"1f474-1f3fc",uc_full:"1f474-1f3fc",shortnames:[],category:"people"},":older_man_tone3:":{uc_base:"1f474-1f3fd",uc_full:"1f474-1f3fd",shortnames:[],category:"people"},":older_man_tone4:":{uc_base:"1f474-1f3fe",uc_full:"1f474-1f3fe",shortnames:[],category:"people"},":older_man_tone5:":{uc_base:"1f474-1f3ff",uc_full:"1f474-1f3ff",shortnames:[],category:"people"},":older_woman_tone1:":{uc_base:"1f475-1f3fb",uc_full:"1f475-1f3fb",shortnames:[":grandma_tone1:"],category:"people"},":older_woman_tone2:":{uc_base:"1f475-1f3fc",uc_full:"1f475-1f3fc",shortnames:[":grandma_tone2:"],category:"people"},":older_woman_tone3:":{uc_base:"1f475-1f3fd",uc_full:"1f475-1f3fd",shortnames:[":grandma_tone3:"],category:"people"},":older_woman_tone4:":{uc_base:"1f475-1f3fe",uc_full:"1f475-1f3fe",shortnames:[":grandma_tone4:"],category:"people"},":older_woman_tone5:":{uc_base:"1f475-1f3ff",uc_full:"1f475-1f3ff",shortnames:[":grandma_tone5:"],category:"people"},":open_hands_tone1:":{uc_base:"1f450-1f3fb",uc_full:"1f450-1f3fb",shortnames:[],category:"people"},":open_hands_tone2:":{uc_base:"1f450-1f3fc",uc_full:"1f450-1f3fc",shortnames:[],category:"people"},":open_hands_tone3:":{uc_base:"1f450-1f3fd",uc_full:"1f450-1f3fd",shortnames:[],category:"people"},":open_hands_tone4:":{uc_base:"1f450-1f3fe",uc_full:"1f450-1f3fe",shortnames:[],category:"people"},":open_hands_tone5:":{uc_base:"1f450-1f3ff",uc_full:"1f450-1f3ff",shortnames:[],category:"people"},":palms_up_together_tone1:":{uc_base:"1f932-1f3fb",uc_full:"1f932-1f3fb",shortnames:[":palms_up_together_light_skin_tone:"],category:"people"},":palms_up_together_tone2:":{uc_base:"1f932-1f3fc",uc_full:"1f932-1f3fc",shortnames:[":palms_up_together_medium_light_skin_tone:"],category:"people"},":palms_up_together_tone3:":{uc_base:"1f932-1f3fd",uc_full:"1f932-1f3fd",shortnames:[":palms_up_together_medium_skin_tone:"],category:"people"},":palms_up_together_tone4:":{uc_base:"1f932-1f3fe",uc_full:"1f932-1f3fe",shortnames:[":palms_up_together_medium_dark_skin_tone:"],category:"people"},":palms_up_together_tone5:":{uc_base:"1f932-1f3ff",uc_full:"1f932-1f3ff",shortnames:[":palms_up_together_dark_skin_tone:"],category:"people"},":person_bald:":{uc_base:"1f9d1-1f9b2",uc_full:"1f9d1-200d-1f9b2",shortnames:[],category:"people"},":person_biking_tone1:":{uc_base:"1f6b4-1f3fb",uc_full:"1f6b4-1f3fb",shortnames:[":bicyclist_tone1:"],category:"activity"},":person_biking_tone2:":{uc_base:"1f6b4-1f3fc",uc_full:"1f6b4-1f3fc",shortnames:[":bicyclist_tone2:"],category:"activity"},":person_biking_tone3:":{uc_base:"1f6b4-1f3fd",uc_full:"1f6b4-1f3fd",shortnames:[":bicyclist_tone3:"],category:"activity"},":person_biking_tone4:":{uc_base:"1f6b4-1f3fe",uc_full:"1f6b4-1f3fe",shortnames:[":bicyclist_tone4:"],category:"activity"},":person_biking_tone5:":{uc_base:"1f6b4-1f3ff",uc_full:"1f6b4-1f3ff",shortnames:[":bicyclist_tone5:"],category:"activity"},":person_bowing_tone1:":{uc_base:"1f647-1f3fb",uc_full:"1f647-1f3fb",shortnames:[":bow_tone1:"],category:"people"},":person_bowing_tone2:":{uc_base:"1f647-1f3fc",uc_full:"1f647-1f3fc",shortnames:[":bow_tone2:"],category:"people"},":person_bowing_tone3:":{uc_base:"1f647-1f3fd",uc_full:"1f647-1f3fd",shortnames:[":bow_tone3:"],category:"people"},":person_bowing_tone4:":{uc_base:"1f647-1f3fe",uc_full:"1f647-1f3fe",shortnames:[":bow_tone4:"],category:"people"},":person_bowing_tone5:":{uc_base:"1f647-1f3ff",uc_full:"1f647-1f3ff",shortnames:[":bow_tone5:"],category:"people"},":person_climbing_tone1:":{uc_base:"1f9d7-1f3fb",uc_full:"1f9d7-1f3fb",shortnames:[":person_climbing_light_skin_tone:"],category:"activity"},":person_climbing_tone2:":{uc_base:"1f9d7-1f3fc",uc_full:"1f9d7-1f3fc",shortnames:[":person_climbing_medium_light_skin_tone:"],category:"activity"},":person_climbing_tone3:":{uc_base:"1f9d7-1f3fd",uc_full:"1f9d7-1f3fd",shortnames:[":person_climbing_medium_skin_tone:"],category:"activity"},":person_climbing_tone4:":{uc_base:"1f9d7-1f3fe",uc_full:"1f9d7-1f3fe",shortnames:[":person_climbing_medium_dark_skin_tone:"],category:"activity"},":person_climbing_tone5:":{uc_base:"1f9d7-1f3ff",uc_full:"1f9d7-1f3ff",shortnames:[":person_climbing_dark_skin_tone:"],category:"activity"},":person_curly_hair:":{uc_base:"1f9d1-1f9b1",uc_full:"1f9d1-200d-1f9b1",shortnames:[],category:"people"},":person_doing_cartwheel_tone1:":{uc_base:"1f938-1f3fb",uc_full:"1f938-1f3fb",shortnames:[":cartwheel_tone1:"],category:"activity"},":person_doing_cartwheel_tone2:":{uc_base:"1f938-1f3fc",uc_full:"1f938-1f3fc",shortnames:[":cartwheel_tone2:"],category:"activity"},":person_doing_cartwheel_tone3:":{uc_base:"1f938-1f3fd",uc_full:"1f938-1f3fd",shortnames:[":cartwheel_tone3:"],category:"activity"},":person_doing_cartwheel_tone4:":{uc_base:"1f938-1f3fe",uc_full:"1f938-1f3fe",shortnames:[":cartwheel_tone4:"],category:"activity"},":person_doing_cartwheel_tone5:":{uc_base:"1f938-1f3ff",uc_full:"1f938-1f3ff",shortnames:[":cartwheel_tone5:"],category:"activity"},":person_facepalming_tone1:":{uc_base:"1f926-1f3fb",uc_full:"1f926-1f3fb",shortnames:[":face_palm_tone1:",":facepalm_tone1:"],category:"people"},":person_facepalming_tone2:":{uc_base:"1f926-1f3fc",uc_full:"1f926-1f3fc",shortnames:[":face_palm_tone2:",":facepalm_tone2:"],category:"people"},":person_facepalming_tone3:":{uc_base:"1f926-1f3fd",uc_full:"1f926-1f3fd",shortnames:[":face_palm_tone3:",":facepalm_tone3:"],category:"people"},":person_facepalming_tone4:":{uc_base:"1f926-1f3fe",uc_full:"1f926-1f3fe",shortnames:[":face_palm_tone4:",":facepalm_tone4:"],category:"people"},":person_facepalming_tone5:":{uc_base:"1f926-1f3ff",uc_full:"1f926-1f3ff",shortnames:[":face_palm_tone5:",":facepalm_tone5:"],category:"people"},":person_feeding_baby:":{uc_base:"1f9d1-1f37c",uc_full:"1f9d1-200d-1f37c",shortnames:[],category:"people"},":person_frowning_tone1:":{uc_base:"1f64d-1f3fb",uc_full:"1f64d-1f3fb",shortnames:[],category:"people"},":person_frowning_tone2:":{uc_base:"1f64d-1f3fc",uc_full:"1f64d-1f3fc",shortnames:[],category:"people"},":person_frowning_tone3:":{uc_base:"1f64d-1f3fd",uc_full:"1f64d-1f3fd",shortnames:[],category:"people"},":person_frowning_tone4:":{uc_base:"1f64d-1f3fe",uc_full:"1f64d-1f3fe",shortnames:[],category:"people"},":person_frowning_tone5:":{uc_base:"1f64d-1f3ff",uc_full:"1f64d-1f3ff",shortnames:[],category:"people"},":person_gesturing_no_tone1:":{uc_base:"1f645-1f3fb",uc_full:"1f645-1f3fb",shortnames:[":no_good_tone1:"],category:"people"},":person_gesturing_no_tone2:":{uc_base:"1f645-1f3fc",uc_full:"1f645-1f3fc",shortnames:[":no_good_tone2:"],category:"people"},":person_gesturing_no_tone3:":{uc_base:"1f645-1f3fd",uc_full:"1f645-1f3fd",shortnames:[":no_good_tone3:"],category:"people"},":person_gesturing_no_tone4:":{uc_base:"1f645-1f3fe",uc_full:"1f645-1f3fe",shortnames:[":no_good_tone4:"],category:"people"},":person_gesturing_no_tone5:":{uc_base:"1f645-1f3ff",uc_full:"1f645-1f3ff",shortnames:[":no_good_tone5:"],category:"people"},":person_gesturing_ok_tone1:":{uc_base:"1f646-1f3fb",uc_full:"1f646-1f3fb",shortnames:[":ok_woman_tone1:"],category:"people"},":person_gesturing_ok_tone2:":{uc_base:"1f646-1f3fc",uc_full:"1f646-1f3fc",shortnames:[":ok_woman_tone2:"],category:"people"},":person_gesturing_ok_tone3:":{uc_base:"1f646-1f3fd",uc_full:"1f646-1f3fd",shortnames:[":ok_woman_tone3:"],category:"people"},":person_gesturing_ok_tone4:":{uc_base:"1f646-1f3fe",uc_full:"1f646-1f3fe",shortnames:[":ok_woman_tone4:"],category:"people"},":person_gesturing_ok_tone5:":{uc_base:"1f646-1f3ff",uc_full:"1f646-1f3ff",shortnames:[":ok_woman_tone5:"],category:"people"},":person_getting_haircut_tone1:":{uc_base:"1f487-1f3fb",uc_full:"1f487-1f3fb",shortnames:[":haircut_tone1:"],category:"people"},":person_getting_haircut_tone2:":{uc_base:"1f487-1f3fc",uc_full:"1f487-1f3fc",shortnames:[":haircut_tone2:"],category:"people"},":person_getting_haircut_tone3:":{uc_base:"1f487-1f3fd",uc_full:"1f487-1f3fd",shortnames:[":haircut_tone3:"],category:"people"},":person_getting_haircut_tone4:":{uc_base:"1f487-1f3fe",uc_full:"1f487-1f3fe",shortnames:[":haircut_tone4:"],category:"people"},":person_getting_haircut_tone5:":{uc_base:"1f487-1f3ff",uc_full:"1f487-1f3ff",shortnames:[":haircut_tone5:"],category:"people"},":person_getting_massage_tone1:":{uc_base:"1f486-1f3fb",uc_full:"1f486-1f3fb",shortnames:[":massage_tone1:"],category:"people"},":person_getting_massage_tone2:":{uc_base:"1f486-1f3fc",uc_full:"1f486-1f3fc",shortnames:[":massage_tone2:"],category:"people"},":person_getting_massage_tone3:":{uc_base:"1f486-1f3fd",uc_full:"1f486-1f3fd",shortnames:[":massage_tone3:"],category:"people"},":person_getting_massage_tone4:":{uc_base:"1f486-1f3fe",uc_full:"1f486-1f3fe",shortnames:[":massage_tone4:"],category:"people"},":person_getting_massage_tone5:":{uc_base:"1f486-1f3ff",uc_full:"1f486-1f3ff",shortnames:[":massage_tone5:"],category:"people"},":person_golfing_tone1:":{uc_base:"1f3cc-1f3fb",uc_full:"1f3cc-1f3fb",shortnames:[":person_golfing_light_skin_tone:"],category:"activity"},":person_golfing_tone2:":{uc_base:"1f3cc-1f3fc",uc_full:"1f3cc-1f3fc",shortnames:[":person_golfing_medium_light_skin_tone:"],category:"activity"},":person_golfing_tone3:":{uc_base:"1f3cc-1f3fd",uc_full:"1f3cc-1f3fd",shortnames:[":person_golfing_medium_skin_tone:"],category:"activity"},":person_golfing_tone4:":{uc_base:"1f3cc-1f3fe",uc_full:"1f3cc-1f3fe",shortnames:[":person_golfing_medium_dark_skin_tone:"],category:"activity"},":person_golfing_tone5:":{uc_base:"1f3cc-1f3ff",uc_full:"1f3cc-1f3ff",shortnames:[":person_golfing_dark_skin_tone:"],category:"activity"},":person_in_bed_tone1:":{uc_base:"1f6cc-1f3fb",uc_full:"1f6cc-1f3fb",shortnames:[":person_in_bed_light_skin_tone:"],category:"objects"},":person_in_bed_tone2:":{uc_base:"1f6cc-1f3fc",uc_full:"1f6cc-1f3fc",shortnames:[":person_in_bed_medium_light_skin_tone:"],category:"objects"},":person_in_bed_tone3:":{uc_base:"1f6cc-1f3fd",uc_full:"1f6cc-1f3fd",shortnames:[":person_in_bed_medium_skin_tone:"],category:"objects"},":person_in_bed_tone4:":{uc_base:"1f6cc-1f3fe",uc_full:"1f6cc-1f3fe",shortnames:[":person_in_bed_medium_dark_skin_tone:"],category:"objects"},":person_in_bed_tone5:":{uc_base:"1f6cc-1f3ff",uc_full:"1f6cc-1f3ff",shortnames:[":person_in_bed_dark_skin_tone:"],category:"objects"},":person_in_lotus_position_tone1:":{uc_base:"1f9d8-1f3fb",uc_full:"1f9d8-1f3fb",shortnames:[":person_in_lotus_position_light_skin_tone:"],category:"activity"},":person_in_lotus_position_tone2:":{uc_base:"1f9d8-1f3fc",uc_full:"1f9d8-1f3fc",shortnames:[":person_in_lotus_position_medium_light_skin_tone:"],category:"activity"},":person_in_lotus_position_tone3:":{uc_base:"1f9d8-1f3fd",uc_full:"1f9d8-1f3fd",shortnames:[":person_in_lotus_position_medium_skin_tone:"],category:"activity"},":person_in_lotus_position_tone4:":{uc_base:"1f9d8-1f3fe",uc_full:"1f9d8-1f3fe",shortnames:[":person_in_lotus_position_medium_dark_skin_tone:"],category:"activity"},":person_in_lotus_position_tone5:":{uc_base:"1f9d8-1f3ff",uc_full:"1f9d8-1f3ff",shortnames:[":person_in_lotus_position_dark_skin_tone:"],category:"activity"},":person_in_manual_wheelchair:":{uc_base:"1f9d1-1f9bd",uc_full:"1f9d1-200d-1f9bd",shortnames:[],category:"people"},":person_in_motorized_wheelchair:":{uc_base:"1f9d1-1f9bc",uc_full:"1f9d1-200d-1f9bc",shortnames:[],category:"people"},":person_in_steamy_room_tone1:":{uc_base:"1f9d6-1f3fb",uc_full:"1f9d6-1f3fb",shortnames:[":person_in_steamy_room_light_skin_tone:"],category:"people"},":person_in_steamy_room_tone2:":{uc_base:"1f9d6-1f3fc",uc_full:"1f9d6-1f3fc",shortnames:[":person_in_steamy_room_medium_light_skin_tone:"],category:"people"},":person_in_steamy_room_tone3:":{uc_base:"1f9d6-1f3fd",uc_full:"1f9d6-1f3fd",shortnames:[":person_in_steamy_room_medium_skin_tone:"],category:"people"},":person_in_steamy_room_tone4:":{uc_base:"1f9d6-1f3fe",uc_full:"1f9d6-1f3fe",shortnames:[":person_in_steamy_room_medium_dark_skin_tone:"],category:"people"},":person_in_steamy_room_tone5:":{uc_base:"1f9d6-1f3ff",uc_full:"1f9d6-1f3ff",shortnames:[":person_in_steamy_room_dark_skin_tone:"],category:"people"},":person_in_tuxedo_tone1:":{uc_base:"1f935-1f3fb",uc_full:"1f935-1f3fb",shortnames:[":tuxedo_tone1:"],category:"people"},":person_in_tuxedo_tone2:":{uc_base:"1f935-1f3fc",uc_full:"1f935-1f3fc",shortnames:[":tuxedo_tone2:"],category:"people"},":person_in_tuxedo_tone3:":{uc_base:"1f935-1f3fd",uc_full:"1f935-1f3fd",shortnames:[":tuxedo_tone3:"],category:"people"},":person_in_tuxedo_tone4:":{uc_base:"1f935-1f3fe",uc_full:"1f935-1f3fe",shortnames:[":tuxedo_tone4:"],category:"people"},":person_in_tuxedo_tone5:":{uc_base:"1f935-1f3ff",uc_full:"1f935-1f3ff",shortnames:[":tuxedo_tone5:"],category:"people"},":person_juggling_tone1:":{uc_base:"1f939-1f3fb",uc_full:"1f939-1f3fb",shortnames:[":juggling_tone1:",":juggler_tone1:"],category:"activity"},":person_juggling_tone2:":{uc_base:"1f939-1f3fc",uc_full:"1f939-1f3fc",shortnames:[":juggling_tone2:",":juggler_tone2:"],category:"activity"},":person_juggling_tone3:":{uc_base:"1f939-1f3fd",uc_full:"1f939-1f3fd",shortnames:[":juggling_tone3:",":juggler_tone3:"],category:"activity"},":person_juggling_tone4:":{uc_base:"1f939-1f3fe",uc_full:"1f939-1f3fe",shortnames:[":juggling_tone4:",":juggler_tone4:"],category:"activity"},":person_juggling_tone5:":{uc_base:"1f939-1f3ff",uc_full:"1f939-1f3ff",shortnames:[":juggling_tone5:",":juggler_tone5:"],category:"activity"},":person_kneeling_tone1:":{uc_base:"1f9ce-1f3fb",uc_full:"1f9ce-1f3fb",shortnames:[":person_kneeling_light_skin_tone:"],category:"people"},":person_kneeling_tone2:":{uc_base:"1f9ce-1f3fc",uc_full:"1f9ce-1f3fc",shortnames:[":person_kneeling_medium_light_skin_tone:"],category:"people"},":person_kneeling_tone3:":{uc_base:"1f9ce-1f3fd",uc_full:"1f9ce-1f3fd",shortnames:[":person_kneeling_medium_skin_tone:"],category:"people"},":person_kneeling_tone4:":{uc_base:"1f9ce-1f3fe",uc_full:"1f9ce-1f3fe",shortnames:[":person_kneeling_medium_dark_skin_tone:"],category:"people"},":person_kneeling_tone5:":{uc_base:"1f9ce-1f3ff",uc_full:"1f9ce-1f3ff",shortnames:[":person_kneeling_dark_skin_tone:"],category:"people"},":person_lifting_weights_tone1:":{uc_base:"1f3cb-1f3fb",uc_full:"1f3cb-1f3fb",shortnames:[":lifter_tone1:",":weight_lifter_tone1:"],category:"activity"},":person_lifting_weights_tone2:":{uc_base:"1f3cb-1f3fc",uc_full:"1f3cb-1f3fc",shortnames:[":lifter_tone2:",":weight_lifter_tone2:"],category:"activity"},":person_lifting_weights_tone3:":{uc_base:"1f3cb-1f3fd",uc_full:"1f3cb-1f3fd",shortnames:[":lifter_tone3:",":weight_lifter_tone3:"],category:"activity"},":person_lifting_weights_tone4:":{uc_base:"1f3cb-1f3fe",uc_full:"1f3cb-1f3fe",shortnames:[":lifter_tone4:",":weight_lifter_tone4:"],category:"activity"},":person_lifting_weights_tone5:":{uc_base:"1f3cb-1f3ff",uc_full:"1f3cb-1f3ff",shortnames:[":lifter_tone5:",":weight_lifter_tone5:"],category:"activity"},":person_mountain_biking_tone1:":{uc_base:"1f6b5-1f3fb",uc_full:"1f6b5-1f3fb",shortnames:[":mountain_bicyclist_tone1:"],category:"activity"},":person_mountain_biking_tone2:":{uc_base:"1f6b5-1f3fc",uc_full:"1f6b5-1f3fc",shortnames:[":mountain_bicyclist_tone2:"],category:"activity"},":person_mountain_biking_tone3:":{uc_base:"1f6b5-1f3fd",uc_full:"1f6b5-1f3fd",shortnames:[":mountain_bicyclist_tone3:"],category:"activity"},":person_mountain_biking_tone4:":{uc_base:"1f6b5-1f3fe",uc_full:"1f6b5-1f3fe",shortnames:[":mountain_bicyclist_tone4:"],category:"activity"},":person_mountain_biking_tone5:":{uc_base:"1f6b5-1f3ff",uc_full:"1f6b5-1f3ff",shortnames:[":mountain_bicyclist_tone5:"],category:"activity"},":person_playing_handball_tone1:":{uc_base:"1f93e-1f3fb",uc_full:"1f93e-1f3fb",shortnames:[":handball_tone1:"],category:"activity"},":person_playing_handball_tone2:":{uc_base:"1f93e-1f3fc",uc_full:"1f93e-1f3fc",shortnames:[":handball_tone2:"],category:"activity"},":person_playing_handball_tone3:":{uc_base:"1f93e-1f3fd",uc_full:"1f93e-1f3fd",shortnames:[":handball_tone3:"],category:"activity"},":person_playing_handball_tone4:":{uc_base:"1f93e-1f3fe",uc_full:"1f93e-1f3fe",shortnames:[":handball_tone4:"],category:"activity"},":person_playing_handball_tone5:":{uc_base:"1f93e-1f3ff",uc_full:"1f93e-1f3ff",shortnames:[":handball_tone5:"],category:"activity"},":person_playing_water_polo_tone1:":{uc_base:"1f93d-1f3fb",uc_full:"1f93d-1f3fb",shortnames:[":water_polo_tone1:"],category:"activity"},":person_playing_water_polo_tone2:":{uc_base:"1f93d-1f3fc",uc_full:"1f93d-1f3fc",shortnames:[":water_polo_tone2:"],category:"activity"},":person_playing_water_polo_tone3:":{uc_base:"1f93d-1f3fd",uc_full:"1f93d-1f3fd",shortnames:[":water_polo_tone3:"],category:"activity"},":person_playing_water_polo_tone4:":{uc_base:"1f93d-1f3fe",uc_full:"1f93d-1f3fe",shortnames:[":water_polo_tone4:"],category:"activity"},":person_playing_water_polo_tone5:":{uc_base:"1f93d-1f3ff",uc_full:"1f93d-1f3ff",shortnames:[":water_polo_tone5:"],category:"activity"},":person_pouting_tone1:":{uc_base:"1f64e-1f3fb",uc_full:"1f64e-1f3fb",shortnames:[":person_with_pouting_face_tone1:"],category:"people"},":person_pouting_tone2:":{uc_base:"1f64e-1f3fc",uc_full:"1f64e-1f3fc",shortnames:[":person_with_pouting_face_tone2:"],category:"people"},":person_pouting_tone3:":{uc_base:"1f64e-1f3fd",uc_full:"1f64e-1f3fd",shortnames:[":person_with_pouting_face_tone3:"],category:"people"},":person_pouting_tone4:":{uc_base:"1f64e-1f3fe",uc_full:"1f64e-1f3fe",shortnames:[":person_with_pouting_face_tone4:"],category:"people"},":person_pouting_tone5:":{uc_base:"1f64e-1f3ff",uc_full:"1f64e-1f3ff",shortnames:[":person_with_pouting_face_tone5:"],category:"people"},":person_raising_hand_tone1:":{uc_base:"1f64b-1f3fb",uc_full:"1f64b-1f3fb",shortnames:[":raising_hand_tone1:"],category:"people"},":person_raising_hand_tone2:":{uc_base:"1f64b-1f3fc",uc_full:"1f64b-1f3fc",shortnames:[":raising_hand_tone2:"],category:"people"},":person_raising_hand_tone3:":{uc_base:"1f64b-1f3fd",uc_full:"1f64b-1f3fd",shortnames:[":raising_hand_tone3:"],category:"people"},":person_raising_hand_tone4:":{uc_base:"1f64b-1f3fe",uc_full:"1f64b-1f3fe",shortnames:[":raising_hand_tone4:"],category:"people"},":person_raising_hand_tone5:":{uc_base:"1f64b-1f3ff",uc_full:"1f64b-1f3ff",shortnames:[":raising_hand_tone5:"],category:"people"},":person_red_hair:":{uc_base:"1f9d1-1f9b0",uc_full:"1f9d1-200d-1f9b0",shortnames:[],category:"people"},":person_rowing_boat_tone1:":{uc_base:"1f6a3-1f3fb",uc_full:"1f6a3-1f3fb",shortnames:[":rowboat_tone1:"],category:"activity"},":person_rowing_boat_tone2:":{uc_base:"1f6a3-1f3fc",uc_full:"1f6a3-1f3fc",shortnames:[":rowboat_tone2:"],category:"activity"},":person_rowing_boat_tone3:":{uc_base:"1f6a3-1f3fd",uc_full:"1f6a3-1f3fd",shortnames:[":rowboat_tone3:"],category:"activity"},":person_rowing_boat_tone4:":{uc_base:"1f6a3-1f3fe",uc_full:"1f6a3-1f3fe",shortnames:[":rowboat_tone4:"],category:"activity"},":person_rowing_boat_tone5:":{uc_base:"1f6a3-1f3ff",uc_full:"1f6a3-1f3ff",shortnames:[":rowboat_tone5:"],category:"activity"},":person_running_tone1:":{uc_base:"1f3c3-1f3fb",uc_full:"1f3c3-1f3fb",shortnames:[":runner_tone1:"],category:"people"},":person_running_tone2:":{uc_base:"1f3c3-1f3fc",uc_full:"1f3c3-1f3fc",shortnames:[":runner_tone2:"],category:"people"},":person_running_tone3:":{uc_base:"1f3c3-1f3fd",uc_full:"1f3c3-1f3fd",shortnames:[":runner_tone3:"],category:"people"},":person_running_tone4:":{uc_base:"1f3c3-1f3fe",uc_full:"1f3c3-1f3fe",shortnames:[":runner_tone4:"],category:"people"},":person_running_tone5:":{uc_base:"1f3c3-1f3ff",uc_full:"1f3c3-1f3ff",shortnames:[":runner_tone5:"],category:"people"},":person_shrugging_tone1:":{uc_base:"1f937-1f3fb",uc_full:"1f937-1f3fb",shortnames:[":shrug_tone1:"],category:"people"},":person_shrugging_tone2:":{uc_base:"1f937-1f3fc",uc_full:"1f937-1f3fc",shortnames:[":shrug_tone2:"],category:"people"},":person_shrugging_tone3:":{uc_base:"1f937-1f3fd",uc_full:"1f937-1f3fd",shortnames:[":shrug_tone3:"],category:"people"},":person_shrugging_tone4:":{uc_base:"1f937-1f3fe",uc_full:"1f937-1f3fe",shortnames:[":shrug_tone4:"],category:"people"},":person_shrugging_tone5:":{uc_base:"1f937-1f3ff",uc_full:"1f937-1f3ff",shortnames:[":shrug_tone5:"],category:"people"},":person_standing_tone1:":{uc_base:"1f9cd-1f3fb",uc_full:"1f9cd-1f3fb",shortnames:[":person_standing_light_skin_tone:"],category:"people"},":person_standing_tone2:":{uc_base:"1f9cd-1f3fc",uc_full:"1f9cd-1f3fc",shortnames:[":person_standing_medium_light_skin_tone:"],category:"people"},":person_standing_tone3:":{uc_base:"1f9cd-1f3fd",uc_full:"1f9cd-1f3fd",shortnames:[":person_standing_medium_skin_tone:"],category:"people"},":person_standing_tone4:":{uc_base:"1f9cd-1f3fe",uc_full:"1f9cd-1f3fe",shortnames:[":person_standing_medium_dark_skin_tone:"],category:"people"},":person_standing_tone5:":{uc_base:"1f9cd-1f3ff",uc_full:"1f9cd-1f3ff",shortnames:[":person_standing_dark_skin_tone:"],category:"people"},":person_surfing_tone1:":{uc_base:"1f3c4-1f3fb",uc_full:"1f3c4-1f3fb",shortnames:[":surfer_tone1:"],category:"activity"},":person_surfing_tone2:":{uc_base:"1f3c4-1f3fc",uc_full:"1f3c4-1f3fc",shortnames:[":surfer_tone2:"],category:"activity"},":person_surfing_tone3:":{uc_base:"1f3c4-1f3fd",uc_full:"1f3c4-1f3fd",shortnames:[":surfer_tone3:"],category:"activity"},":person_surfing_tone4:":{uc_base:"1f3c4-1f3fe",uc_full:"1f3c4-1f3fe",shortnames:[":surfer_tone4:"],category:"activity"},":person_surfing_tone5:":{uc_base:"1f3c4-1f3ff",uc_full:"1f3c4-1f3ff",shortnames:[":surfer_tone5:"],category:"activity"},":person_swimming_tone1:":{uc_base:"1f3ca-1f3fb",uc_full:"1f3ca-1f3fb",shortnames:[":swimmer_tone1:"],category:"activity"},":person_swimming_tone2:":{uc_base:"1f3ca-1f3fc",uc_full:"1f3ca-1f3fc",shortnames:[":swimmer_tone2:"],category:"activity"},":person_swimming_tone3:":{uc_base:"1f3ca-1f3fd",uc_full:"1f3ca-1f3fd",shortnames:[":swimmer_tone3:"],category:"activity"},":person_swimming_tone4:":{uc_base:"1f3ca-1f3fe",uc_full:"1f3ca-1f3fe",shortnames:[":swimmer_tone4:"],category:"activity"},":person_swimming_tone5:":{uc_base:"1f3ca-1f3ff",uc_full:"1f3ca-1f3ff",shortnames:[":swimmer_tone5:"],category:"activity"},":person_tipping_hand_tone1:":{uc_base:"1f481-1f3fb",uc_full:"1f481-1f3fb",shortnames:[":information_desk_person_tone1:"],category:"people"},":person_tipping_hand_tone2:":{uc_base:"1f481-1f3fc",uc_full:"1f481-1f3fc",shortnames:[":information_desk_person_tone2:"],category:"people"},":person_tipping_hand_tone3:":{uc_base:"1f481-1f3fd",uc_full:"1f481-1f3fd",shortnames:[":information_desk_person_tone3:"],category:"people"},":person_tipping_hand_tone4:":{uc_base:"1f481-1f3fe",uc_full:"1f481-1f3fe",shortnames:[":information_desk_person_tone4:"],category:"people"},":person_tipping_hand_tone5:":{uc_base:"1f481-1f3ff",uc_full:"1f481-1f3ff",shortnames:[":information_desk_person_tone5:"],category:"people"},":person_walking_tone1:":{uc_base:"1f6b6-1f3fb",uc_full:"1f6b6-1f3fb",shortnames:[":walking_tone1:"],category:"people"},":person_walking_tone2:":{uc_base:"1f6b6-1f3fc",uc_full:"1f6b6-1f3fc",shortnames:[":walking_tone2:"],category:"people"},":person_walking_tone3:":{uc_base:"1f6b6-1f3fd",uc_full:"1f6b6-1f3fd",shortnames:[":walking_tone3:"],category:"people"},":person_walking_tone4:":{uc_base:"1f6b6-1f3fe",uc_full:"1f6b6-1f3fe",shortnames:[":walking_tone4:"],category:"people"},":person_walking_tone5:":{uc_base:"1f6b6-1f3ff",uc_full:"1f6b6-1f3ff",shortnames:[":walking_tone5:"],category:"people"},":person_wearing_turban_tone1:":{uc_base:"1f473-1f3fb",uc_full:"1f473-1f3fb",shortnames:[":man_with_turban_tone1:"],category:"people"},":person_wearing_turban_tone2:":{uc_base:"1f473-1f3fc",uc_full:"1f473-1f3fc",shortnames:[":man_with_turban_tone2:"],category:"people"},":person_wearing_turban_tone3:":{uc_base:"1f473-1f3fd",uc_full:"1f473-1f3fd",shortnames:[":man_with_turban_tone3:"],category:"people"},":person_wearing_turban_tone4:":{uc_base:"1f473-1f3fe",uc_full:"1f473-1f3fe",shortnames:[":man_with_turban_tone4:"],category:"people"},":person_wearing_turban_tone5:":{uc_base:"1f473-1f3ff",uc_full:"1f473-1f3ff",shortnames:[":man_with_turban_tone5:"],category:"people"},":person_white_hair:":{uc_base:"1f9d1-1f9b3",uc_full:"1f9d1-200d-1f9b3",shortnames:[],category:"people"},":person_with_probing_cane:":{uc_base:"1f9d1-1f9af",uc_full:"1f9d1-200d-1f9af",shortnames:[],category:"people"},":person_with_veil_tone1:":{uc_base:"1f470-1f3fb",uc_full:"1f470-1f3fb",shortnames:[],category:"people"},":person_with_veil_tone2:":{uc_base:"1f470-1f3fc",uc_full:"1f470-1f3fc",shortnames:[],category:"people"},":person_with_veil_tone3:":{uc_base:"1f470-1f3fd",uc_full:"1f470-1f3fd",shortnames:[],category:"people"},":person_with_veil_tone4:":{uc_base:"1f470-1f3fe",uc_full:"1f470-1f3fe",shortnames:[],category:"people"},":person_with_veil_tone5:":{uc_base:"1f470-1f3ff",uc_full:"1f470-1f3ff",shortnames:[],category:"people"},":pinched_fingers_tone1:":{uc_base:"1f90c-1f3fb",uc_full:"1f90c-1f3fb",shortnames:[":pinched_fingers_light_skin_tone:"],category:"people"},":pinched_fingers_tone2:":{uc_base:"1f90c-1f3fc",uc_full:"1f90c-1f3fc",shortnames:[":pinched_fingers_medium_light_skin_tone:"],category:"people"},":pinched_fingers_tone3:":{uc_base:"1f90c-1f3fd",uc_full:"1f90c-1f3fd",shortnames:[":pinched_fingers_medium_skin_tone:"],category:"people"},":pinched_fingers_tone4:":{uc_base:"1f90c-1f3fe",uc_full:"1f90c-1f3fe",shortnames:[":pinched_fingers_medium_dark_skin_tone:"],category:"people"},":pinched_fingers_tone5:":{uc_base:"1f90c-1f3ff",uc_full:"1f90c-1f3ff",shortnames:[":pinched_fingers_dark_skin_tone:"],category:"people"},":pinching_hand_tone1:":{uc_base:"1f90f-1f3fb",uc_full:"1f90f-1f3fb",shortnames:[":pinching_hand_light_skin_tone:"],category:"people"},":pinching_hand_tone2:":{uc_base:"1f90f-1f3fc",uc_full:"1f90f-1f3fc",shortnames:[":pinching_hand_medium_light_skin_tone:"],category:"people"},":pinching_hand_tone3:":{uc_base:"1f90f-1f3fd",uc_full:"1f90f-1f3fd",shortnames:[":pinching_hand_medium_skin_tone:"],category:"people"},":pinching_hand_tone4:":{uc_base:"1f90f-1f3fe",uc_full:"1f90f-1f3fe",shortnames:[":pinching_hand_medium_dark_skin_tone:"],category:"people"},":pinching_hand_tone5:":{uc_base:"1f90f-1f3ff",uc_full:"1f90f-1f3ff",shortnames:[":pinching_hand_dark_skin_tone:"],category:"people"},":point_down_tone1:":{uc_base:"1f447-1f3fb",uc_full:"1f447-1f3fb",shortnames:[],category:"people"},":point_down_tone2:":{uc_base:"1f447-1f3fc",uc_full:"1f447-1f3fc",shortnames:[],category:"people"},":point_down_tone3:":{uc_base:"1f447-1f3fd",uc_full:"1f447-1f3fd",shortnames:[],category:"people"},":point_down_tone4:":{uc_base:"1f447-1f3fe",uc_full:"1f447-1f3fe",shortnames:[],category:"people"},":point_down_tone5:":{uc_base:"1f447-1f3ff",uc_full:"1f447-1f3ff",shortnames:[],category:"people"},":point_left_tone1:":{uc_base:"1f448-1f3fb",uc_full:"1f448-1f3fb",shortnames:[],category:"people"},":point_left_tone2:":{uc_base:"1f448-1f3fc",uc_full:"1f448-1f3fc",shortnames:[],category:"people"},":point_left_tone3:":{uc_base:"1f448-1f3fd",uc_full:"1f448-1f3fd",shortnames:[],category:"people"},":point_left_tone4:":{uc_base:"1f448-1f3fe",uc_full:"1f448-1f3fe",shortnames:[],category:"people"},":point_left_tone5:":{uc_base:"1f448-1f3ff",uc_full:"1f448-1f3ff",shortnames:[],category:"people"},":point_right_tone1:":{uc_base:"1f449-1f3fb",uc_full:"1f449-1f3fb",shortnames:[],category:"people"},":point_right_tone2:":{uc_base:"1f449-1f3fc",uc_full:"1f449-1f3fc",shortnames:[],category:"people"},":point_right_tone3:":{uc_base:"1f449-1f3fd",uc_full:"1f449-1f3fd",shortnames:[],category:"people"},":point_right_tone4:":{uc_base:"1f449-1f3fe",uc_full:"1f449-1f3fe",shortnames:[],category:"people"},":point_right_tone5:":{uc_base:"1f449-1f3ff",uc_full:"1f449-1f3ff",shortnames:[],category:"people"},":point_up_2_tone1:":{uc_base:"1f446-1f3fb",uc_full:"1f446-1f3fb",shortnames:[],category:"people"},":point_up_2_tone2:":{uc_base:"1f446-1f3fc",uc_full:"1f446-1f3fc",shortnames:[],category:"people"},":point_up_2_tone3:":{uc_base:"1f446-1f3fd",uc_full:"1f446-1f3fd",shortnames:[],category:"people"},":point_up_2_tone4:":{uc_base:"1f446-1f3fe",uc_full:"1f446-1f3fe",shortnames:[],category:"people"},":point_up_2_tone5:":{uc_base:"1f446-1f3ff",uc_full:"1f446-1f3ff",shortnames:[],category:"people"},":police_officer_tone1:":{uc_base:"1f46e-1f3fb",uc_full:"1f46e-1f3fb",shortnames:[":cop_tone1:"],category:"people"},":police_officer_tone2:":{uc_base:"1f46e-1f3fc",uc_full:"1f46e-1f3fc",shortnames:[":cop_tone2:"],category:"people"},":police_officer_tone3:":{uc_base:"1f46e-1f3fd",uc_full:"1f46e-1f3fd",shortnames:[":cop_tone3:"],category:"people"},":police_officer_tone4:":{uc_base:"1f46e-1f3fe",uc_full:"1f46e-1f3fe",shortnames:[":cop_tone4:"],category:"people"},":police_officer_tone5:":{uc_base:"1f46e-1f3ff",uc_full:"1f46e-1f3ff",shortnames:[":cop_tone5:"],category:"people"},":pray_tone1:":{uc_base:"1f64f-1f3fb",uc_full:"1f64f-1f3fb",shortnames:[],category:"people"},":pray_tone2:":{uc_base:"1f64f-1f3fc",uc_full:"1f64f-1f3fc",shortnames:[],category:"people"},":pray_tone3:":{uc_base:"1f64f-1f3fd",uc_full:"1f64f-1f3fd",shortnames:[],category:"people"},":pray_tone4:":{uc_base:"1f64f-1f3fe",uc_full:"1f64f-1f3fe",shortnames:[],category:"people"},":pray_tone5:":{uc_base:"1f64f-1f3ff",uc_full:"1f64f-1f3ff",shortnames:[],category:"people"},":pregnant_woman_tone1:":{uc_base:"1f930-1f3fb",uc_full:"1f930-1f3fb",shortnames:[":expecting_woman_tone1:"],category:"people"},":pregnant_woman_tone2:":{uc_base:"1f930-1f3fc",uc_full:"1f930-1f3fc",shortnames:[":expecting_woman_tone2:"],category:"people"},":pregnant_woman_tone3:":{uc_base:"1f930-1f3fd",uc_full:"1f930-1f3fd",shortnames:[":expecting_woman_tone3:"],category:"people"},":pregnant_woman_tone4:":{uc_base:"1f930-1f3fe",uc_full:"1f930-1f3fe",shortnames:[":expecting_woman_tone4:"],category:"people"},":pregnant_woman_tone5:":{uc_base:"1f930-1f3ff",uc_full:"1f930-1f3ff",shortnames:[":expecting_woman_tone5:"],category:"people"},":prince_tone1:":{uc_base:"1f934-1f3fb",uc_full:"1f934-1f3fb",shortnames:[],category:"people"},":prince_tone2:":{uc_base:"1f934-1f3fc",uc_full:"1f934-1f3fc",shortnames:[],category:"people"},":prince_tone3:":{uc_base:"1f934-1f3fd",uc_full:"1f934-1f3fd",shortnames:[],category:"people"},":prince_tone4:":{uc_base:"1f934-1f3fe",uc_full:"1f934-1f3fe",shortnames:[],category:"people"},":prince_tone5:":{uc_base:"1f934-1f3ff",uc_full:"1f934-1f3ff",shortnames:[],category:"people"},":princess_tone1:":{uc_base:"1f478-1f3fb",uc_full:"1f478-1f3fb",shortnames:[],category:"people"},":princess_tone2:":{uc_base:"1f478-1f3fc",uc_full:"1f478-1f3fc",shortnames:[],category:"people"},":princess_tone3:":{uc_base:"1f478-1f3fd",uc_full:"1f478-1f3fd",shortnames:[],category:"people"},":princess_tone4:":{uc_base:"1f478-1f3fe",uc_full:"1f478-1f3fe",shortnames:[],category:"people"},":princess_tone5:":{uc_base:"1f478-1f3ff",uc_full:"1f478-1f3ff",shortnames:[],category:"people"},":punch_tone1:":{uc_base:"1f44a-1f3fb",uc_full:"1f44a-1f3fb",shortnames:[],category:"people"},":punch_tone2:":{uc_base:"1f44a-1f3fc",uc_full:"1f44a-1f3fc",shortnames:[],category:"people"},":punch_tone3:":{uc_base:"1f44a-1f3fd",uc_full:"1f44a-1f3fd",shortnames:[],category:"people"},":punch_tone4:":{uc_base:"1f44a-1f3fe", -uc_full:"1f44a-1f3fe",shortnames:[],category:"people"},":punch_tone5:":{uc_base:"1f44a-1f3ff",uc_full:"1f44a-1f3ff",shortnames:[],category:"people"},":rainbow_flag:":{uc_base:"1f3f3-1f308",uc_full:"1f3f3-fe0f-200d-1f308",shortnames:[":gay_pride_flag:"],category:"flags"},":raised_back_of_hand_tone1:":{uc_base:"1f91a-1f3fb",uc_full:"1f91a-1f3fb",shortnames:[":back_of_hand_tone1:"],category:"people"},":raised_back_of_hand_tone2:":{uc_base:"1f91a-1f3fc",uc_full:"1f91a-1f3fc",shortnames:[":back_of_hand_tone2:"],category:"people"},":raised_back_of_hand_tone3:":{uc_base:"1f91a-1f3fd",uc_full:"1f91a-1f3fd",shortnames:[":back_of_hand_tone3:"],category:"people"},":raised_back_of_hand_tone4:":{uc_base:"1f91a-1f3fe",uc_full:"1f91a-1f3fe",shortnames:[":back_of_hand_tone4:"],category:"people"},":raised_back_of_hand_tone5:":{uc_base:"1f91a-1f3ff",uc_full:"1f91a-1f3ff",shortnames:[":back_of_hand_tone5:"],category:"people"},":raised_hands_tone1:":{uc_base:"1f64c-1f3fb",uc_full:"1f64c-1f3fb",shortnames:[],category:"people"},":raised_hands_tone2:":{uc_base:"1f64c-1f3fc",uc_full:"1f64c-1f3fc",shortnames:[],category:"people"},":raised_hands_tone3:":{uc_base:"1f64c-1f3fd",uc_full:"1f64c-1f3fd",shortnames:[],category:"people"},":raised_hands_tone4:":{uc_base:"1f64c-1f3fe",uc_full:"1f64c-1f3fe",shortnames:[],category:"people"},":raised_hands_tone5:":{uc_base:"1f64c-1f3ff",uc_full:"1f64c-1f3ff",shortnames:[],category:"people"},":right_facing_fist_tone1:":{uc_base:"1f91c-1f3fb",uc_full:"1f91c-1f3fb",shortnames:[":right_fist_tone1:"],category:"people"},":right_facing_fist_tone2:":{uc_base:"1f91c-1f3fc",uc_full:"1f91c-1f3fc",shortnames:[":right_fist_tone2:"],category:"people"},":right_facing_fist_tone3:":{uc_base:"1f91c-1f3fd",uc_full:"1f91c-1f3fd",shortnames:[":right_fist_tone3:"],category:"people"},":right_facing_fist_tone4:":{uc_base:"1f91c-1f3fe",uc_full:"1f91c-1f3fe",shortnames:[":right_fist_tone4:"],category:"people"},":right_facing_fist_tone5:":{uc_base:"1f91c-1f3ff",uc_full:"1f91c-1f3ff",shortnames:[":right_fist_tone5:"],category:"people"},":santa_tone1:":{uc_base:"1f385-1f3fb",uc_full:"1f385-1f3fb",shortnames:[],category:"people"},":santa_tone2:":{uc_base:"1f385-1f3fc",uc_full:"1f385-1f3fc",shortnames:[],category:"people"},":santa_tone3:":{uc_base:"1f385-1f3fd",uc_full:"1f385-1f3fd",shortnames:[],category:"people"},":santa_tone4:":{uc_base:"1f385-1f3fe",uc_full:"1f385-1f3fe",shortnames:[],category:"people"},":santa_tone5:":{uc_base:"1f385-1f3ff",uc_full:"1f385-1f3ff",shortnames:[],category:"people"},":scientist:":{uc_base:"1f9d1-1f52c",uc_full:"1f9d1-200d-1f52c",shortnames:[],category:"people"},":selfie_tone1:":{uc_base:"1f933-1f3fb",uc_full:"1f933-1f3fb",shortnames:[],category:"people"},":selfie_tone2:":{uc_base:"1f933-1f3fc",uc_full:"1f933-1f3fc",shortnames:[],category:"people"},":selfie_tone3:":{uc_base:"1f933-1f3fd",uc_full:"1f933-1f3fd",shortnames:[],category:"people"},":selfie_tone4:":{uc_base:"1f933-1f3fe",uc_full:"1f933-1f3fe",shortnames:[],category:"people"},":selfie_tone5:":{uc_base:"1f933-1f3ff",uc_full:"1f933-1f3ff",shortnames:[],category:"people"},":service_dog:":{uc_base:"1f415-1f9ba",uc_full:"1f415-200d-1f9ba",shortnames:[],category:"nature"},":singer:":{uc_base:"1f9d1-1f3a4",uc_full:"1f9d1-200d-1f3a4",shortnames:[],category:"people"},":snowboarder_tone1:":{uc_base:"1f3c2-1f3fb",uc_full:"1f3c2-1f3fb",shortnames:[":snowboarder_light_skin_tone:"],category:"activity"},":snowboarder_tone2:":{uc_base:"1f3c2-1f3fc",uc_full:"1f3c2-1f3fc",shortnames:[":snowboarder_medium_light_skin_tone:"],category:"activity"},":snowboarder_tone3:":{uc_base:"1f3c2-1f3fd",uc_full:"1f3c2-1f3fd",shortnames:[":snowboarder_medium_skin_tone:"],category:"activity"},":snowboarder_tone4:":{uc_base:"1f3c2-1f3fe",uc_full:"1f3c2-1f3fe",shortnames:[":snowboarder_medium_dark_skin_tone:"],category:"activity"},":snowboarder_tone5:":{uc_base:"1f3c2-1f3ff",uc_full:"1f3c2-1f3ff",shortnames:[":snowboarder_dark_skin_tone:"],category:"activity"},":student:":{uc_base:"1f9d1-1f393",uc_full:"1f9d1-200d-1f393",shortnames:[],category:"people"},":superhero_tone1:":{uc_base:"1f9b8-1f3fb",uc_full:"1f9b8-1f3fb",shortnames:[":superhero_light_skin_tone:"],category:"people"},":superhero_tone2:":{uc_base:"1f9b8-1f3fc",uc_full:"1f9b8-1f3fc",shortnames:[":superhero_medium_light_skin_tone:"],category:"people"},":superhero_tone3:":{uc_base:"1f9b8-1f3fd",uc_full:"1f9b8-1f3fd",shortnames:[":superhero_medium_skin_tone:"],category:"people"},":superhero_tone4:":{uc_base:"1f9b8-1f3fe",uc_full:"1f9b8-1f3fe",shortnames:[":superhero_medium_dark_skin_tone:"],category:"people"},":superhero_tone5:":{uc_base:"1f9b8-1f3ff",uc_full:"1f9b8-1f3ff",shortnames:[":superhero_dark_skin_tone:"],category:"people"},":supervillain_tone1:":{uc_base:"1f9b9-1f3fb",uc_full:"1f9b9-1f3fb",shortnames:[":supervillain_light_skin_tone:"],category:"people"},":supervillain_tone2:":{uc_base:"1f9b9-1f3fc",uc_full:"1f9b9-1f3fc",shortnames:[":supervillain_medium_light_skin_tone:"],category:"people"},":supervillain_tone3:":{uc_base:"1f9b9-1f3fd",uc_full:"1f9b9-1f3fd",shortnames:[":supervillain_medium_skin_tone:"],category:"people"},":supervillain_tone4:":{uc_base:"1f9b9-1f3fe",uc_full:"1f9b9-1f3fe",shortnames:[":supervillain_medium_dark_skin_tone:"],category:"people"},":supervillain_tone5:":{uc_base:"1f9b9-1f3ff",uc_full:"1f9b9-1f3ff",shortnames:[":supervillain_dark_skin_tone:"],category:"people"},":teacher:":{uc_base:"1f9d1-1f3eb",uc_full:"1f9d1-200d-1f3eb",shortnames:[],category:"people"},":technologist:":{uc_base:"1f9d1-1f4bb",uc_full:"1f9d1-200d-1f4bb",shortnames:[],category:"people"},":thumbsdown_tone1:":{uc_base:"1f44e-1f3fb",uc_full:"1f44e-1f3fb",shortnames:[":-1_tone1:",":thumbdown_tone1:"],category:"people"},":thumbsdown_tone2:":{uc_base:"1f44e-1f3fc",uc_full:"1f44e-1f3fc",shortnames:[":-1_tone2:",":thumbdown_tone2:"],category:"people"},":thumbsdown_tone3:":{uc_base:"1f44e-1f3fd",uc_full:"1f44e-1f3fd",shortnames:[":-1_tone3:",":thumbdown_tone3:"],category:"people"},":thumbsdown_tone4:":{uc_base:"1f44e-1f3fe",uc_full:"1f44e-1f3fe",shortnames:[":-1_tone4:",":thumbdown_tone4:"],category:"people"},":thumbsdown_tone5:":{uc_base:"1f44e-1f3ff",uc_full:"1f44e-1f3ff",shortnames:[":-1_tone5:",":thumbdown_tone5:"],category:"people"},":thumbsup_tone1:":{uc_base:"1f44d-1f3fb",uc_full:"1f44d-1f3fb",shortnames:[":+1_tone1:",":thumbup_tone1:"],category:"people"},":thumbsup_tone2:":{uc_base:"1f44d-1f3fc",uc_full:"1f44d-1f3fc",shortnames:[":+1_tone2:",":thumbup_tone2:"],category:"people"},":thumbsup_tone3:":{uc_base:"1f44d-1f3fd",uc_full:"1f44d-1f3fd",shortnames:[":+1_tone3:",":thumbup_tone3:"],category:"people"},":thumbsup_tone4:":{uc_base:"1f44d-1f3fe",uc_full:"1f44d-1f3fe",shortnames:[":+1_tone4:",":thumbup_tone4:"],category:"people"},":thumbsup_tone5:":{uc_base:"1f44d-1f3ff",uc_full:"1f44d-1f3ff",shortnames:[":+1_tone5:",":thumbup_tone5:"],category:"people"},":united_nations:":{uc_base:"1f1fa-1f1f3",uc_full:"1f1fa-1f1f3",shortnames:[],category:"flags"},":vampire_tone1:":{uc_base:"1f9db-1f3fb",uc_full:"1f9db-1f3fb",shortnames:[":vampire_light_skin_tone:"],category:"people"},":vampire_tone2:":{uc_base:"1f9db-1f3fc",uc_full:"1f9db-1f3fc",shortnames:[":vampire_medium_light_skin_tone:"],category:"people"},":vampire_tone3:":{uc_base:"1f9db-1f3fd",uc_full:"1f9db-1f3fd",shortnames:[":vampire_medium_skin_tone:"],category:"people"},":vampire_tone4:":{uc_base:"1f9db-1f3fe",uc_full:"1f9db-1f3fe",shortnames:[":vampire_medium_dark_skin_tone:"],category:"people"},":vampire_tone5:":{uc_base:"1f9db-1f3ff",uc_full:"1f9db-1f3ff",shortnames:[":vampire_dark_skin_tone:"],category:"people"},":vulcan_tone1:":{uc_base:"1f596-1f3fb",uc_full:"1f596-1f3fb",shortnames:[":raised_hand_with_part_between_middle_and_ring_fingers_tone1:"],category:"people"},":vulcan_tone2:":{uc_base:"1f596-1f3fc",uc_full:"1f596-1f3fc",shortnames:[":raised_hand_with_part_between_middle_and_ring_fingers_tone2:"],category:"people"},":vulcan_tone3:":{uc_base:"1f596-1f3fd",uc_full:"1f596-1f3fd",shortnames:[":raised_hand_with_part_between_middle_and_ring_fingers_tone3:"],category:"people"},":vulcan_tone4:":{uc_base:"1f596-1f3fe",uc_full:"1f596-1f3fe",shortnames:[":raised_hand_with_part_between_middle_and_ring_fingers_tone4:"],category:"people"},":vulcan_tone5:":{uc_base:"1f596-1f3ff",uc_full:"1f596-1f3ff",shortnames:[":raised_hand_with_part_between_middle_and_ring_fingers_tone5:"],category:"people"},":wave_tone1:":{uc_base:"1f44b-1f3fb",uc_full:"1f44b-1f3fb",shortnames:[],category:"people"},":wave_tone2:":{uc_base:"1f44b-1f3fc",uc_full:"1f44b-1f3fc",shortnames:[],category:"people"},":wave_tone3:":{uc_base:"1f44b-1f3fd",uc_full:"1f44b-1f3fd",shortnames:[],category:"people"},":wave_tone4:":{uc_base:"1f44b-1f3fe",uc_full:"1f44b-1f3fe",shortnames:[],category:"people"},":wave_tone5:":{uc_base:"1f44b-1f3ff",uc_full:"1f44b-1f3ff",shortnames:[],category:"people"},":woman_and_man_holding_hands_tone1:":{uc_base:"1f46b-1f3fb",uc_full:"1f46b-1f3fb",shortnames:[":woman_and_man_holding_hands_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone2:":{uc_base:"1f46b-1f3fc",uc_full:"1f46b-1f3fc",shortnames:[":woman_and_man_holding_hands_medium_light_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone3:":{uc_base:"1f46b-1f3fd",uc_full:"1f46b-1f3fd",shortnames:[":woman_and_man_holding_hands_medium_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone4:":{uc_base:"1f46b-1f3fe",uc_full:"1f46b-1f3fe",shortnames:[":woman_and_man_holding_hands_medium_dark_skin_tone:"],category:"people"},":woman_and_man_holding_hands_tone5:":{uc_base:"1f46b-1f3ff",uc_full:"1f46b-1f3ff",shortnames:[":woman_and_man_holding_hands_dark_skin_tone:"],category:"people"},":woman_artist:":{uc_base:"1f469-1f3a8",uc_full:"1f469-200d-1f3a8",shortnames:[],category:"people"},":woman_astronaut:":{uc_base:"1f469-1f680",uc_full:"1f469-200d-1f680",shortnames:[],category:"people"},":woman_bald:":{uc_base:"1f469-1f9b2",uc_full:"1f469-200d-1f9b2",shortnames:[],category:"people"},":woman_cook:":{uc_base:"1f469-1f373",uc_full:"1f469-200d-1f373",shortnames:[],category:"people"},":woman_curly_haired:":{uc_base:"1f469-1f9b1",uc_full:"1f469-200d-1f9b1",shortnames:[],category:"people"},":woman_factory_worker:":{uc_base:"1f469-1f3ed",uc_full:"1f469-200d-1f3ed",shortnames:[],category:"people"},":woman_farmer:":{uc_base:"1f469-1f33e",uc_full:"1f469-200d-1f33e",shortnames:[],category:"people"},":woman_feeding_baby:":{uc_base:"1f469-1f37c",uc_full:"1f469-200d-1f37c",shortnames:[],category:"people"},":woman_firefighter:":{uc_base:"1f469-1f692",uc_full:"1f469-200d-1f692",shortnames:[],category:"people"},":woman_in_manual_wheelchair:":{uc_base:"1f469-1f9bd",uc_full:"1f469-200d-1f9bd",shortnames:[],category:"people"},":woman_in_motorized_wheelchair:":{uc_base:"1f469-1f9bc",uc_full:"1f469-200d-1f9bc",shortnames:[],category:"people"},":woman_mechanic:":{uc_base:"1f469-1f527",uc_full:"1f469-200d-1f527",shortnames:[],category:"people"},":woman_office_worker:":{uc_base:"1f469-1f4bc",uc_full:"1f469-200d-1f4bc",shortnames:[],category:"people"},":woman_red_haired:":{uc_base:"1f469-1f9b0",uc_full:"1f469-200d-1f9b0",shortnames:[],category:"people"},":woman_scientist:":{uc_base:"1f469-1f52c",uc_full:"1f469-200d-1f52c",shortnames:[],category:"people"},":woman_singer:":{uc_base:"1f469-1f3a4",uc_full:"1f469-200d-1f3a4",shortnames:[],category:"people"},":woman_student:":{uc_base:"1f469-1f393",uc_full:"1f469-200d-1f393",shortnames:[],category:"people"},":woman_teacher:":{uc_base:"1f469-1f3eb",uc_full:"1f469-200d-1f3eb",shortnames:[],category:"people"},":woman_technologist:":{uc_base:"1f469-1f4bb",uc_full:"1f469-200d-1f4bb",shortnames:[],category:"people"},":woman_tone1:":{uc_base:"1f469-1f3fb",uc_full:"1f469-1f3fb",shortnames:[],category:"people"},":woman_tone2:":{uc_base:"1f469-1f3fc",uc_full:"1f469-1f3fc",shortnames:[],category:"people"},":woman_tone3:":{uc_base:"1f469-1f3fd",uc_full:"1f469-1f3fd",shortnames:[],category:"people"},":woman_tone4:":{uc_base:"1f469-1f3fe",uc_full:"1f469-1f3fe",shortnames:[],category:"people"},":woman_tone5:":{uc_base:"1f469-1f3ff",uc_full:"1f469-1f3ff",shortnames:[],category:"people"},":woman_white_haired:":{uc_base:"1f469-1f9b3",uc_full:"1f469-200d-1f9b3",shortnames:[],category:"people"},":woman_with_headscarf_tone1:":{uc_base:"1f9d5-1f3fb",uc_full:"1f9d5-1f3fb",shortnames:[":woman_with_headscarf_light_skin_tone:"],category:"people"},":woman_with_headscarf_tone2:":{uc_base:"1f9d5-1f3fc",uc_full:"1f9d5-1f3fc",shortnames:[":woman_with_headscarf_medium_light_skin_tone:"],category:"people"},":woman_with_headscarf_tone3:":{uc_base:"1f9d5-1f3fd",uc_full:"1f9d5-1f3fd",shortnames:[":woman_with_headscarf_medium_skin_tone:"],category:"people"},":woman_with_headscarf_tone4:":{uc_base:"1f9d5-1f3fe",uc_full:"1f9d5-1f3fe",shortnames:[":woman_with_headscarf_medium_dark_skin_tone:"],category:"people"},":woman_with_headscarf_tone5:":{uc_base:"1f9d5-1f3ff",uc_full:"1f9d5-1f3ff",shortnames:[":woman_with_headscarf_dark_skin_tone:"],category:"people"},":woman_with_probing_cane:":{uc_base:"1f469-1f9af",uc_full:"1f469-200d-1f9af",shortnames:[],category:"people"},":women_holding_hands_tone1:":{uc_base:"1f46d-1f3fb",uc_full:"1f46d-1f3fb",shortnames:[":women_holding_hands_light_skin_tone:"],category:"people"},":women_holding_hands_tone2:":{uc_base:"1f46d-1f3fc",uc_full:"1f46d-1f3fc",shortnames:[":women_holding_hands_medium_light_skin_tone:"],category:"people"},":women_holding_hands_tone3:":{uc_base:"1f46d-1f3fd",uc_full:"1f46d-1f3fd",shortnames:[":women_holding_hands_medium_skin_tone:"],category:"people"},":women_holding_hands_tone4:":{uc_base:"1f46d-1f3fe",uc_full:"1f46d-1f3fe",shortnames:[":women_holding_hands_medium_dark_skin_tone:"],category:"people"},":women_holding_hands_tone5:":{uc_base:"1f46d-1f3ff",uc_full:"1f46d-1f3ff",shortnames:[":women_holding_hands_dark_skin_tone:"],category:"people"},":black_cat:":{uc_base:"1f408-2b1b",uc_full:"1f408-200d-2b1b",shortnames:[],category:"nature"},":blond-haired_man:":{uc_base:"1f471-2642",uc_full:"1f471-200d-2642-fe0f",shortnames:[],category:"people"},":blond-haired_woman:":{uc_base:"1f471-2640",uc_full:"1f471-200d-2640-fe0f",shortnames:[],category:"people"},":deaf_man:":{uc_base:"1f9cf-2642",uc_full:"1f9cf-200d-2642-fe0f",shortnames:[],category:"people"},":deaf_woman:":{uc_base:"1f9cf-2640",uc_full:"1f9cf-200d-2640-fe0f",shortnames:[],category:"people"},":fist_tone1:":{uc_base:"270a-1f3fb",uc_full:"270a-1f3fb",shortnames:[],category:"people"},":fist_tone2:":{uc_base:"270a-1f3fc",uc_full:"270a-1f3fc",shortnames:[],category:"people"},":fist_tone3:":{uc_base:"270a-1f3fd",uc_full:"270a-1f3fd",shortnames:[],category:"people"},":fist_tone4:":{uc_base:"270a-1f3fe",uc_full:"270a-1f3fe",shortnames:[],category:"people"},":fist_tone5:":{uc_base:"270a-1f3ff",uc_full:"270a-1f3ff",shortnames:[],category:"people"},":health_worker:":{uc_base:"1f9d1-2695",uc_full:"1f9d1-200d-2695-fe0f",shortnames:[],category:"people"},":heart_on_fire:":{uc_base:"2764-1f525",uc_full:"2764-fe0f-200d-1f525",shortnames:[],category:"symbols"},":judge:":{uc_base:"1f9d1-2696",uc_full:"1f9d1-200d-2696-fe0f",shortnames:[],category:"people"},":man_beard:":{uc_base:"1f9d4-2642",uc_full:"1f9d4-200d-2642-fe0f",shortnames:[],category:"people"},":man_biking:":{uc_base:"1f6b4-2642",uc_full:"1f6b4-200d-2642-fe0f",shortnames:[],category:"activity"},":man_bowing:":{uc_base:"1f647-2642",uc_full:"1f647-200d-2642-fe0f",shortnames:[],category:"people"},":man_cartwheeling:":{uc_base:"1f938-2642",uc_full:"1f938-200d-2642-fe0f",shortnames:[],category:"activity"},":man_climbing:":{uc_base:"1f9d7-2642",uc_full:"1f9d7-200d-2642-fe0f",shortnames:[],category:"activity"},":man_construction_worker:":{uc_base:"1f477-2642",uc_full:"1f477-200d-2642-fe0f",shortnames:[],category:"people"},":man_detective:":{uc_base:"1f575-2642",uc_full:"1f575-fe0f-200d-2642-fe0f",shortnames:[],category:"people"},":man_elf:":{uc_base:"1f9dd-2642",uc_full:"1f9dd-200d-2642-fe0f",shortnames:[],category:"people"},":man_facepalming:":{uc_base:"1f926-2642",uc_full:"1f926-200d-2642-fe0f",shortnames:[],category:"people"},":man_fairy:":{uc_base:"1f9da-2642",uc_full:"1f9da-200d-2642-fe0f",shortnames:[],category:"people"},":man_frowning:":{uc_base:"1f64d-2642",uc_full:"1f64d-200d-2642-fe0f",shortnames:[],category:"people"},":man_genie:":{uc_base:"1f9de-2642",uc_full:"1f9de-200d-2642-fe0f",shortnames:[],category:"people"},":man_gesturing_no:":{uc_base:"1f645-2642",uc_full:"1f645-200d-2642-fe0f",shortnames:[],category:"people"},":man_gesturing_ok:":{uc_base:"1f646-2642",uc_full:"1f646-200d-2642-fe0f",shortnames:[],category:"people"},":man_getting_face_massage:":{uc_base:"1f486-2642",uc_full:"1f486-200d-2642-fe0f",shortnames:[],category:"people"},":man_getting_haircut:":{uc_base:"1f487-2642",uc_full:"1f487-200d-2642-fe0f",shortnames:[],category:"people"},":man_golfing:":{uc_base:"1f3cc-2642",uc_full:"1f3cc-fe0f-200d-2642-fe0f",shortnames:[],category:"activity"},":man_guard:":{uc_base:"1f482-2642",uc_full:"1f482-200d-2642-fe0f",shortnames:[],category:"people"},":man_health_worker:":{uc_base:"1f468-2695",uc_full:"1f468-200d-2695-fe0f",shortnames:[],category:"people"},":man_in_lotus_position:":{uc_base:"1f9d8-2642",uc_full:"1f9d8-200d-2642-fe0f",shortnames:[],category:"activity"},":man_in_steamy_room:":{uc_base:"1f9d6-2642",uc_full:"1f9d6-200d-2642-fe0f",shortnames:[],category:"people"},":man_in_tuxedo:":{uc_base:"1f935-2642",uc_full:"1f935-200d-2642-fe0f",shortnames:[],category:"people"},":man_judge:":{uc_base:"1f468-2696",uc_full:"1f468-200d-2696-fe0f",shortnames:[],category:"people"},":man_juggling:":{uc_base:"1f939-2642",uc_full:"1f939-200d-2642-fe0f",shortnames:[],category:"activity"},":man_kneeling:":{uc_base:"1f9ce-2642",uc_full:"1f9ce-200d-2642-fe0f",shortnames:[],category:"people"},":man_lifting_weights:":{uc_base:"1f3cb-2642",uc_full:"1f3cb-fe0f-200d-2642-fe0f",shortnames:[],category:"activity"},":man_mage:":{uc_base:"1f9d9-2642",uc_full:"1f9d9-200d-2642-fe0f",shortnames:[],category:"people"},":man_mountain_biking:":{uc_base:"1f6b5-2642",uc_full:"1f6b5-200d-2642-fe0f",shortnames:[],category:"activity"},":man_pilot:":{uc_base:"1f468-2708",uc_full:"1f468-200d-2708-fe0f",shortnames:[],category:"people"},":man_playing_handball:":{uc_base:"1f93e-2642",uc_full:"1f93e-200d-2642-fe0f",shortnames:[],category:"activity"},":man_playing_water_polo:":{uc_base:"1f93d-2642",uc_full:"1f93d-200d-2642-fe0f",shortnames:[],category:"activity"},":man_police_officer:":{uc_base:"1f46e-2642",uc_full:"1f46e-200d-2642-fe0f",shortnames:[],category:"people"},":man_pouting:":{uc_base:"1f64e-2642",uc_full:"1f64e-200d-2642-fe0f",shortnames:[],category:"people"},":man_raising_hand:":{uc_base:"1f64b-2642",uc_full:"1f64b-200d-2642-fe0f",shortnames:[],category:"people"},":man_rowing_boat:":{uc_base:"1f6a3-2642",uc_full:"1f6a3-200d-2642-fe0f",shortnames:[],category:"activity"},":man_running:":{uc_base:"1f3c3-2642",uc_full:"1f3c3-200d-2642-fe0f",shortnames:[],category:"people"},":man_shrugging:":{uc_base:"1f937-2642",uc_full:"1f937-200d-2642-fe0f",shortnames:[],category:"people"},":man_standing:":{uc_base:"1f9cd-2642",uc_full:"1f9cd-200d-2642-fe0f",shortnames:[],category:"people"},":man_superhero:":{uc_base:"1f9b8-2642",uc_full:"1f9b8-200d-2642-fe0f",shortnames:[],category:"people"},":man_supervillain:":{uc_base:"1f9b9-2642",uc_full:"1f9b9-200d-2642-fe0f",shortnames:[],category:"people"},":man_surfing:":{uc_base:"1f3c4-2642",uc_full:"1f3c4-200d-2642-fe0f",shortnames:[],category:"activity"},":man_swimming:":{uc_base:"1f3ca-2642",uc_full:"1f3ca-200d-2642-fe0f",shortnames:[],category:"activity"},":man_tipping_hand:":{uc_base:"1f481-2642",uc_full:"1f481-200d-2642-fe0f",shortnames:[],category:"people"},":man_vampire:":{uc_base:"1f9db-2642",uc_full:"1f9db-200d-2642-fe0f",shortnames:[],category:"people"},":man_walking:":{uc_base:"1f6b6-2642",uc_full:"1f6b6-200d-2642-fe0f",shortnames:[],category:"people"},":man_wearing_turban:":{uc_base:"1f473-2642",uc_full:"1f473-200d-2642-fe0f",shortnames:[],category:"people"},":man_with_veil:":{uc_base:"1f470-2642",uc_full:"1f470-200d-2642-fe0f",shortnames:[],category:"people"},":man_zombie:":{uc_base:"1f9df-2642",uc_full:"1f9df-200d-2642-fe0f",shortnames:[],category:"people"},":men_with_bunny_ears_partying:":{uc_base:"1f46f-2642",uc_full:"1f46f-200d-2642-fe0f",shortnames:[],category:"people"},":men_wrestling:":{uc_base:"1f93c-2642",uc_full:"1f93c-200d-2642-fe0f",shortnames:[],category:"activity"},":mending_heart:":{uc_base:"2764-1fa79",uc_full:"2764-fe0f-200d-1fa79",shortnames:[],category:"symbols"},":mermaid:":{uc_base:"1f9dc-2640",uc_full:"1f9dc-200d-2640-fe0f",shortnames:[],category:"people"},":merman:":{uc_base:"1f9dc-2642",uc_full:"1f9dc-200d-2642-fe0f",shortnames:[],category:"people"},":person_bouncing_ball_tone1:":{uc_base:"26f9-1f3fb",uc_full:"26f9-1f3fb",shortnames:[":basketball_player_tone1:",":person_with_ball_tone1:"],category:"activity"},":person_bouncing_ball_tone2:":{uc_base:"26f9-1f3fc",uc_full:"26f9-1f3fc",shortnames:[":basketball_player_tone2:",":person_with_ball_tone2:"],category:"activity"},":person_bouncing_ball_tone3:":{uc_base:"26f9-1f3fd",uc_full:"26f9-1f3fd",shortnames:[":basketball_player_tone3:",":person_with_ball_tone3:"],category:"activity"},":person_bouncing_ball_tone4:":{uc_base:"26f9-1f3fe",uc_full:"26f9-1f3fe",shortnames:[":basketball_player_tone4:",":person_with_ball_tone4:"],category:"activity"},":person_bouncing_ball_tone5:":{uc_base:"26f9-1f3ff",uc_full:"26f9-1f3ff",shortnames:[":basketball_player_tone5:",":person_with_ball_tone5:"],category:"activity"},":pilot:":{uc_base:"1f9d1-2708",uc_full:"1f9d1-200d-2708-fe0f",shortnames:[],category:"people"},":pirate_flag:":{uc_base:"1f3f4-2620",uc_full:"1f3f4-200d-2620-fe0f",shortnames:[],category:"flags"},":point_up_tone1:":{uc_base:"261d-1f3fb",uc_full:"261d-1f3fb",shortnames:[],category:"people"},":point_up_tone2:":{uc_base:"261d-1f3fc",uc_full:"261d-1f3fc",shortnames:[],category:"people"},":point_up_tone3:":{uc_base:"261d-1f3fd",uc_full:"261d-1f3fd",shortnames:[],category:"people"},":point_up_tone4:":{uc_base:"261d-1f3fe",uc_full:"261d-1f3fe",shortnames:[],category:"people"},":point_up_tone5:":{uc_base:"261d-1f3ff",uc_full:"261d-1f3ff",shortnames:[],category:"people"},":polar_bear:":{uc_base:"1f43b-2744",uc_full:"1f43b-200d-2744-fe0f",shortnames:[],category:"nature"},":raised_hand_tone1:":{uc_base:"270b-1f3fb",uc_full:"270b-1f3fb",shortnames:[],category:"people"},":raised_hand_tone2:":{uc_base:"270b-1f3fc",uc_full:"270b-1f3fc",shortnames:[],category:"people"},":raised_hand_tone3:":{uc_base:"270b-1f3fd",uc_full:"270b-1f3fd",shortnames:[],category:"people"},":raised_hand_tone4:":{uc_base:"270b-1f3fe",uc_full:"270b-1f3fe",shortnames:[],category:"people"},":raised_hand_tone5:":{uc_base:"270b-1f3ff",uc_full:"270b-1f3ff",shortnames:[],category:"people"},":transgender_flag:":{uc_base:"1f3f3-26a7",uc_full:"1f3f3-fe0f-200d-26a7-fe0f",shortnames:[],category:"flags"},":v_tone1:":{uc_base:"270c-1f3fb",uc_full:"270c-1f3fb",shortnames:[],category:"people"},":v_tone2:":{uc_base:"270c-1f3fc",uc_full:"270c-1f3fc",shortnames:[],category:"people"},":v_tone3:":{uc_base:"270c-1f3fd",uc_full:"270c-1f3fd",shortnames:[],category:"people"},":v_tone4:":{uc_base:"270c-1f3fe",uc_full:"270c-1f3fe",shortnames:[],category:"people"},":v_tone5:":{uc_base:"270c-1f3ff",uc_full:"270c-1f3ff",shortnames:[],category:"people"},":woman_beard:":{uc_base:"1f9d4-2640",uc_full:"1f9d4-200d-2640-fe0f",shortnames:[],category:"people"},":woman_biking:":{uc_base:"1f6b4-2640",uc_full:"1f6b4-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_bowing:":{uc_base:"1f647-2640",uc_full:"1f647-200d-2640-fe0f",shortnames:[],category:"people"},":woman_cartwheeling:":{uc_base:"1f938-2640",uc_full:"1f938-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_climbing:":{uc_base:"1f9d7-2640",uc_full:"1f9d7-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_construction_worker:":{uc_base:"1f477-2640",uc_full:"1f477-200d-2640-fe0f",shortnames:[],category:"people"},":woman_detective:":{uc_base:"1f575-2640",uc_full:"1f575-fe0f-200d-2640-fe0f",shortnames:[],category:"people"},":woman_elf:":{uc_base:"1f9dd-2640",uc_full:"1f9dd-200d-2640-fe0f",shortnames:[],category:"people"},":woman_facepalming:":{uc_base:"1f926-2640",uc_full:"1f926-200d-2640-fe0f",shortnames:[],category:"people"},":woman_fairy:":{uc_base:"1f9da-2640",uc_full:"1f9da-200d-2640-fe0f",shortnames:[],category:"people"},":woman_frowning:":{uc_base:"1f64d-2640",uc_full:"1f64d-200d-2640-fe0f",shortnames:[],category:"people"},":woman_genie:":{uc_base:"1f9de-2640",uc_full:"1f9de-200d-2640-fe0f",shortnames:[],category:"people"},":woman_gesturing_no:":{uc_base:"1f645-2640",uc_full:"1f645-200d-2640-fe0f",shortnames:[],category:"people"},":woman_gesturing_ok:":{uc_base:"1f646-2640",uc_full:"1f646-200d-2640-fe0f",shortnames:[],category:"people"},":woman_getting_face_massage:":{uc_base:"1f486-2640",uc_full:"1f486-200d-2640-fe0f",shortnames:[],category:"people"},":woman_getting_haircut:":{uc_base:"1f487-2640",uc_full:"1f487-200d-2640-fe0f",shortnames:[],category:"people"},":woman_golfing:":{uc_base:"1f3cc-2640",uc_full:"1f3cc-fe0f-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_guard:":{uc_base:"1f482-2640",uc_full:"1f482-200d-2640-fe0f",shortnames:[],category:"people"},":woman_health_worker:":{uc_base:"1f469-2695",uc_full:"1f469-200d-2695-fe0f",shortnames:[],category:"people"},":woman_in_lotus_position:":{uc_base:"1f9d8-2640",uc_full:"1f9d8-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_in_steamy_room:":{uc_base:"1f9d6-2640",uc_full:"1f9d6-200d-2640-fe0f",shortnames:[],category:"people"},":woman_in_tuxedo:":{uc_base:"1f935-2640",uc_full:"1f935-200d-2640-fe0f",shortnames:[],category:"people"},":woman_judge:":{uc_base:"1f469-2696",uc_full:"1f469-200d-2696-fe0f",shortnames:[],category:"people"},":woman_juggling:":{uc_base:"1f939-2640",uc_full:"1f939-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_kneeling:":{uc_base:"1f9ce-2640",uc_full:"1f9ce-200d-2640-fe0f",shortnames:[],category:"people"},":woman_lifting_weights:":{uc_base:"1f3cb-2640",uc_full:"1f3cb-fe0f-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_mage:":{uc_base:"1f9d9-2640",uc_full:"1f9d9-200d-2640-fe0f",shortnames:[],category:"people"},":woman_mountain_biking:":{uc_base:"1f6b5-2640",uc_full:"1f6b5-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_pilot:":{uc_base:"1f469-2708",uc_full:"1f469-200d-2708-fe0f",shortnames:[],category:"people"},":woman_playing_handball:":{uc_base:"1f93e-2640",uc_full:"1f93e-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_playing_water_polo:":{uc_base:"1f93d-2640",uc_full:"1f93d-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_police_officer:":{uc_base:"1f46e-2640",uc_full:"1f46e-200d-2640-fe0f",shortnames:[],category:"people"},":woman_pouting:":{uc_base:"1f64e-2640",uc_full:"1f64e-200d-2640-fe0f",shortnames:[],category:"people"},":woman_raising_hand:":{uc_base:"1f64b-2640",uc_full:"1f64b-200d-2640-fe0f",shortnames:[],category:"people"},":woman_rowing_boat:":{uc_base:"1f6a3-2640",uc_full:"1f6a3-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_running:":{uc_base:"1f3c3-2640",uc_full:"1f3c3-200d-2640-fe0f",shortnames:[],category:"people"},":woman_shrugging:":{uc_base:"1f937-2640",uc_full:"1f937-200d-2640-fe0f",shortnames:[],category:"people"},":woman_standing:":{uc_base:"1f9cd-2640",uc_full:"1f9cd-200d-2640-fe0f",shortnames:[],category:"people"},":woman_superhero:":{uc_base:"1f9b8-2640",uc_full:"1f9b8-200d-2640-fe0f",shortnames:[],category:"people"},":woman_supervillain:":{uc_base:"1f9b9-2640",uc_full:"1f9b9-200d-2640-fe0f",shortnames:[],category:"people"},":woman_surfing:":{uc_base:"1f3c4-2640",uc_full:"1f3c4-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_swimming:":{uc_base:"1f3ca-2640",uc_full:"1f3ca-200d-2640-fe0f",shortnames:[],category:"activity"},":woman_tipping_hand:":{uc_base:"1f481-2640",uc_full:"1f481-200d-2640-fe0f",shortnames:[],category:"people"},":woman_vampire:":{uc_base:"1f9db-2640",uc_full:"1f9db-200d-2640-fe0f",shortnames:[],category:"people"},":woman_walking:":{uc_base:"1f6b6-2640",uc_full:"1f6b6-200d-2640-fe0f",shortnames:[],category:"people"},":woman_wearing_turban:":{uc_base:"1f473-2640",uc_full:"1f473-200d-2640-fe0f",shortnames:[],category:"people"},":woman_with_veil:":{uc_base:"1f470-2640",uc_full:"1f470-200d-2640-fe0f",shortnames:[],category:"people"},":woman_zombie:":{uc_base:"1f9df-2640",uc_full:"1f9df-200d-2640-fe0f",shortnames:[],category:"people"},":women_with_bunny_ears_partying:":{uc_base:"1f46f-2640",uc_full:"1f46f-200d-2640-fe0f",shortnames:[],category:"people"},":women_wrestling:":{uc_base:"1f93c-2640",uc_full:"1f93c-200d-2640-fe0f",shortnames:[],category:"activity"},":writing_hand_tone1:":{uc_base:"270d-1f3fb",uc_full:"270d-1f3fb",shortnames:[],category:"people"},":writing_hand_tone2:":{uc_base:"270d-1f3fc",uc_full:"270d-1f3fc",shortnames:[],category:"people"},":writing_hand_tone3:":{uc_base:"270d-1f3fd",uc_full:"270d-1f3fd",shortnames:[],category:"people"},":writing_hand_tone4:":{uc_base:"270d-1f3fe",uc_full:"270d-1f3fe",shortnames:[],category:"people"},":writing_hand_tone5:":{uc_base:"270d-1f3ff",uc_full:"270d-1f3ff",shortnames:[],category:"people"},":asterisk:":{uc_base:"002a-20e3",uc_full:"002a-fe0f-20e3",shortnames:[":keycap_asterisk:"],category:"symbols"},":eight:":{uc_base:"0038-20e3",uc_full:"0038-fe0f-20e3",shortnames:[],category:"symbols"},":five:":{uc_base:"0035-20e3",uc_full:"0035-fe0f-20e3",shortnames:[],category:"symbols"},":four:":{uc_base:"0034-20e3",uc_full:"0034-fe0f-20e3",shortnames:[],category:"symbols"},":hash:":{uc_base:"0023-20e3",uc_full:"0023-fe0f-20e3",shortnames:[],category:"symbols"},":man_bouncing_ball:":{uc_base:"26f9-2642",uc_full:"26f9-fe0f-200d-2642-fe0f",shortnames:[],category:"activity"},":nine:":{uc_base:"0039-20e3",uc_full:"0039-fe0f-20e3",shortnames:[],category:"symbols"},":one:":{uc_base:"0031-20e3",uc_full:"0031-fe0f-20e3",shortnames:[],category:"symbols"},":seven:":{uc_base:"0037-20e3",uc_full:"0037-fe0f-20e3",shortnames:[],category:"symbols"},":six:":{uc_base:"0036-20e3",uc_full:"0036-fe0f-20e3",shortnames:[],category:"symbols"},":three:":{uc_base:"0033-20e3",uc_full:"0033-fe0f-20e3",shortnames:[],category:"symbols"},":two:":{uc_base:"0032-20e3",uc_full:"0032-fe0f-20e3",shortnames:[],category:"symbols"},":woman_bouncing_ball:":{uc_base:"26f9-2640",uc_full:"26f9-fe0f-200d-2640-fe0f",shortnames:[],category:"activity"},":zero:":{uc_base:"0030-20e3",uc_full:"0030-fe0f-20e3",shortnames:[],category:"symbols"},":100:":{uc_base:"1f4af",uc_full:"1f4af",shortnames:[],category:"symbols"},":1234:":{uc_base:"1f522",uc_full:"1f522",shortnames:[],category:"symbols"},":8ball:":{uc_base:"1f3b1",uc_full:"1f3b1",shortnames:[],category:"activity"},":a:":{uc_base:"1f170",uc_full:"1f170-fe0f",shortnames:[],category:"symbols"},":ab:":{uc_base:"1f18e",uc_full:"1f18e",shortnames:[],category:"symbols"},":abacus:":{uc_base:"1f9ee",uc_full:"1f9ee",shortnames:[],category:"objects"},":abc:":{uc_base:"1f524",uc_full:"1f524",shortnames:[],category:"symbols"},":abcd:":{uc_base:"1f521",uc_full:"1f521",shortnames:[],category:"symbols"},":accept:":{uc_base:"1f251",uc_full:"1f251",shortnames:[],category:"symbols"},":accordion:":{uc_base:"1fa97",uc_full:"1fa97",shortnames:[],category:"activity"},":adhesive_bandage:":{uc_base:"1fa79",uc_full:"1fa79",shortnames:[],category:"objects"},":adult:":{uc_base:"1f9d1",uc_full:"1f9d1",shortnames:[],category:"people"},":aerial_tramway:":{uc_base:"1f6a1",uc_full:"1f6a1",shortnames:[],category:"travel"},":airplane_arriving:":{uc_base:"1f6ec",uc_full:"1f6ec",shortnames:[],category:"travel"},":airplane_departure:":{uc_base:"1f6eb",uc_full:"1f6eb",shortnames:[],category:"travel"},":airplane_small:":{uc_base:"1f6e9",uc_full:"1f6e9-fe0f",shortnames:[":small_airplane:"],category:"travel"},":alien:":{uc_base:"1f47d",uc_full:"1f47d",shortnames:[],category:"people"},":ambulance:":{uc_base:"1f691",uc_full:"1f691",shortnames:[], -category:"travel"},":amphora:":{uc_base:"1f3fa",uc_full:"1f3fa",shortnames:[],category:"objects"},":anatomical_heart:":{uc_base:"1fac0",uc_full:"1fac0",shortnames:[],category:"people"},":angel:":{uc_base:"1f47c",uc_full:"1f47c",shortnames:[],category:"people"},":anger:":{uc_base:"1f4a2",uc_full:"1f4a2",shortnames:[],category:"symbols"},":anger_right:":{uc_base:"1f5ef",uc_full:"1f5ef-fe0f",shortnames:[":right_anger_bubble:"],category:"symbols"},":angry:":{uc_base:"1f620",uc_full:"1f620",shortnames:[],category:"people"},":anguished:":{uc_base:"1f627",uc_full:"1f627",shortnames:[],category:"people"},":ant:":{uc_base:"1f41c",uc_full:"1f41c",shortnames:[],category:"nature"},":apple:":{uc_base:"1f34e",uc_full:"1f34e",shortnames:[],category:"food"},":arrow_down_small:":{uc_base:"1f53d",uc_full:"1f53d",shortnames:[],category:"symbols"},":arrow_up_small:":{uc_base:"1f53c",uc_full:"1f53c",shortnames:[],category:"symbols"},":arrows_clockwise:":{uc_base:"1f503",uc_full:"1f503",shortnames:[],category:"symbols"},":arrows_counterclockwise:":{uc_base:"1f504",uc_full:"1f504",shortnames:[],category:"symbols"},":art:":{uc_base:"1f3a8",uc_full:"1f3a8",shortnames:[],category:"activity"},":articulated_lorry:":{uc_base:"1f69b",uc_full:"1f69b",shortnames:[],category:"travel"},":astonished:":{uc_base:"1f632",uc_full:"1f632",shortnames:[],category:"people"},":athletic_shoe:":{uc_base:"1f45f",uc_full:"1f45f",shortnames:[],category:"people"},":atm:":{uc_base:"1f3e7",uc_full:"1f3e7",shortnames:[],category:"symbols"},":auto_rickshaw:":{uc_base:"1f6fa",uc_full:"1f6fa",shortnames:[],category:"travel"},":avocado:":{uc_base:"1f951",uc_full:"1f951",shortnames:[],category:"food"},":axe:":{uc_base:"1fa93",uc_full:"1fa93",shortnames:[],category:"objects"},":b:":{uc_base:"1f171",uc_full:"1f171-fe0f",shortnames:[],category:"symbols"},":baby:":{uc_base:"1f476",uc_full:"1f476",shortnames:[],category:"people"},":baby_bottle:":{uc_base:"1f37c",uc_full:"1f37c",shortnames:[],category:"food"},":baby_chick:":{uc_base:"1f424",uc_full:"1f424",shortnames:[],category:"nature"},":baby_symbol:":{uc_base:"1f6bc",uc_full:"1f6bc",shortnames:[],category:"symbols"},":back:":{uc_base:"1f519",uc_full:"1f519",shortnames:[],category:"symbols"},":bacon:":{uc_base:"1f953",uc_full:"1f953",shortnames:[],category:"food"},":badger:":{uc_base:"1f9a1",uc_full:"1f9a1",shortnames:[],category:"nature"},":badminton:":{uc_base:"1f3f8",uc_full:"1f3f8",shortnames:[],category:"activity"},":bagel:":{uc_base:"1f96f",uc_full:"1f96f",shortnames:[],category:"food"},":baggage_claim:":{uc_base:"1f6c4",uc_full:"1f6c4",shortnames:[],category:"symbols"},":bald:":{uc_base:"1f9b2",uc_full:"1f9b2",shortnames:[],category:"people"},":ballet_shoes:":{uc_base:"1fa70",uc_full:"1fa70",shortnames:[],category:"activity"},":balloon:":{uc_base:"1f388",uc_full:"1f388",shortnames:[],category:"objects"},":ballot_box:":{uc_base:"1f5f3",uc_full:"1f5f3-fe0f",shortnames:[":ballot_box_with_ballot:"],category:"objects"},":bamboo:":{uc_base:"1f38d",uc_full:"1f38d",shortnames:[],category:"nature"},":banana:":{uc_base:"1f34c",uc_full:"1f34c",shortnames:[],category:"food"},":banjo:":{uc_base:"1fa95",uc_full:"1fa95",shortnames:[],category:"activity"},":bank:":{uc_base:"1f3e6",uc_full:"1f3e6",shortnames:[],category:"travel"},":bar_chart:":{uc_base:"1f4ca",uc_full:"1f4ca",shortnames:[],category:"objects"},":barber:":{uc_base:"1f488",uc_full:"1f488",shortnames:[],category:"objects"},":basket:":{uc_base:"1f9fa",uc_full:"1f9fa",shortnames:[],category:"objects"},":basketball:":{uc_base:"1f3c0",uc_full:"1f3c0",shortnames:[],category:"activity"},":bat:":{uc_base:"1f987",uc_full:"1f987",shortnames:[],category:"nature"},":bath:":{uc_base:"1f6c0",uc_full:"1f6c0",shortnames:[],category:"objects"},":bathtub:":{uc_base:"1f6c1",uc_full:"1f6c1",shortnames:[],category:"objects"},":battery:":{uc_base:"1f50b",uc_full:"1f50b",shortnames:[],category:"objects"},":beach:":{uc_base:"1f3d6",uc_full:"1f3d6-fe0f",shortnames:[":beach_with_umbrella:"],category:"travel"},":bear:":{uc_base:"1f43b",uc_full:"1f43b",shortnames:[],category:"nature"},":bearded_person:":{uc_base:"1f9d4",uc_full:"1f9d4",shortnames:[],category:"people"},":beaver:":{uc_base:"1f9ab",uc_full:"1f9ab",shortnames:[],category:"nature"},":bed:":{uc_base:"1f6cf",uc_full:"1f6cf-fe0f",shortnames:[],category:"objects"},":bee:":{uc_base:"1f41d",uc_full:"1f41d",shortnames:[],category:"nature"},":beer:":{uc_base:"1f37a",uc_full:"1f37a",shortnames:[],category:"food"},":beers:":{uc_base:"1f37b",uc_full:"1f37b",shortnames:[],category:"food"},":beetle:":{uc_base:"1fab2",uc_full:"1fab2",shortnames:[],category:"nature"},":beginner:":{uc_base:"1f530",uc_full:"1f530",shortnames:[],category:"symbols"},":bell:":{uc_base:"1f514",uc_full:"1f514",shortnames:[],category:"symbols"},":bell_pepper:":{uc_base:"1fad1",uc_full:"1fad1",shortnames:[],category:"food"},":bellhop:":{uc_base:"1f6ce",uc_full:"1f6ce-fe0f",shortnames:[":bellhop_bell:"],category:"objects"},":bento:":{uc_base:"1f371",uc_full:"1f371",shortnames:[],category:"food"},":beverage_box:":{uc_base:"1f9c3",uc_full:"1f9c3",shortnames:[],category:"food"},":bike:":{uc_base:"1f6b2",uc_full:"1f6b2",shortnames:[],category:"travel"},":bikini:":{uc_base:"1f459",uc_full:"1f459",shortnames:[],category:"people"},":billed_cap:":{uc_base:"1f9e2",uc_full:"1f9e2",shortnames:[],category:"people"},":bird:":{uc_base:"1f426",uc_full:"1f426",shortnames:[],category:"nature"},":birthday:":{uc_base:"1f382",uc_full:"1f382",shortnames:[],category:"food"},":bison:":{uc_base:"1f9ac",uc_full:"1f9ac",shortnames:[],category:"nature"},":black_heart:":{uc_base:"1f5a4",uc_full:"1f5a4",shortnames:[],category:"symbols"},":black_joker:":{uc_base:"1f0cf",uc_full:"1f0cf",shortnames:[],category:"symbols"},":black_square_button:":{uc_base:"1f532",uc_full:"1f532",shortnames:[],category:"symbols"},":blond_haired_person:":{uc_base:"1f471",uc_full:"1f471",shortnames:[":person_with_blond_hair:"],category:"people"},":blossom:":{uc_base:"1f33c",uc_full:"1f33c",shortnames:[],category:"nature"},":blowfish:":{uc_base:"1f421",uc_full:"1f421",shortnames:[],category:"nature"},":blue_book:":{uc_base:"1f4d8",uc_full:"1f4d8",shortnames:[],category:"objects"},":blue_car:":{uc_base:"1f699",uc_full:"1f699",shortnames:[],category:"travel"},":blue_circle:":{uc_base:"1f535",uc_full:"1f535",shortnames:[],category:"symbols"},":blue_heart:":{uc_base:"1f499",uc_full:"1f499",shortnames:[],category:"symbols"},":blue_square:":{uc_base:"1f7e6",uc_full:"1f7e6",shortnames:[],category:"symbols"},":blueberries:":{uc_base:"1fad0",uc_full:"1fad0",shortnames:[],category:"food"},":blush:":{uc_base:"1f60a",uc_full:"1f60a",shortnames:[],category:"people"},":boar:":{uc_base:"1f417",uc_full:"1f417",shortnames:[],category:"nature"},":bomb:":{uc_base:"1f4a3",uc_full:"1f4a3",shortnames:[],category:"objects"},":bone:":{uc_base:"1f9b4",uc_full:"1f9b4",shortnames:[],category:"people"},":book:":{uc_base:"1f4d6",uc_full:"1f4d6",shortnames:[],category:"objects"},":bookmark:":{uc_base:"1f516",uc_full:"1f516",shortnames:[],category:"objects"},":bookmark_tabs:":{uc_base:"1f4d1",uc_full:"1f4d1",shortnames:[],category:"objects"},":books:":{uc_base:"1f4da",uc_full:"1f4da",shortnames:[],category:"objects"},":boom:":{uc_base:"1f4a5",uc_full:"1f4a5",shortnames:[],category:"nature"},":boomerang:":{uc_base:"1fa83",uc_full:"1fa83",shortnames:[],category:"activity"},":boot:":{uc_base:"1f462",uc_full:"1f462",shortnames:[],category:"people"},":bouquet:":{uc_base:"1f490",uc_full:"1f490",shortnames:[],category:"nature"},":bow_and_arrow:":{uc_base:"1f3f9",uc_full:"1f3f9",shortnames:[":archery:"],category:"activity"},":bowl_with_spoon:":{uc_base:"1f963",uc_full:"1f963",shortnames:[],category:"food"},":bowling:":{uc_base:"1f3b3",uc_full:"1f3b3",shortnames:[],category:"activity"},":boxing_glove:":{uc_base:"1f94a",uc_full:"1f94a",shortnames:[":boxing_gloves:"],category:"activity"},":boy:":{uc_base:"1f466",uc_full:"1f466",shortnames:[],category:"people"},":brain:":{uc_base:"1f9e0",uc_full:"1f9e0",shortnames:[],category:"people"},":bread:":{uc_base:"1f35e",uc_full:"1f35e",shortnames:[],category:"food"},":breast_feeding:":{uc_base:"1f931",uc_full:"1f931",shortnames:[],category:"people"},":bricks:":{uc_base:"1f9f1",uc_full:"1f9f1",shortnames:[],category:"objects"},":bridge_at_night:":{uc_base:"1f309",uc_full:"1f309",shortnames:[],category:"travel"},":briefcase:":{uc_base:"1f4bc",uc_full:"1f4bc",shortnames:[],category:"people"},":briefs:":{uc_base:"1fa72",uc_full:"1fa72",shortnames:[],category:"people"},":broccoli:":{uc_base:"1f966",uc_full:"1f966",shortnames:[],category:"food"},":broken_heart:":{uc_base:"1f494",uc_full:"1f494",shortnames:[],category:"symbols"},":broom:":{uc_base:"1f9f9",uc_full:"1f9f9",shortnames:[],category:"objects"},":brown_circle:":{uc_base:"1f7e4",uc_full:"1f7e4",shortnames:[],category:"symbols"},":brown_heart:":{uc_base:"1f90e",uc_full:"1f90e",shortnames:[],category:"symbols"},":brown_square:":{uc_base:"1f7eb",uc_full:"1f7eb",shortnames:[],category:"symbols"},":bubble_tea:":{uc_base:"1f9cb",uc_full:"1f9cb",shortnames:[],category:"food"},":bucket:":{uc_base:"1faa3",uc_full:"1faa3",shortnames:[],category:"objects"},":bug:":{uc_base:"1f41b",uc_full:"1f41b",shortnames:[],category:"nature"},":bulb:":{uc_base:"1f4a1",uc_full:"1f4a1",shortnames:[],category:"objects"},":bullettrain_front:":{uc_base:"1f685",uc_full:"1f685",shortnames:[],category:"travel"},":bullettrain_side:":{uc_base:"1f684",uc_full:"1f684",shortnames:[],category:"travel"},":burrito:":{uc_base:"1f32f",uc_full:"1f32f",shortnames:[],category:"food"},":bus:":{uc_base:"1f68c",uc_full:"1f68c",shortnames:[],category:"travel"},":busstop:":{uc_base:"1f68f",uc_full:"1f68f",shortnames:[],category:"travel"},":bust_in_silhouette:":{uc_base:"1f464",uc_full:"1f464",shortnames:[],category:"people"},":busts_in_silhouette:":{uc_base:"1f465",uc_full:"1f465",shortnames:[],category:"people"},":butter:":{uc_base:"1f9c8",uc_full:"1f9c8",shortnames:[],category:"food"},":butterfly:":{uc_base:"1f98b",uc_full:"1f98b",shortnames:[],category:"nature"},":cactus:":{uc_base:"1f335",uc_full:"1f335",shortnames:[],category:"nature"},":cake:":{uc_base:"1f370",uc_full:"1f370",shortnames:[],category:"food"},":calendar:":{uc_base:"1f4c6",uc_full:"1f4c6",shortnames:[],category:"objects"},":calendar_spiral:":{uc_base:"1f5d3",uc_full:"1f5d3-fe0f",shortnames:[":spiral_calendar_pad:"],category:"objects"},":call_me:":{uc_base:"1f919",uc_full:"1f919",shortnames:[":call_me_hand:"],category:"people"},":calling:":{uc_base:"1f4f2",uc_full:"1f4f2",shortnames:[],category:"objects"},":camel:":{uc_base:"1f42b",uc_full:"1f42b",shortnames:[],category:"nature"},":camera:":{uc_base:"1f4f7",uc_full:"1f4f7",shortnames:[],category:"objects"},":camera_with_flash:":{uc_base:"1f4f8",uc_full:"1f4f8",shortnames:[],category:"objects"},":camping:":{uc_base:"1f3d5",uc_full:"1f3d5-fe0f",shortnames:[],category:"travel"},":candle:":{uc_base:"1f56f",uc_full:"1f56f-fe0f",shortnames:[],category:"objects"},":candy:":{uc_base:"1f36c",uc_full:"1f36c",shortnames:[],category:"food"},":canned_food:":{uc_base:"1f96b",uc_full:"1f96b",shortnames:[],category:"food"},":canoe:":{uc_base:"1f6f6",uc_full:"1f6f6",shortnames:[":kayak:"],category:"travel"},":capital_abcd:":{uc_base:"1f520",uc_full:"1f520",shortnames:[],category:"symbols"},":card_box:":{uc_base:"1f5c3",uc_full:"1f5c3-fe0f",shortnames:[":card_file_box:"],category:"objects"},":card_index:":{uc_base:"1f4c7",uc_full:"1f4c7",shortnames:[],category:"objects"},":carousel_horse:":{uc_base:"1f3a0",uc_full:"1f3a0",shortnames:[],category:"travel"},":carpentry_saw:":{uc_base:"1fa9a",uc_full:"1fa9a",shortnames:[],category:"objects"},":carrot:":{uc_base:"1f955",uc_full:"1f955",shortnames:[],category:"food"},":cat2:":{uc_base:"1f408",uc_full:"1f408",shortnames:[],category:"nature"},":cat:":{uc_base:"1f431",uc_full:"1f431",shortnames:[],category:"nature"},":cd:":{uc_base:"1f4bf",uc_full:"1f4bf",shortnames:[],category:"objects"},":chair:":{uc_base:"1fa91",uc_full:"1fa91",shortnames:[],category:"objects"},":champagne:":{uc_base:"1f37e",uc_full:"1f37e",shortnames:[":bottle_with_popping_cork:"],category:"food"},":champagne_glass:":{uc_base:"1f942",uc_full:"1f942",shortnames:[":clinking_glass:"],category:"food"},":chart:":{uc_base:"1f4b9",uc_full:"1f4b9",shortnames:[],category:"symbols"},":chart_with_downwards_trend:":{uc_base:"1f4c9",uc_full:"1f4c9",shortnames:[],category:"objects"},":chart_with_upwards_trend:":{uc_base:"1f4c8",uc_full:"1f4c8",shortnames:[],category:"objects"},":checkered_flag:":{uc_base:"1f3c1",uc_full:"1f3c1",shortnames:[],category:"flags"},":cheese:":{uc_base:"1f9c0",uc_full:"1f9c0",shortnames:[":cheese_wedge:"],category:"food"},":cherries:":{uc_base:"1f352",uc_full:"1f352",shortnames:[],category:"food"},":cherry_blossom:":{uc_base:"1f338",uc_full:"1f338",shortnames:[],category:"nature"},":chestnut:":{uc_base:"1f330",uc_full:"1f330",shortnames:[],category:"food"},":chicken:":{uc_base:"1f414",uc_full:"1f414",shortnames:[],category:"nature"},":child:":{uc_base:"1f9d2",uc_full:"1f9d2",shortnames:[],category:"people"},":children_crossing:":{uc_base:"1f6b8",uc_full:"1f6b8",shortnames:[],category:"symbols"},":chipmunk:":{uc_base:"1f43f",uc_full:"1f43f-fe0f",shortnames:[],category:"nature"},":chocolate_bar:":{uc_base:"1f36b",uc_full:"1f36b",shortnames:[],category:"food"},":chopsticks:":{uc_base:"1f962",uc_full:"1f962",shortnames:[],category:"food"},":christmas_tree:":{uc_base:"1f384",uc_full:"1f384",shortnames:[],category:"nature"},":cinema:":{uc_base:"1f3a6",uc_full:"1f3a6",shortnames:[],category:"symbols"},":circus_tent:":{uc_base:"1f3aa",uc_full:"1f3aa",shortnames:[],category:"activity"},":city_dusk:":{uc_base:"1f306",uc_full:"1f306",shortnames:[],category:"travel"},":city_sunset:":{uc_base:"1f307",uc_full:"1f307",shortnames:[":city_sunrise:"],category:"travel"},":cityscape:":{uc_base:"1f3d9",uc_full:"1f3d9-fe0f",shortnames:[],category:"travel"},":cl:":{uc_base:"1f191",uc_full:"1f191",shortnames:[],category:"symbols"},":clap:":{uc_base:"1f44f",uc_full:"1f44f",shortnames:[],category:"people"},":clapper:":{uc_base:"1f3ac",uc_full:"1f3ac",shortnames:[],category:"activity"},":classical_building:":{uc_base:"1f3db",uc_full:"1f3db-fe0f",shortnames:[],category:"travel"},":clipboard:":{uc_base:"1f4cb",uc_full:"1f4cb",shortnames:[],category:"objects"},":clock1030:":{uc_base:"1f565",uc_full:"1f565",shortnames:[],category:"symbols"},":clock10:":{uc_base:"1f559",uc_full:"1f559",shortnames:[],category:"symbols"},":clock1130:":{uc_base:"1f566",uc_full:"1f566",shortnames:[],category:"symbols"},":clock11:":{uc_base:"1f55a",uc_full:"1f55a",shortnames:[],category:"symbols"},":clock1230:":{uc_base:"1f567",uc_full:"1f567",shortnames:[],category:"symbols"},":clock12:":{uc_base:"1f55b",uc_full:"1f55b",shortnames:[],category:"symbols"},":clock130:":{uc_base:"1f55c",uc_full:"1f55c",shortnames:[],category:"symbols"},":clock1:":{uc_base:"1f550",uc_full:"1f550",shortnames:[],category:"symbols"},":clock230:":{uc_base:"1f55d",uc_full:"1f55d",shortnames:[],category:"symbols"},":clock2:":{uc_base:"1f551",uc_full:"1f551",shortnames:[],category:"symbols"},":clock330:":{uc_base:"1f55e",uc_full:"1f55e",shortnames:[],category:"symbols"},":clock3:":{uc_base:"1f552",uc_full:"1f552",shortnames:[],category:"symbols"},":clock430:":{uc_base:"1f55f",uc_full:"1f55f",shortnames:[],category:"symbols"},":clock4:":{uc_base:"1f553",uc_full:"1f553",shortnames:[],category:"symbols"},":clock530:":{uc_base:"1f560",uc_full:"1f560",shortnames:[],category:"symbols"},":clock5:":{uc_base:"1f554",uc_full:"1f554",shortnames:[],category:"symbols"},":clock630:":{uc_base:"1f561",uc_full:"1f561",shortnames:[],category:"symbols"},":clock6:":{uc_base:"1f555",uc_full:"1f555",shortnames:[],category:"symbols"},":clock730:":{uc_base:"1f562",uc_full:"1f562",shortnames:[],category:"symbols"},":clock7:":{uc_base:"1f556",uc_full:"1f556",shortnames:[],category:"symbols"},":clock830:":{uc_base:"1f563",uc_full:"1f563",shortnames:[],category:"symbols"},":clock8:":{uc_base:"1f557",uc_full:"1f557",shortnames:[],category:"symbols"},":clock930:":{uc_base:"1f564",uc_full:"1f564",shortnames:[],category:"symbols"},":clock9:":{uc_base:"1f558",uc_full:"1f558",shortnames:[],category:"symbols"},":clock:":{uc_base:"1f570",uc_full:"1f570-fe0f",shortnames:[":mantlepiece_clock:"],category:"objects"},":closed_book:":{uc_base:"1f4d5",uc_full:"1f4d5",shortnames:[],category:"objects"},":closed_lock_with_key:":{uc_base:"1f510",uc_full:"1f510",shortnames:[],category:"objects"},":closed_umbrella:":{uc_base:"1f302",uc_full:"1f302",shortnames:[],category:"people"},":cloud_lightning:":{uc_base:"1f329",uc_full:"1f329-fe0f",shortnames:[":cloud_with_lightning:"],category:"nature"},":cloud_rain:":{uc_base:"1f327",uc_full:"1f327-fe0f",shortnames:[":cloud_with_rain:"],category:"nature"},":cloud_snow:":{uc_base:"1f328",uc_full:"1f328-fe0f",shortnames:[":cloud_with_snow:"],category:"nature"},":cloud_tornado:":{uc_base:"1f32a",uc_full:"1f32a-fe0f",shortnames:[":cloud_with_tornado:"],category:"nature"},":clown:":{uc_base:"1f921",uc_full:"1f921",shortnames:[":clown_face:"],category:"people"},":coat:":{uc_base:"1f9e5",uc_full:"1f9e5",shortnames:[],category:"people"},":cockroach:":{uc_base:"1fab3",uc_full:"1fab3",shortnames:[],category:"nature"},":cocktail:":{uc_base:"1f378",uc_full:"1f378",shortnames:[],category:"food"},":coconut:":{uc_base:"1f965",uc_full:"1f965",shortnames:[],category:"food"},":coin:":{uc_base:"1fa99",uc_full:"1fa99",shortnames:[],category:"objects"},":cold_face:":{uc_base:"1f976",uc_full:"1f976",shortnames:[],category:"people"},":cold_sweat:":{uc_base:"1f630",uc_full:"1f630",shortnames:[],category:"people"},":compass:":{uc_base:"1f9ed",uc_full:"1f9ed",shortnames:[],category:"objects"},":compression:":{uc_base:"1f5dc",uc_full:"1f5dc-fe0f",shortnames:[],category:"objects"},":computer:":{uc_base:"1f4bb",uc_full:"1f4bb",shortnames:[],category:"objects"},":confetti_ball:":{uc_base:"1f38a",uc_full:"1f38a",shortnames:[],category:"objects"},":confounded:":{uc_base:"1f616",uc_full:"1f616",shortnames:[],category:"people"},":confused:":{uc_base:"1f615",uc_full:"1f615",shortnames:[],category:"people"},":construction:":{uc_base:"1f6a7",uc_full:"1f6a7",shortnames:[],category:"travel"},":construction_site:":{uc_base:"1f3d7",uc_full:"1f3d7-fe0f",shortnames:[":building_construction:"],category:"travel"},":construction_worker:":{uc_base:"1f477",uc_full:"1f477",shortnames:[],category:"people"},":control_knobs:":{uc_base:"1f39b",uc_full:"1f39b-fe0f",shortnames:[],category:"objects"},":convenience_store:":{uc_base:"1f3ea",uc_full:"1f3ea",shortnames:[],category:"travel"},":cookie:":{uc_base:"1f36a",uc_full:"1f36a",shortnames:[],category:"food"},":cooking:":{uc_base:"1f373",uc_full:"1f373",shortnames:[],category:"food"},":cool:":{uc_base:"1f192",uc_full:"1f192",shortnames:[],category:"symbols"},":corn:":{uc_base:"1f33d",uc_full:"1f33d",shortnames:[],category:"food"},":couch:":{uc_base:"1f6cb",uc_full:"1f6cb-fe0f",shortnames:[":couch_and_lamp:"],category:"objects"},":couple:":{uc_base:"1f46b",uc_full:"1f46b",shortnames:[],category:"people"},":couple_with_heart:":{uc_base:"1f491",uc_full:"1f491",shortnames:[],category:"people"},":couplekiss:":{uc_base:"1f48f",uc_full:"1f48f",shortnames:[],category:"people"},":cow2:":{uc_base:"1f404",uc_full:"1f404",shortnames:[],category:"nature"},":cow:":{uc_base:"1f42e",uc_full:"1f42e",shortnames:[],category:"nature"},":cowboy:":{uc_base:"1f920",uc_full:"1f920",shortnames:[":face_with_cowboy_hat:"],category:"people"},":crab:":{uc_base:"1f980",uc_full:"1f980",shortnames:[],category:"nature"},":crayon:":{uc_base:"1f58d",uc_full:"1f58d-fe0f",shortnames:[":lower_left_crayon:"],category:"objects"},":credit_card:":{uc_base:"1f4b3",uc_full:"1f4b3",shortnames:[],category:"objects"},":crescent_moon:":{uc_base:"1f319",uc_full:"1f319",shortnames:[],category:"nature"},":cricket:":{uc_base:"1f997",uc_full:"1f997",shortnames:[],category:"nature"},":cricket_game:":{uc_base:"1f3cf",uc_full:"1f3cf",shortnames:[":cricket_bat_ball:"],category:"activity"},":crocodile:":{uc_base:"1f40a",uc_full:"1f40a",shortnames:[],category:"nature"},":croissant:":{uc_base:"1f950",uc_full:"1f950",shortnames:[],category:"food"},":crossed_flags:":{uc_base:"1f38c",uc_full:"1f38c",shortnames:[],category:"flags"},":crown:":{uc_base:"1f451",uc_full:"1f451",shortnames:[],category:"people"},":cruise_ship:":{uc_base:"1f6f3",uc_full:"1f6f3-fe0f",shortnames:[":passenger_ship:"],category:"travel"},":cry:":{uc_base:"1f622",uc_full:"1f622",shortnames:[],category:"people"},":crying_cat_face:":{uc_base:"1f63f",uc_full:"1f63f",shortnames:[],category:"people"},":crystal_ball:":{uc_base:"1f52e",uc_full:"1f52e",shortnames:[],category:"objects"},":cucumber:":{uc_base:"1f952",uc_full:"1f952",shortnames:[],category:"food"},":cup_with_straw:":{uc_base:"1f964",uc_full:"1f964",shortnames:[],category:"food"},":cupcake:":{uc_base:"1f9c1",uc_full:"1f9c1",shortnames:[],category:"food"},":cupid:":{uc_base:"1f498",uc_full:"1f498",shortnames:[],category:"symbols"},":curling_stone:":{uc_base:"1f94c",uc_full:"1f94c",shortnames:[],category:"activity"},":curly_haired:":{uc_base:"1f9b1",uc_full:"1f9b1",shortnames:[],category:"people"},":currency_exchange:":{uc_base:"1f4b1",uc_full:"1f4b1",shortnames:[],category:"symbols"},":curry:":{uc_base:"1f35b",uc_full:"1f35b",shortnames:[],category:"food"},":custard:":{uc_base:"1f36e",uc_full:"1f36e",shortnames:[":pudding:",":flan:"],category:"food"},":customs:":{uc_base:"1f6c3",uc_full:"1f6c3",shortnames:[],category:"symbols"},":cut_of_meat:":{uc_base:"1f969",uc_full:"1f969",shortnames:[],category:"food"},":cyclone:":{uc_base:"1f300",uc_full:"1f300",shortnames:[],category:"symbols"},":dagger:":{uc_base:"1f5e1",uc_full:"1f5e1-fe0f",shortnames:[":dagger_knife:"],category:"objects"},":dancer:":{uc_base:"1f483",uc_full:"1f483",shortnames:[],category:"people"},":dango:":{uc_base:"1f361",uc_full:"1f361",shortnames:[],category:"food"},":dark_sunglasses:":{uc_base:"1f576",uc_full:"1f576-fe0f",shortnames:[],category:"people"},":dart:":{uc_base:"1f3af",uc_full:"1f3af",shortnames:[],category:"activity"},":dash:":{uc_base:"1f4a8",uc_full:"1f4a8",shortnames:[],category:"nature"},":date:":{uc_base:"1f4c5",uc_full:"1f4c5",shortnames:[],category:"objects"},":deaf_person:":{uc_base:"1f9cf",uc_full:"1f9cf",shortnames:[],category:"people"},":deciduous_tree:":{uc_base:"1f333",uc_full:"1f333",shortnames:[],category:"nature"},":deer:":{uc_base:"1f98c",uc_full:"1f98c",shortnames:[],category:"nature"},":department_store:":{uc_base:"1f3ec",uc_full:"1f3ec",shortnames:[],category:"travel"},":desert:":{uc_base:"1f3dc",uc_full:"1f3dc-fe0f",shortnames:[],category:"travel"},":desktop:":{uc_base:"1f5a5",uc_full:"1f5a5-fe0f",shortnames:[":desktop_computer:"],category:"objects"},":detective:":{uc_base:"1f575",uc_full:"1f575",shortnames:[":spy:",":sleuth_or_spy:"],category:"people"},":diamond_shape_with_a_dot_inside:":{uc_base:"1f4a0",uc_full:"1f4a0",shortnames:[],category:"symbols"},":disappointed:":{uc_base:"1f61e",uc_full:"1f61e",shortnames:[],category:"people"},":disappointed_relieved:":{uc_base:"1f625",uc_full:"1f625",shortnames:[],category:"people"},":disguised_face:":{uc_base:"1f978",uc_full:"1f978",shortnames:[],category:"people"},":dividers:":{uc_base:"1f5c2",uc_full:"1f5c2-fe0f",shortnames:[":card_index_dividers:"],category:"objects"},":diving_mask:":{uc_base:"1f93f",uc_full:"1f93f",shortnames:[],category:"activity"},":diya_lamp:":{uc_base:"1fa94",uc_full:"1fa94",shortnames:[],category:"objects"},":dizzy:":{uc_base:"1f4ab",uc_full:"1f4ab",shortnames:[],category:"nature"},":dizzy_face:":{uc_base:"1f635",uc_full:"1f635",shortnames:[],category:"people"},":dna:":{uc_base:"1f9ec",uc_full:"1f9ec",shortnames:[],category:"objects"},":do_not_litter:":{uc_base:"1f6af",uc_full:"1f6af",shortnames:[],category:"symbols"},":dodo:":{uc_base:"1f9a4",uc_full:"1f9a4",shortnames:[],category:"nature"},":dog2:":{uc_base:"1f415",uc_full:"1f415",shortnames:[],category:"nature"},":dog:":{uc_base:"1f436",uc_full:"1f436",shortnames:[],category:"nature"},":dollar:":{uc_base:"1f4b5",uc_full:"1f4b5",shortnames:[],category:"objects"},":dolls:":{uc_base:"1f38e",uc_full:"1f38e",shortnames:[],category:"objects"},":dolphin:":{uc_base:"1f42c",uc_full:"1f42c",shortnames:[],category:"nature"},":door:":{uc_base:"1f6aa",uc_full:"1f6aa",shortnames:[],category:"objects"},":doughnut:":{uc_base:"1f369",uc_full:"1f369",shortnames:[],category:"food"},":dove:":{uc_base:"1f54a",uc_full:"1f54a-fe0f",shortnames:[":dove_of_peace:"],category:"nature"},":dragon:":{uc_base:"1f409",uc_full:"1f409",shortnames:[],category:"nature"},":dragon_face:":{uc_base:"1f432",uc_full:"1f432",shortnames:[],category:"nature"},":dress:":{uc_base:"1f457",uc_full:"1f457",shortnames:[],category:"people"},":dromedary_camel:":{uc_base:"1f42a",uc_full:"1f42a",shortnames:[],category:"nature"},":drooling_face:":{uc_base:"1f924",uc_full:"1f924",shortnames:[":drool:"],category:"people"},":drop_of_blood:":{uc_base:"1fa78",uc_full:"1fa78",shortnames:[],category:"objects"},":droplet:":{uc_base:"1f4a7",uc_full:"1f4a7",shortnames:[],category:"nature"},":drum:":{uc_base:"1f941",uc_full:"1f941",shortnames:[":drum_with_drumsticks:"],category:"activity"},":duck:":{uc_base:"1f986",uc_full:"1f986",shortnames:[],category:"nature"},":dumpling:":{uc_base:"1f95f",uc_full:"1f95f",shortnames:[],category:"food"},":dvd:":{uc_base:"1f4c0",uc_full:"1f4c0",shortnames:[],category:"objects"},":e-mail:":{uc_base:"1f4e7",uc_full:"1f4e7",shortnames:[":email:"],category:"objects"},":eagle:":{uc_base:"1f985",uc_full:"1f985",shortnames:[],category:"nature"},":ear:":{uc_base:"1f442",uc_full:"1f442",shortnames:[],category:"people"},":ear_of_rice:":{uc_base:"1f33e",uc_full:"1f33e",shortnames:[],category:"nature"},":ear_with_hearing_aid:":{uc_base:"1f9bb",uc_full:"1f9bb",shortnames:[],category:"people"},":earth_africa:":{uc_base:"1f30d",uc_full:"1f30d",shortnames:[],category:"nature"},":earth_americas:":{uc_base:"1f30e",uc_full:"1f30e",shortnames:[],category:"nature"},":earth_asia:":{uc_base:"1f30f",uc_full:"1f30f",shortnames:[],category:"nature"},":egg:":{uc_base:"1f95a",uc_full:"1f95a",shortnames:[],category:"food"},":eggplant:":{uc_base:"1f346",uc_full:"1f346",shortnames:[],category:"food"},":electric_plug:":{uc_base:"1f50c",uc_full:"1f50c",shortnames:[],category:"objects"},":elephant:":{uc_base:"1f418",uc_full:"1f418",shortnames:[],category:"nature"},":elevator:":{uc_base:"1f6d7",uc_full:"1f6d7",shortnames:[],category:"symbols"},":elf:":{uc_base:"1f9dd",uc_full:"1f9dd",shortnames:[],category:"people"},":end:":{uc_base:"1f51a",uc_full:"1f51a",shortnames:[],category:"symbols"},":envelope_with_arrow:":{uc_base:"1f4e9",uc_full:"1f4e9",shortnames:[],category:"objects"},":euro:":{uc_base:"1f4b6",uc_full:"1f4b6",shortnames:[],category:"objects"},":european_castle:":{uc_base:"1f3f0",uc_full:"1f3f0",shortnames:[],category:"travel"},":european_post_office:":{uc_base:"1f3e4",uc_full:"1f3e4",shortnames:[],category:"travel"},":evergreen_tree:":{uc_base:"1f332",uc_full:"1f332",shortnames:[],category:"nature"},":exploding_head:":{uc_base:"1f92f",uc_full:"1f92f",shortnames:[],category:"people"},":expressionless:":{uc_base:"1f611",uc_full:"1f611",shortnames:[],category:"people"},":eye:":{uc_base:"1f441",uc_full:"1f441-fe0f",shortnames:[],category:"people"},":eyeglasses:":{uc_base:"1f453",uc_full:"1f453",shortnames:[],category:"people"},":eyes:":{uc_base:"1f440",uc_full:"1f440",shortnames:[],category:"people"},":face_vomiting:":{uc_base:"1f92e",uc_full:"1f92e",shortnames:[],category:"people"},":face_with_hand_over_mouth:":{uc_base:"1f92d",uc_full:"1f92d",shortnames:[],category:"people"},":face_with_monocle:":{uc_base:"1f9d0",uc_full:"1f9d0",shortnames:[],category:"people"},":face_with_raised_eyebrow:":{uc_base:"1f928",uc_full:"1f928",shortnames:[],category:"people"},":face_with_symbols_over_mouth:":{uc_base:"1f92c",uc_full:"1f92c",shortnames:[],category:"people"},":factory:":{uc_base:"1f3ed",uc_full:"1f3ed",shortnames:[],category:"travel"},":fairy:":{uc_base:"1f9da",uc_full:"1f9da",shortnames:[],category:"people"},":falafel:":{uc_base:"1f9c6",uc_full:"1f9c6",shortnames:[],category:"food"},":fallen_leaf:":{uc_base:"1f342",uc_full:"1f342",shortnames:[],category:"nature"},":family:":{uc_base:"1f46a",uc_full:"1f46a",shortnames:[],category:"people"},":fax:":{uc_base:"1f4e0",uc_full:"1f4e0",shortnames:[],category:"objects"},":fearful:":{uc_base:"1f628",uc_full:"1f628",shortnames:[],category:"people"},":feather:":{uc_base:"1fab6",uc_full:"1fab6",shortnames:[],category:"nature"},":feet:":{uc_base:"1f43e",uc_full:"1f43e",shortnames:[":paw_prints:"],category:"nature"},":ferris_wheel:":{uc_base:"1f3a1",uc_full:"1f3a1",shortnames:[],category:"travel"},":field_hockey:":{uc_base:"1f3d1",uc_full:"1f3d1",shortnames:[],category:"activity"},":file_cabinet:":{uc_base:"1f5c4",uc_full:"1f5c4-fe0f",shortnames:[],category:"objects"},":file_folder:":{uc_base:"1f4c1",uc_full:"1f4c1",shortnames:[],category:"objects"},":film_frames:":{uc_base:"1f39e",uc_full:"1f39e-fe0f",shortnames:[],category:"objects"},":fingers_crossed:":{uc_base:"1f91e",uc_full:"1f91e",shortnames:[":hand_with_index_and_middle_finger_crossed:"],category:"people"},":fire:":{uc_base:"1f525",uc_full:"1f525",shortnames:[":flame:"],category:"nature"},":fire_engine:":{uc_base:"1f692",uc_full:"1f692",shortnames:[],category:"travel"},":fire_extinguisher:":{uc_base:"1f9ef",uc_full:"1f9ef",shortnames:[],category:"objects"},":firecracker:":{uc_base:"1f9e8",uc_full:"1f9e8",shortnames:[],category:"objects"},":fireworks:":{uc_base:"1f386",uc_full:"1f386",shortnames:[],category:"travel"},":first_place:":{uc_base:"1f947",uc_full:"1f947",shortnames:[":first_place_medal:"],category:"activity"},":first_quarter_moon:":{uc_base:"1f313",uc_full:"1f313",shortnames:[],category:"nature"},":first_quarter_moon_with_face:":{uc_base:"1f31b",uc_full:"1f31b",shortnames:[],category:"nature"},":fish:":{uc_base:"1f41f",uc_full:"1f41f",shortnames:[],category:"nature"},":fish_cake:":{uc_base:"1f365",uc_full:"1f365",shortnames:[],category:"food"},":fishing_pole_and_fish:":{uc_base:"1f3a3",uc_full:"1f3a3",shortnames:[],category:"activity"},":flag_black:":{uc_base:"1f3f4",uc_full:"1f3f4",shortnames:[":waving_black_flag:"],category:"flags"},":flag_white:":{uc_base:"1f3f3",uc_full:"1f3f3-fe0f",shortnames:[":waving_white_flag:"],category:"flags"},":flags:":{uc_base:"1f38f",uc_full:"1f38f",shortnames:[],category:"objects"},":flamingo:":{uc_base:"1f9a9",uc_full:"1f9a9",shortnames:[],category:"nature"},":flashlight:":{uc_base:"1f526",uc_full:"1f526",shortnames:[],category:"objects"},":flatbread:":{uc_base:"1fad3",uc_full:"1fad3",shortnames:[],category:"food"},":floppy_disk:":{uc_base:"1f4be",uc_full:"1f4be",shortnames:[],category:"objects"},":flower_playing_cards:":{uc_base:"1f3b4",uc_full:"1f3b4",shortnames:[],category:"symbols"},":flushed:":{uc_base:"1f633",uc_full:"1f633",shortnames:[],category:"people"},":fly:":{uc_base:"1fab0",uc_full:"1fab0",shortnames:[],category:"nature"},":flying_disc:":{uc_base:"1f94f",uc_full:"1f94f",shortnames:[],category:"activity"},":flying_saucer:":{uc_base:"1f6f8",uc_full:"1f6f8",shortnames:[],category:"travel"},":fog:":{uc_base:"1f32b",uc_full:"1f32b-fe0f",shortnames:[],category:"nature"},":foggy:":{uc_base:"1f301",uc_full:"1f301",shortnames:[],category:"travel"},":fondue:":{uc_base:"1fad5",uc_full:"1fad5",shortnames:[],category:"food"},":foot:":{uc_base:"1f9b6",uc_full:"1f9b6",shortnames:[],category:"people"},":football:":{uc_base:"1f3c8",uc_full:"1f3c8",shortnames:[],category:"activity"},":footprints:":{uc_base:"1f463",uc_full:"1f463",shortnames:[],category:"people"},":fork_and_knife:":{uc_base:"1f374",uc_full:"1f374",shortnames:[],category:"food"},":fork_knife_plate:":{uc_base:"1f37d",uc_full:"1f37d-fe0f",shortnames:[":fork_and_knife_with_plate:"],category:"food"},":fortune_cookie:":{uc_base:"1f960",uc_full:"1f960",shortnames:[],category:"food"},":four_leaf_clover:":{uc_base:"1f340",uc_full:"1f340",shortnames:[],category:"nature" -},":fox:":{uc_base:"1f98a",uc_full:"1f98a",shortnames:[":fox_face:"],category:"nature"},":frame_photo:":{uc_base:"1f5bc",uc_full:"1f5bc-fe0f",shortnames:[":frame_with_picture:"],category:"objects"},":free:":{uc_base:"1f193",uc_full:"1f193",shortnames:[],category:"symbols"},":french_bread:":{uc_base:"1f956",uc_full:"1f956",shortnames:[":baguette_bread:"],category:"food"},":fried_shrimp:":{uc_base:"1f364",uc_full:"1f364",shortnames:[],category:"food"},":fries:":{uc_base:"1f35f",uc_full:"1f35f",shortnames:[],category:"food"},":frog:":{uc_base:"1f438",uc_full:"1f438",shortnames:[],category:"nature"},":frowning:":{uc_base:"1f626",uc_full:"1f626",shortnames:[],category:"people"},":full_moon:":{uc_base:"1f315",uc_full:"1f315",shortnames:[],category:"nature"},":full_moon_with_face:":{uc_base:"1f31d",uc_full:"1f31d",shortnames:[],category:"nature"},":game_die:":{uc_base:"1f3b2",uc_full:"1f3b2",shortnames:[],category:"activity"},":garlic:":{uc_base:"1f9c4",uc_full:"1f9c4",shortnames:[],category:"food"},":gem:":{uc_base:"1f48e",uc_full:"1f48e",shortnames:[],category:"objects"},":genie:":{uc_base:"1f9de",uc_full:"1f9de",shortnames:[],category:"people"},":ghost:":{uc_base:"1f47b",uc_full:"1f47b",shortnames:[],category:"people"},":gift:":{uc_base:"1f381",uc_full:"1f381",shortnames:[],category:"objects"},":gift_heart:":{uc_base:"1f49d",uc_full:"1f49d",shortnames:[],category:"symbols"},":giraffe:":{uc_base:"1f992",uc_full:"1f992",shortnames:[],category:"nature"},":girl:":{uc_base:"1f467",uc_full:"1f467",shortnames:[],category:"people"},":globe_with_meridians:":{uc_base:"1f310",uc_full:"1f310",shortnames:[],category:"symbols"},":gloves:":{uc_base:"1f9e4",uc_full:"1f9e4",shortnames:[],category:"people"},":goal:":{uc_base:"1f945",uc_full:"1f945",shortnames:[":goal_net:"],category:"activity"},":goat:":{uc_base:"1f410",uc_full:"1f410",shortnames:[],category:"nature"},":goggles:":{uc_base:"1f97d",uc_full:"1f97d",shortnames:[],category:"people"},":gorilla:":{uc_base:"1f98d",uc_full:"1f98d",shortnames:[],category:"nature"},":grapes:":{uc_base:"1f347",uc_full:"1f347",shortnames:[],category:"food"},":green_apple:":{uc_base:"1f34f",uc_full:"1f34f",shortnames:[],category:"food"},":green_book:":{uc_base:"1f4d7",uc_full:"1f4d7",shortnames:[],category:"objects"},":green_circle:":{uc_base:"1f7e2",uc_full:"1f7e2",shortnames:[],category:"symbols"},":green_heart:":{uc_base:"1f49a",uc_full:"1f49a",shortnames:[],category:"symbols"},":green_square:":{uc_base:"1f7e9",uc_full:"1f7e9",shortnames:[],category:"symbols"},":grimacing:":{uc_base:"1f62c",uc_full:"1f62c",shortnames:[],category:"people"},":grin:":{uc_base:"1f601",uc_full:"1f601",shortnames:[],category:"people"},":grinning:":{uc_base:"1f600",uc_full:"1f600",shortnames:[],category:"people"},":guard:":{uc_base:"1f482",uc_full:"1f482",shortnames:[":guardsman:"],category:"people"},":guide_dog:":{uc_base:"1f9ae",uc_full:"1f9ae",shortnames:[],category:"nature"},":guitar:":{uc_base:"1f3b8",uc_full:"1f3b8",shortnames:[],category:"activity"},":gun:":{uc_base:"1f52b",uc_full:"1f52b",shortnames:[],category:"objects"},":hamburger:":{uc_base:"1f354",uc_full:"1f354",shortnames:[],category:"food"},":hammer:":{uc_base:"1f528",uc_full:"1f528",shortnames:[],category:"objects"},":hamster:":{uc_base:"1f439",uc_full:"1f439",shortnames:[],category:"nature"},":hand_splayed:":{uc_base:"1f590",uc_full:"1f590",shortnames:[":raised_hand_with_fingers_splayed:"],category:"people"},":handbag:":{uc_base:"1f45c",uc_full:"1f45c",shortnames:[],category:"people"},":handshake:":{uc_base:"1f91d",uc_full:"1f91d",shortnames:[":shaking_hands:"],category:"people"},":hatched_chick:":{uc_base:"1f425",uc_full:"1f425",shortnames:[],category:"nature"},":hatching_chick:":{uc_base:"1f423",uc_full:"1f423",shortnames:[],category:"nature"},":head_bandage:":{uc_base:"1f915",uc_full:"1f915",shortnames:[":face_with_head_bandage:"],category:"people"},":headphones:":{uc_base:"1f3a7",uc_full:"1f3a7",shortnames:[],category:"activity"},":headstone:":{uc_base:"1faa6",uc_full:"1faa6",shortnames:[],category:"objects"},":hear_no_evil:":{uc_base:"1f649",uc_full:"1f649",shortnames:[],category:"nature"},":heart_decoration:":{uc_base:"1f49f",uc_full:"1f49f",shortnames:[],category:"symbols"},":heart_eyes:":{uc_base:"1f60d",uc_full:"1f60d",shortnames:[],category:"people"},":heart_eyes_cat:":{uc_base:"1f63b",uc_full:"1f63b",shortnames:[],category:"people"},":heartbeat:":{uc_base:"1f493",uc_full:"1f493",shortnames:[],category:"symbols"},":heartpulse:":{uc_base:"1f497",uc_full:"1f497",shortnames:[],category:"symbols"},":heavy_dollar_sign:":{uc_base:"1f4b2",uc_full:"1f4b2",shortnames:[],category:"symbols"},":hedgehog:":{uc_base:"1f994",uc_full:"1f994",shortnames:[],category:"nature"},":helicopter:":{uc_base:"1f681",uc_full:"1f681",shortnames:[],category:"travel"},":herb:":{uc_base:"1f33f",uc_full:"1f33f",shortnames:[],category:"nature"},":hibiscus:":{uc_base:"1f33a",uc_full:"1f33a",shortnames:[],category:"nature"},":high_brightness:":{uc_base:"1f506",uc_full:"1f506",shortnames:[],category:"symbols"},":high_heel:":{uc_base:"1f460",uc_full:"1f460",shortnames:[],category:"people"},":hiking_boot:":{uc_base:"1f97e",uc_full:"1f97e",shortnames:[],category:"people"},":hindu_temple:":{uc_base:"1f6d5",uc_full:"1f6d5",shortnames:[],category:"travel"},":hippopotamus:":{uc_base:"1f99b",uc_full:"1f99b",shortnames:[],category:"nature"},":hockey:":{uc_base:"1f3d2",uc_full:"1f3d2",shortnames:[],category:"activity"},":hole:":{uc_base:"1f573",uc_full:"1f573-fe0f",shortnames:[],category:"objects"},":homes:":{uc_base:"1f3d8",uc_full:"1f3d8-fe0f",shortnames:[":house_buildings:"],category:"travel"},":honey_pot:":{uc_base:"1f36f",uc_full:"1f36f",shortnames:[],category:"food"},":hook:":{uc_base:"1fa9d",uc_full:"1fa9d",shortnames:[],category:"objects"},":horse:":{uc_base:"1f434",uc_full:"1f434",shortnames:[],category:"nature"},":horse_racing:":{uc_base:"1f3c7",uc_full:"1f3c7",shortnames:[],category:"activity"},":hospital:":{uc_base:"1f3e5",uc_full:"1f3e5",shortnames:[],category:"travel"},":hot_face:":{uc_base:"1f975",uc_full:"1f975",shortnames:[],category:"people"},":hot_pepper:":{uc_base:"1f336",uc_full:"1f336-fe0f",shortnames:[],category:"food"},":hotdog:":{uc_base:"1f32d",uc_full:"1f32d",shortnames:[":hot_dog:"],category:"food"},":hotel:":{uc_base:"1f3e8",uc_full:"1f3e8",shortnames:[],category:"travel"},":house:":{uc_base:"1f3e0",uc_full:"1f3e0",shortnames:[],category:"travel"},":house_abandoned:":{uc_base:"1f3da",uc_full:"1f3da-fe0f",shortnames:[":derelict_house_building:"],category:"travel"},":house_with_garden:":{uc_base:"1f3e1",uc_full:"1f3e1",shortnames:[],category:"travel"},":hugging:":{uc_base:"1f917",uc_full:"1f917",shortnames:[":hugging_face:"],category:"people"},":hushed:":{uc_base:"1f62f",uc_full:"1f62f",shortnames:[],category:"people"},":hut:":{uc_base:"1f6d6",uc_full:"1f6d6",shortnames:[],category:"travel"},":ice_cream:":{uc_base:"1f368",uc_full:"1f368",shortnames:[],category:"food"},":ice_cube:":{uc_base:"1f9ca",uc_full:"1f9ca",shortnames:[],category:"food"},":icecream:":{uc_base:"1f366",uc_full:"1f366",shortnames:[],category:"food"},":id:":{uc_base:"1f194",uc_full:"1f194",shortnames:[],category:"symbols"},":ideograph_advantage:":{uc_base:"1f250",uc_full:"1f250",shortnames:[],category:"symbols"},":imp:":{uc_base:"1f47f",uc_full:"1f47f",shortnames:[],category:"people"},":inbox_tray:":{uc_base:"1f4e5",uc_full:"1f4e5",shortnames:[],category:"objects"},":incoming_envelope:":{uc_base:"1f4e8",uc_full:"1f4e8",shortnames:[],category:"objects"},":innocent:":{uc_base:"1f607",uc_full:"1f607",shortnames:[],category:"people"},":island:":{uc_base:"1f3dd",uc_full:"1f3dd-fe0f",shortnames:[":desert_island:"],category:"travel"},":izakaya_lantern:":{uc_base:"1f3ee",uc_full:"1f3ee",shortnames:[],category:"objects"},":jack_o_lantern:":{uc_base:"1f383",uc_full:"1f383",shortnames:[],category:"people"},":japan:":{uc_base:"1f5fe",uc_full:"1f5fe",shortnames:[],category:"travel"},":japanese_castle:":{uc_base:"1f3ef",uc_full:"1f3ef",shortnames:[],category:"travel"},":japanese_goblin:":{uc_base:"1f47a",uc_full:"1f47a",shortnames:[],category:"people"},":japanese_ogre:":{uc_base:"1f479",uc_full:"1f479",shortnames:[],category:"people"},":jeans:":{uc_base:"1f456",uc_full:"1f456",shortnames:[],category:"people"},":jigsaw:":{uc_base:"1f9e9",uc_full:"1f9e9",shortnames:[],category:"activity"},":joy:":{uc_base:"1f602",uc_full:"1f602",shortnames:[],category:"people"},":joy_cat:":{uc_base:"1f639",uc_full:"1f639",shortnames:[],category:"people"},":joystick:":{uc_base:"1f579",uc_full:"1f579-fe0f",shortnames:[],category:"objects"},":kaaba:":{uc_base:"1f54b",uc_full:"1f54b",shortnames:[],category:"travel"},":kangaroo:":{uc_base:"1f998",uc_full:"1f998",shortnames:[],category:"nature"},":key2:":{uc_base:"1f5dd",uc_full:"1f5dd-fe0f",shortnames:[":old_key:"],category:"objects"},":key:":{uc_base:"1f511",uc_full:"1f511",shortnames:[],category:"objects"},":keycap_ten:":{uc_base:"1f51f",uc_full:"1f51f",shortnames:[],category:"symbols"},":kimono:":{uc_base:"1f458",uc_full:"1f458",shortnames:[],category:"people"},":kiss:":{uc_base:"1f48b",uc_full:"1f48b",shortnames:[],category:"people"},":kissing:":{uc_base:"1f617",uc_full:"1f617",shortnames:[],category:"people"},":kissing_cat:":{uc_base:"1f63d",uc_full:"1f63d",shortnames:[],category:"people"},":kissing_closed_eyes:":{uc_base:"1f61a",uc_full:"1f61a",shortnames:[],category:"people"},":kissing_heart:":{uc_base:"1f618",uc_full:"1f618",shortnames:[],category:"people"},":kissing_smiling_eyes:":{uc_base:"1f619",uc_full:"1f619",shortnames:[],category:"people"},":kite:":{uc_base:"1fa81",uc_full:"1fa81",shortnames:[],category:"activity"},":kiwi:":{uc_base:"1f95d",uc_full:"1f95d",shortnames:[":kiwifruit:"],category:"food"},":knife:":{uc_base:"1f52a",uc_full:"1f52a",shortnames:[],category:"objects"},":knot:":{uc_base:"1faa2",uc_full:"1faa2",shortnames:[],category:"objects"},":koala:":{uc_base:"1f428",uc_full:"1f428",shortnames:[],category:"nature"},":koko:":{uc_base:"1f201",uc_full:"1f201",shortnames:[],category:"symbols"},":lab_coat:":{uc_base:"1f97c",uc_full:"1f97c",shortnames:[],category:"people"},":label:":{uc_base:"1f3f7",uc_full:"1f3f7-fe0f",shortnames:[],category:"objects"},":lacrosse:":{uc_base:"1f94d",uc_full:"1f94d",shortnames:[],category:"activity"},":ladder:":{uc_base:"1fa9c",uc_full:"1fa9c",shortnames:[],category:"objects"},":lady_beetle:":{uc_base:"1f41e",uc_full:"1f41e",shortnames:[],category:"nature"},":large_blue_diamond:":{uc_base:"1f537",uc_full:"1f537",shortnames:[],category:"symbols"},":large_orange_diamond:":{uc_base:"1f536",uc_full:"1f536",shortnames:[],category:"symbols"},":last_quarter_moon:":{uc_base:"1f317",uc_full:"1f317",shortnames:[],category:"nature"},":last_quarter_moon_with_face:":{uc_base:"1f31c",uc_full:"1f31c",shortnames:[],category:"nature"},":laughing:":{uc_base:"1f606",uc_full:"1f606",shortnames:[":satisfied:"],category:"people"},":leafy_green:":{uc_base:"1f96c",uc_full:"1f96c",shortnames:[],category:"food"},":leaves:":{uc_base:"1f343",uc_full:"1f343",shortnames:[],category:"nature"},":ledger:":{uc_base:"1f4d2",uc_full:"1f4d2",shortnames:[],category:"objects"},":left_facing_fist:":{uc_base:"1f91b",uc_full:"1f91b",shortnames:[":left_fist:"],category:"people"},":left_luggage:":{uc_base:"1f6c5",uc_full:"1f6c5",shortnames:[],category:"symbols"},":leg:":{uc_base:"1f9b5",uc_full:"1f9b5",shortnames:[],category:"people"},":lemon:":{uc_base:"1f34b",uc_full:"1f34b",shortnames:[],category:"food"},":leopard:":{uc_base:"1f406",uc_full:"1f406",shortnames:[],category:"nature"},":level_slider:":{uc_base:"1f39a",uc_full:"1f39a-fe0f",shortnames:[],category:"objects"},":levitate:":{uc_base:"1f574",uc_full:"1f574-fe0f",shortnames:[":man_in_business_suit_levitating:"],category:"people"},":light_rail:":{uc_base:"1f688",uc_full:"1f688",shortnames:[],category:"travel"},":link:":{uc_base:"1f517",uc_full:"1f517",shortnames:[],category:"objects"},":lion_face:":{uc_base:"1f981",uc_full:"1f981",shortnames:[":lion:"],category:"nature"},":lips:":{uc_base:"1f444",uc_full:"1f444",shortnames:[],category:"people"},":lipstick:":{uc_base:"1f484",uc_full:"1f484",shortnames:[],category:"people"},":lizard:":{uc_base:"1f98e",uc_full:"1f98e",shortnames:[],category:"nature"},":llama:":{uc_base:"1f999",uc_full:"1f999",shortnames:[],category:"nature"},":lobster:":{uc_base:"1f99e",uc_full:"1f99e",shortnames:[],category:"nature"},":lock:":{uc_base:"1f512",uc_full:"1f512",shortnames:[],category:"objects"},":lock_with_ink_pen:":{uc_base:"1f50f",uc_full:"1f50f",shortnames:[],category:"objects"},":lollipop:":{uc_base:"1f36d",uc_full:"1f36d",shortnames:[],category:"food"},":long_drum:":{uc_base:"1fa98",uc_full:"1fa98",shortnames:[],category:"activity"},":loud_sound:":{uc_base:"1f50a",uc_full:"1f50a",shortnames:[],category:"symbols"},":loudspeaker:":{uc_base:"1f4e2",uc_full:"1f4e2",shortnames:[],category:"symbols"},":love_hotel:":{uc_base:"1f3e9",uc_full:"1f3e9",shortnames:[],category:"travel"},":love_letter:":{uc_base:"1f48c",uc_full:"1f48c",shortnames:[],category:"objects"},":love_you_gesture:":{uc_base:"1f91f",uc_full:"1f91f",shortnames:[],category:"people"},":low_brightness:":{uc_base:"1f505",uc_full:"1f505",shortnames:[],category:"symbols"},":luggage:":{uc_base:"1f9f3",uc_full:"1f9f3",shortnames:[],category:"people"},":lungs:":{uc_base:"1fac1",uc_full:"1fac1",shortnames:[],category:"people"},":lying_face:":{uc_base:"1f925",uc_full:"1f925",shortnames:[":liar:"],category:"people"},":mag:":{uc_base:"1f50d",uc_full:"1f50d",shortnames:[],category:"objects"},":mag_right:":{uc_base:"1f50e",uc_full:"1f50e",shortnames:[],category:"objects"},":mage:":{uc_base:"1f9d9",uc_full:"1f9d9",shortnames:[],category:"people"},":magic_wand:":{uc_base:"1fa84",uc_full:"1fa84",shortnames:[],category:"objects"},":magnet:":{uc_base:"1f9f2",uc_full:"1f9f2",shortnames:[],category:"objects"},":mahjong:":{uc_base:"1f004",uc_full:"1f004",shortnames:[],category:"symbols"},":mailbox:":{uc_base:"1f4eb",uc_full:"1f4eb",shortnames:[],category:"objects"},":mailbox_closed:":{uc_base:"1f4ea",uc_full:"1f4ea",shortnames:[],category:"objects"},":mailbox_with_mail:":{uc_base:"1f4ec",uc_full:"1f4ec",shortnames:[],category:"objects"},":mailbox_with_no_mail:":{uc_base:"1f4ed",uc_full:"1f4ed",shortnames:[],category:"objects"},":mammoth:":{uc_base:"1f9a3",uc_full:"1f9a3",shortnames:[],category:"nature"},":man:":{uc_base:"1f468",uc_full:"1f468",shortnames:[],category:"people"},":man_dancing:":{uc_base:"1f57a",uc_full:"1f57a",shortnames:[":male_dancer:"],category:"people"},":man_with_chinese_cap:":{uc_base:"1f472",uc_full:"1f472",shortnames:[":man_with_gua_pi_mao:"],category:"people"},":mango:":{uc_base:"1f96d",uc_full:"1f96d",shortnames:[],category:"food"},":mans_shoe:":{uc_base:"1f45e",uc_full:"1f45e",shortnames:[],category:"people"},":manual_wheelchair:":{uc_base:"1f9bd",uc_full:"1f9bd",shortnames:[],category:"travel"},":map:":{uc_base:"1f5fa",uc_full:"1f5fa-fe0f",shortnames:[":world_map:"],category:"travel"},":maple_leaf:":{uc_base:"1f341",uc_full:"1f341",shortnames:[],category:"nature"},":martial_arts_uniform:":{uc_base:"1f94b",uc_full:"1f94b",shortnames:[":karate_uniform:"],category:"activity"},":mask:":{uc_base:"1f637",uc_full:"1f637",shortnames:[],category:"people"},":mate:":{uc_base:"1f9c9",uc_full:"1f9c9",shortnames:[],category:"food"},":meat_on_bone:":{uc_base:"1f356",uc_full:"1f356",shortnames:[],category:"food"},":mechanical_arm:":{uc_base:"1f9be",uc_full:"1f9be",shortnames:[],category:"people"},":mechanical_leg:":{uc_base:"1f9bf",uc_full:"1f9bf",shortnames:[],category:"people"},":medal:":{uc_base:"1f3c5",uc_full:"1f3c5",shortnames:[":sports_medal:"],category:"activity"},":mega:":{uc_base:"1f4e3",uc_full:"1f4e3",shortnames:[],category:"symbols"},":melon:":{uc_base:"1f348",uc_full:"1f348",shortnames:[],category:"food"},":menorah:":{uc_base:"1f54e",uc_full:"1f54e",shortnames:[],category:"symbols"},":mens:":{uc_base:"1f6b9",uc_full:"1f6b9",shortnames:[],category:"symbols"},":merperson:":{uc_base:"1f9dc",uc_full:"1f9dc",shortnames:[],category:"people"},":metal:":{uc_base:"1f918",uc_full:"1f918",shortnames:[":sign_of_the_horns:"],category:"people"},":metro:":{uc_base:"1f687",uc_full:"1f687",shortnames:[],category:"travel"},":microbe:":{uc_base:"1f9a0",uc_full:"1f9a0",shortnames:[],category:"objects"},":microphone2:":{uc_base:"1f399",uc_full:"1f399-fe0f",shortnames:[":studio_microphone:"],category:"objects"},":microphone:":{uc_base:"1f3a4",uc_full:"1f3a4",shortnames:[],category:"activity"},":microscope:":{uc_base:"1f52c",uc_full:"1f52c",shortnames:[],category:"objects"},":middle_finger:":{uc_base:"1f595",uc_full:"1f595",shortnames:[":reversed_hand_with_middle_finger_extended:"],category:"people"},":military_helmet:":{uc_base:"1fa96",uc_full:"1fa96",shortnames:[],category:"people"},":military_medal:":{uc_base:"1f396",uc_full:"1f396-fe0f",shortnames:[],category:"activity"},":milk:":{uc_base:"1f95b",uc_full:"1f95b",shortnames:[":glass_of_milk:"],category:"food"},":milky_way:":{uc_base:"1f30c",uc_full:"1f30c",shortnames:[],category:"travel"},":minibus:":{uc_base:"1f690",uc_full:"1f690",shortnames:[],category:"travel"},":minidisc:":{uc_base:"1f4bd",uc_full:"1f4bd",shortnames:[],category:"objects"},":mirror:":{uc_base:"1fa9e",uc_full:"1fa9e",shortnames:[],category:"objects"},":mobile_phone:":{uc_base:"1f4f1",uc_full:"1f4f1",shortnames:[],category:"objects"},":mobile_phone_off:":{uc_base:"1f4f4",uc_full:"1f4f4",shortnames:[],category:"symbols"},":money_mouth:":{uc_base:"1f911",uc_full:"1f911",shortnames:[":money_mouth_face:"],category:"people"},":money_with_wings:":{uc_base:"1f4b8",uc_full:"1f4b8",shortnames:[],category:"objects"},":moneybag:":{uc_base:"1f4b0",uc_full:"1f4b0",shortnames:[],category:"objects"},":monkey:":{uc_base:"1f412",uc_full:"1f412",shortnames:[],category:"nature"},":monkey_face:":{uc_base:"1f435",uc_full:"1f435",shortnames:[],category:"nature"},":monorail:":{uc_base:"1f69d",uc_full:"1f69d",shortnames:[],category:"travel"},":moon_cake:":{uc_base:"1f96e",uc_full:"1f96e",shortnames:[],category:"food"},":mortar_board:":{uc_base:"1f393",uc_full:"1f393",shortnames:[],category:"people"},":mosque:":{uc_base:"1f54c",uc_full:"1f54c",shortnames:[],category:"travel"},":mosquito:":{uc_base:"1f99f",uc_full:"1f99f",shortnames:[],category:"nature"},":motor_scooter:":{uc_base:"1f6f5",uc_full:"1f6f5",shortnames:[":motorbike:"],category:"travel"},":motorboat:":{uc_base:"1f6e5",uc_full:"1f6e5-fe0f",shortnames:[],category:"travel"},":motorcycle:":{uc_base:"1f3cd",uc_full:"1f3cd-fe0f",shortnames:[":racing_motorcycle:"],category:"travel"},":motorized_wheelchair:":{uc_base:"1f9bc",uc_full:"1f9bc",shortnames:[],category:"travel"},":motorway:":{uc_base:"1f6e3",uc_full:"1f6e3-fe0f",shortnames:[],category:"travel"},":mount_fuji:":{uc_base:"1f5fb",uc_full:"1f5fb",shortnames:[],category:"travel"},":mountain_cableway:":{uc_base:"1f6a0",uc_full:"1f6a0",shortnames:[],category:"travel"},":mountain_railway:":{uc_base:"1f69e",uc_full:"1f69e",shortnames:[],category:"travel"},":mountain_snow:":{uc_base:"1f3d4",uc_full:"1f3d4-fe0f",shortnames:[":snow_capped_mountain:"],category:"travel"},":mouse2:":{uc_base:"1f401",uc_full:"1f401",shortnames:[],category:"nature"},":mouse:":{uc_base:"1f42d",uc_full:"1f42d",shortnames:[],category:"nature"},":mouse_three_button:":{uc_base:"1f5b1",uc_full:"1f5b1-fe0f",shortnames:[":three_button_mouse:"],category:"objects"},":mouse_trap:":{uc_base:"1faa4",uc_full:"1faa4",shortnames:[],category:"objects"},":movie_camera:":{uc_base:"1f3a5",uc_full:"1f3a5",shortnames:[],category:"objects"},":moyai:":{uc_base:"1f5ff",uc_full:"1f5ff",shortnames:[],category:"travel"},":mrs_claus:":{uc_base:"1f936",uc_full:"1f936",shortnames:[":mother_christmas:"],category:"people"},":muscle:":{uc_base:"1f4aa",uc_full:"1f4aa",shortnames:[],category:"people"},":mushroom:":{uc_base:"1f344",uc_full:"1f344",shortnames:[],category:"nature"},":musical_keyboard:":{uc_base:"1f3b9",uc_full:"1f3b9",shortnames:[],category:"activity"},":musical_note:":{uc_base:"1f3b5",uc_full:"1f3b5",shortnames:[],category:"symbols"},":musical_score:":{uc_base:"1f3bc",uc_full:"1f3bc",shortnames:[],category:"activity"},":mute:":{uc_base:"1f507",uc_full:"1f507",shortnames:[],category:"symbols"},":nail_care:":{uc_base:"1f485",uc_full:"1f485",shortnames:[],category:"people"},":name_badge:":{uc_base:"1f4db",uc_full:"1f4db",shortnames:[],category:"symbols"},":nauseated_face:":{uc_base:"1f922",uc_full:"1f922",shortnames:[":sick:"],category:"people"},":nazar_amulet:":{uc_base:"1f9ff",uc_full:"1f9ff",shortnames:[],category:"objects"},":necktie:":{uc_base:"1f454",uc_full:"1f454",shortnames:[],category:"people"},":nerd:":{uc_base:"1f913",uc_full:"1f913",shortnames:[":nerd_face:"],category:"people"},":nesting_dolls:":{uc_base:"1fa86",uc_full:"1fa86",shortnames:[],category:"objects"},":neutral_face:":{uc_base:"1f610",uc_full:"1f610",shortnames:[],category:"people"},":new:":{uc_base:"1f195",uc_full:"1f195",shortnames:[],category:"symbols"},":new_moon:":{uc_base:"1f311",uc_full:"1f311",shortnames:[],category:"nature"},":new_moon_with_face:":{uc_base:"1f31a",uc_full:"1f31a",shortnames:[],category:"nature"},":newspaper2:":{uc_base:"1f5de",uc_full:"1f5de-fe0f",shortnames:[":rolled_up_newspaper:"],category:"objects"},":newspaper:":{uc_base:"1f4f0",uc_full:"1f4f0",shortnames:[],category:"objects"},":ng:":{uc_base:"1f196",uc_full:"1f196",shortnames:[],category:"symbols"},":night_with_stars:":{uc_base:"1f303",uc_full:"1f303",shortnames:[],category:"travel"},":ninja:":{uc_base:"1f977",uc_full:"1f977",shortnames:[],category:"people"},":no_bell:":{uc_base:"1f515",uc_full:"1f515",shortnames:[],category:"symbols"},":no_bicycles:":{uc_base:"1f6b3",uc_full:"1f6b3",shortnames:[],category:"symbols"},":no_entry_sign:":{uc_base:"1f6ab",uc_full:"1f6ab",shortnames:[],category:"symbols"},":no_mobile_phones:":{uc_base:"1f4f5",uc_full:"1f4f5",shortnames:[],category:"symbols"},":no_mouth:":{uc_base:"1f636",uc_full:"1f636",shortnames:[],category:"people"},":no_pedestrians:":{uc_base:"1f6b7",uc_full:"1f6b7",shortnames:[],category:"symbols"},":no_smoking:":{uc_base:"1f6ad",uc_full:"1f6ad",shortnames:[],category:"symbols"},":non-potable_water:":{uc_base:"1f6b1",uc_full:"1f6b1",shortnames:[],category:"symbols"},":nose:":{uc_base:"1f443",uc_full:"1f443",shortnames:[],category:"people"},":notebook:":{uc_base:"1f4d3",uc_full:"1f4d3",shortnames:[],category:"objects"},":notebook_with_decorative_cover:":{uc_base:"1f4d4",uc_full:"1f4d4",shortnames:[],category:"objects"},":notepad_spiral:":{uc_base:"1f5d2",uc_full:"1f5d2-fe0f",shortnames:[":spiral_note_pad:"],category:"objects"},":notes:":{uc_base:"1f3b6",uc_full:"1f3b6",shortnames:[],category:"symbols"},":nut_and_bolt:":{uc_base:"1f529",uc_full:"1f529",shortnames:[],category:"objects"},":o2:":{uc_base:"1f17e",uc_full:"1f17e-fe0f",shortnames:[],category:"symbols"},":ocean:":{uc_base:"1f30a",uc_full:"1f30a",shortnames:[],category:"nature"},":octagonal_sign:":{uc_base:"1f6d1",uc_full:"1f6d1",shortnames:[":stop_sign:"],category:"symbols"},":octopus:":{uc_base:"1f419",uc_full:"1f419",shortnames:[],category:"nature"},":oden:":{uc_base:"1f362",uc_full:"1f362",shortnames:[],category:"food"},":office:":{uc_base:"1f3e2",uc_full:"1f3e2",shortnames:[],category:"travel"},":oil:":{uc_base:"1f6e2",uc_full:"1f6e2-fe0f",shortnames:[":oil_drum:"],category:"objects"},":ok:":{uc_base:"1f197",uc_full:"1f197",shortnames:[],category:"symbols"},":ok_hand:":{uc_base:"1f44c",uc_full:"1f44c",shortnames:[],category:"people"},":older_adult:":{uc_base:"1f9d3",uc_full:"1f9d3",shortnames:[],category:"people"},":older_man:":{uc_base:"1f474",uc_full:"1f474",shortnames:[],category:"people"},":older_woman:":{uc_base:"1f475",uc_full:"1f475",shortnames:[":grandma:"],category:"people"},":olive:":{uc_base:"1fad2",uc_full:"1fad2",shortnames:[],category:"food"},":om_symbol:":{uc_base:"1f549",uc_full:"1f549-fe0f",shortnames:[],category:"symbols"},":on:":{uc_base:"1f51b",uc_full:"1f51b",shortnames:[],category:"symbols"},":oncoming_automobile:":{uc_base:"1f698",uc_full:"1f698",shortnames:[],category:"travel"},":oncoming_bus:":{uc_base:"1f68d",uc_full:"1f68d",shortnames:[],category:"travel"},":oncoming_police_car:":{uc_base:"1f694",uc_full:"1f694",shortnames:[],category:"travel"},":oncoming_taxi:":{uc_base:"1f696",uc_full:"1f696",shortnames:[],category:"travel"},":one_piece_swimsuit:":{uc_base:"1fa71",uc_full:"1fa71",shortnames:[],category:"people"},":onion:":{uc_base:"1f9c5",uc_full:"1f9c5",shortnames:[],category:"food"},":open_file_folder:":{uc_base:"1f4c2",uc_full:"1f4c2",shortnames:[],category:"objects"},":open_hands:":{uc_base:"1f450",uc_full:"1f450",shortnames:[],category:"people"},":open_mouth:":{uc_base:"1f62e",uc_full:"1f62e",shortnames:[],category:"people"},":orange_book:":{uc_base:"1f4d9",uc_full:"1f4d9",shortnames:[],category:"objects"},":orange_circle:":{uc_base:"1f7e0",uc_full:"1f7e0",shortnames:[],category:"symbols"},":orange_heart:":{uc_base:"1f9e1",uc_full:"1f9e1",shortnames:[],category:"symbols"},":orange_square:":{uc_base:"1f7e7",uc_full:"1f7e7",shortnames:[],category:"symbols"},":orangutan:":{uc_base:"1f9a7",uc_full:"1f9a7",shortnames:[],category:"nature"},":otter:":{uc_base:"1f9a6",uc_full:"1f9a6",shortnames:[],category:"nature"},":outbox_tray:":{uc_base:"1f4e4",uc_full:"1f4e4",shortnames:[],category:"objects"},":owl:":{uc_base:"1f989",uc_full:"1f989",shortnames:[],category:"nature"},":ox:":{uc_base:"1f402",uc_full:"1f402",shortnames:[],category:"nature"},":oyster:":{uc_base:"1f9aa",uc_full:"1f9aa",shortnames:[],category:"food"},":package:":{uc_base:"1f4e6",uc_full:"1f4e6",shortnames:[],category:"objects"},":page_facing_up:":{uc_base:"1f4c4",uc_full:"1f4c4",shortnames:[],category:"objects"},":page_with_curl:":{uc_base:"1f4c3",uc_full:"1f4c3",shortnames:[],category:"objects"},":pager:":{uc_base:"1f4df",uc_full:"1f4df",shortnames:[],category:"objects"},":paintbrush:":{uc_base:"1f58c",uc_full:"1f58c-fe0f",shortnames:[":lower_left_paintbrush:"],category:"objects"},":palm_tree:":{uc_base:"1f334",uc_full:"1f334",shortnames:[],category:"nature"},":palms_up_together:":{uc_base:"1f932",uc_full:"1f932",shortnames:[],category:"people"},":pancakes:":{uc_base:"1f95e",uc_full:"1f95e",shortnames:[],category:"food"},":panda_face:":{uc_base:"1f43c",uc_full:"1f43c",shortnames:[],category:"nature"},":paperclip:":{uc_base:"1f4ce",uc_full:"1f4ce",shortnames:[],category:"objects"},":paperclips:":{uc_base:"1f587",uc_full:"1f587-fe0f",shortnames:[":linked_paperclips:"],category:"objects"},":parachute:":{uc_base:"1fa82",uc_full:"1fa82",shortnames:[],category:"activity"},":park:":{uc_base:"1f3de",uc_full:"1f3de-fe0f",shortnames:[":national_park:"],category:"travel"},":parking:":{uc_base:"1f17f",uc_full:"1f17f-fe0f",shortnames:[],category:"symbols"},":parrot:":{uc_base:"1f99c",uc_full:"1f99c",shortnames:[],category:"nature"},":partying_face:":{uc_base:"1f973",uc_full:"1f973",shortnames:[],category:"people"},":passport_control:":{uc_base:"1f6c2",uc_full:"1f6c2",shortnames:[],category:"symbols"},":peach:":{uc_base:"1f351",uc_full:"1f351",shortnames:[],category:"food"},":peacock:":{uc_base:"1f99a",uc_full:"1f99a",shortnames:[],category:"nature"},":peanuts:":{uc_base:"1f95c",uc_full:"1f95c",shortnames:[":shelled_peanut:"],category:"food"},":pear:":{uc_base:"1f350",uc_full:"1f350",shortnames:[],category:"food"},":pen_ballpoint:":{uc_base:"1f58a",uc_full:"1f58a-fe0f",shortnames:[":lower_left_ballpoint_pen:"],category:"objects"},":pen_fountain:":{uc_base:"1f58b",uc_full:"1f58b-fe0f",shortnames:[":lower_left_fountain_pen:"],category:"objects"},":pencil:":{uc_base:"1f4dd",uc_full:"1f4dd",shortnames:[":memo:"],category:"objects"},":penguin:":{uc_base:"1f427",uc_full:"1f427",shortnames:[],category:"nature"},":pensive:":{uc_base:"1f614",uc_full:"1f614",shortnames:[],category:"people"},":people_hugging:":{uc_base:"1fac2",uc_full:"1fac2",shortnames:[],category:"people"},":people_with_bunny_ears_partying:":{uc_base:"1f46f",uc_full:"1f46f",shortnames:[":dancers:"],category:"people"},":people_wrestling:":{uc_base:"1f93c",uc_full:"1f93c",shortnames:[":wrestlers:",":wrestling:"],category:"activity"},":performing_arts:":{uc_base:"1f3ad",uc_full:"1f3ad",shortnames:[],category:"activity"},":persevere:":{uc_base:"1f623",uc_full:"1f623",shortnames:[],category:"people"},":person_biking:":{uc_base:"1f6b4",uc_full:"1f6b4",shortnames:[":bicyclist:"],category:"activity"},":person_bowing:":{uc_base:"1f647",uc_full:"1f647",shortnames:[":bow:"],category:"people"},":person_climbing:":{uc_base:"1f9d7",uc_full:"1f9d7",shortnames:[],category:"activity"},":person_doing_cartwheel:":{uc_base:"1f938",uc_full:"1f938",shortnames:[":cartwheel:"],category:"activity"},":person_facepalming:":{uc_base:"1f926",uc_full:"1f926",shortnames:[":face_palm:",":facepalm:"],category:"people"},":person_fencing:":{uc_base:"1f93a",uc_full:"1f93a",shortnames:[":fencer:",":fencing:"],category:"activity"},":person_frowning:":{uc_base:"1f64d",uc_full:"1f64d",shortnames:[],category:"people"},":person_gesturing_no:":{uc_base:"1f645",uc_full:"1f645",shortnames:[":no_good:"],category:"people"},":person_gesturing_ok:":{uc_base:"1f646",uc_full:"1f646",shortnames:[":ok_woman:"],category:"people"},":person_getting_haircut:":{uc_base:"1f487",uc_full:"1f487",shortnames:[":haircut:"],category:"people"},":person_getting_massage:":{uc_base:"1f486",uc_full:"1f486",shortnames:[":massage:"],category:"people"},":person_golfing:":{uc_base:"1f3cc",uc_full:"1f3cc",shortnames:[":golfer:"],category:"activity"},":person_in_lotus_position:":{uc_base:"1f9d8",uc_full:"1f9d8",shortnames:[],category:"activity"},":person_in_steamy_room:":{uc_base:"1f9d6",uc_full:"1f9d6",shortnames:[],category:"people"},":person_in_tuxedo:":{uc_base:"1f935",uc_full:"1f935",shortnames:[],category:"people"},":person_juggling:":{uc_base:"1f939",uc_full:"1f939",shortnames:[":juggling:",":juggler:"],category:"activity"},":person_kneeling:":{uc_base:"1f9ce",uc_full:"1f9ce",shortnames:[],category:"people"},":person_lifting_weights:":{uc_base:"1f3cb",uc_full:"1f3cb",shortnames:[":lifter:",":weight_lifter:"],category:"activity"},":person_mountain_biking:":{uc_base:"1f6b5",uc_full:"1f6b5",shortnames:[":mountain_bicyclist:"],category:"activity"},":person_playing_handball:":{uc_base:"1f93e",uc_full:"1f93e",shortnames:[":handball:"],category:"activity"},":person_playing_water_polo:":{uc_base:"1f93d",uc_full:"1f93d",shortnames:[":water_polo:"],category:"activity"},":person_pouting:":{uc_base:"1f64e",uc_full:"1f64e",shortnames:[":person_with_pouting_face:"],category:"people"},":person_raising_hand:":{uc_base:"1f64b",uc_full:"1f64b",shortnames:[":raising_hand:"],category:"people"},":person_rowing_boat:":{uc_base:"1f6a3",uc_full:"1f6a3",shortnames:[":rowboat:"],category:"activity"},":person_running:":{uc_base:"1f3c3",uc_full:"1f3c3",shortnames:[":runner:"],category:"people"},":person_shrugging:":{uc_base:"1f937",uc_full:"1f937",shortnames:[":shrug:"],category:"people"},":person_standing:":{uc_base:"1f9cd",uc_full:"1f9cd",shortnames:[],category:"people"},":person_surfing:":{uc_base:"1f3c4",uc_full:"1f3c4",shortnames:[":surfer:"],category:"activity"},":person_swimming:":{uc_base:"1f3ca",uc_full:"1f3ca",shortnames:[":swimmer:"],category:"activity"},":person_tipping_hand:":{uc_base:"1f481",uc_full:"1f481",shortnames:[":information_desk_person:"],category:"people"},":person_walking:":{uc_base:"1f6b6",uc_full:"1f6b6",shortnames:[":walking:"],category:"people"},":person_wearing_turban:":{uc_base:"1f473",uc_full:"1f473",shortnames:[":man_with_turban:"],category:"people"},":person_with_veil:":{uc_base:"1f470",uc_full:"1f470",shortnames:[],category:"people"},":petri_dish:":{uc_base:"1f9eb",uc_full:"1f9eb",shortnames:[],category:"objects"},":pickup_truck:":{uc_base:"1f6fb",uc_full:"1f6fb",shortnames:[],category:"travel"},":pie:":{uc_base:"1f967",uc_full:"1f967",shortnames:[],category:"food"},":pig2:":{uc_base:"1f416",uc_full:"1f416",shortnames:[],category:"nature"},":pig:":{uc_base:"1f437",uc_full:"1f437",shortnames:[],category:"nature"},":pig_nose:":{ -uc_base:"1f43d",uc_full:"1f43d",shortnames:[],category:"nature"},":pill:":{uc_base:"1f48a",uc_full:"1f48a",shortnames:[],category:"objects"},":pinched_fingers:":{uc_base:"1f90c",uc_full:"1f90c",shortnames:[],category:"people"},":pinching_hand:":{uc_base:"1f90f",uc_full:"1f90f",shortnames:[],category:"people"},":pineapple:":{uc_base:"1f34d",uc_full:"1f34d",shortnames:[],category:"food"},":ping_pong:":{uc_base:"1f3d3",uc_full:"1f3d3",shortnames:[":table_tennis:"],category:"activity"},":pizza:":{uc_base:"1f355",uc_full:"1f355",shortnames:[],category:"food"},":pi\xf1ata:":{uc_base:"1fa85",uc_full:"1fa85",shortnames:[],category:"objects"},":placard:":{uc_base:"1faa7",uc_full:"1faa7",shortnames:[],category:"objects"},":place_of_worship:":{uc_base:"1f6d0",uc_full:"1f6d0",shortnames:[":worship_symbol:"],category:"symbols"},":pleading_face:":{uc_base:"1f97a",uc_full:"1f97a",shortnames:[],category:"people"},":plunger:":{uc_base:"1faa0",uc_full:"1faa0",shortnames:[],category:"objects"},":point_down:":{uc_base:"1f447",uc_full:"1f447",shortnames:[],category:"people"},":point_left:":{uc_base:"1f448",uc_full:"1f448",shortnames:[],category:"people"},":point_right:":{uc_base:"1f449",uc_full:"1f449",shortnames:[],category:"people"},":point_up_2:":{uc_base:"1f446",uc_full:"1f446",shortnames:[],category:"people"},":police_car:":{uc_base:"1f693",uc_full:"1f693",shortnames:[],category:"travel"},":police_officer:":{uc_base:"1f46e",uc_full:"1f46e",shortnames:[":cop:"],category:"people"},":poodle:":{uc_base:"1f429",uc_full:"1f429",shortnames:[],category:"nature"},":poop:":{uc_base:"1f4a9",uc_full:"1f4a9",shortnames:[":shit:",":hankey:",":poo:"],category:"people"},":popcorn:":{uc_base:"1f37f",uc_full:"1f37f",shortnames:[],category:"food"},":post_office:":{uc_base:"1f3e3",uc_full:"1f3e3",shortnames:[],category:"travel"},":postal_horn:":{uc_base:"1f4ef",uc_full:"1f4ef",shortnames:[],category:"objects"},":postbox:":{uc_base:"1f4ee",uc_full:"1f4ee",shortnames:[],category:"objects"},":potable_water:":{uc_base:"1f6b0",uc_full:"1f6b0",shortnames:[],category:"objects"},":potato:":{uc_base:"1f954",uc_full:"1f954",shortnames:[],category:"food"},":potted_plant:":{uc_base:"1fab4",uc_full:"1fab4",shortnames:[],category:"nature"},":pouch:":{uc_base:"1f45d",uc_full:"1f45d",shortnames:[],category:"people"},":poultry_leg:":{uc_base:"1f357",uc_full:"1f357",shortnames:[],category:"food"},":pound:":{uc_base:"1f4b7",uc_full:"1f4b7",shortnames:[],category:"objects"},":pouting_cat:":{uc_base:"1f63e",uc_full:"1f63e",shortnames:[],category:"people"},":pray:":{uc_base:"1f64f",uc_full:"1f64f",shortnames:[],category:"people"},":prayer_beads:":{uc_base:"1f4ff",uc_full:"1f4ff",shortnames:[],category:"objects"},":pregnant_woman:":{uc_base:"1f930",uc_full:"1f930",shortnames:[":expecting_woman:"],category:"people"},":pretzel:":{uc_base:"1f968",uc_full:"1f968",shortnames:[],category:"food"},":prince:":{uc_base:"1f934",uc_full:"1f934",shortnames:[],category:"people"},":princess:":{uc_base:"1f478",uc_full:"1f478",shortnames:[],category:"people"},":printer:":{uc_base:"1f5a8",uc_full:"1f5a8-fe0f",shortnames:[],category:"objects"},":probing_cane:":{uc_base:"1f9af",uc_full:"1f9af",shortnames:[],category:"travel"},":projector:":{uc_base:"1f4fd",uc_full:"1f4fd-fe0f",shortnames:[":film_projector:"],category:"objects"},":punch:":{uc_base:"1f44a",uc_full:"1f44a",shortnames:[],category:"people"},":purple_circle:":{uc_base:"1f7e3",uc_full:"1f7e3",shortnames:[],category:"symbols"},":purple_heart:":{uc_base:"1f49c",uc_full:"1f49c",shortnames:[],category:"symbols"},":purple_square:":{uc_base:"1f7ea",uc_full:"1f7ea",shortnames:[],category:"symbols"},":purse:":{uc_base:"1f45b",uc_full:"1f45b",shortnames:[],category:"people"},":pushpin:":{uc_base:"1f4cc",uc_full:"1f4cc",shortnames:[],category:"objects"},":put_litter_in_its_place:":{uc_base:"1f6ae",uc_full:"1f6ae",shortnames:[],category:"symbols"},":rabbit2:":{uc_base:"1f407",uc_full:"1f407",shortnames:[],category:"nature"},":rabbit:":{uc_base:"1f430",uc_full:"1f430",shortnames:[],category:"nature"},":raccoon:":{uc_base:"1f99d",uc_full:"1f99d",shortnames:[],category:"nature"},":race_car:":{uc_base:"1f3ce",uc_full:"1f3ce-fe0f",shortnames:[":racing_car:"],category:"travel"},":racehorse:":{uc_base:"1f40e",uc_full:"1f40e",shortnames:[],category:"nature"},":radio:":{uc_base:"1f4fb",uc_full:"1f4fb",shortnames:[],category:"objects"},":radio_button:":{uc_base:"1f518",uc_full:"1f518",shortnames:[],category:"symbols"},":rage:":{uc_base:"1f621",uc_full:"1f621",shortnames:[],category:"people"},":railway_car:":{uc_base:"1f683",uc_full:"1f683",shortnames:[],category:"travel"},":railway_track:":{uc_base:"1f6e4",uc_full:"1f6e4-fe0f",shortnames:[":railroad_track:"],category:"travel"},":rainbow:":{uc_base:"1f308",uc_full:"1f308",shortnames:[],category:"nature"},":raised_back_of_hand:":{uc_base:"1f91a",uc_full:"1f91a",shortnames:[":back_of_hand:"],category:"people"},":raised_hands:":{uc_base:"1f64c",uc_full:"1f64c",shortnames:[],category:"people"},":ram:":{uc_base:"1f40f",uc_full:"1f40f",shortnames:[],category:"nature"},":ramen:":{uc_base:"1f35c",uc_full:"1f35c",shortnames:[],category:"food"},":rat:":{uc_base:"1f400",uc_full:"1f400",shortnames:[],category:"nature"},":razor:":{uc_base:"1fa92",uc_full:"1fa92",shortnames:[],category:"objects"},":receipt:":{uc_base:"1f9fe",uc_full:"1f9fe",shortnames:[],category:"objects"},":red_car:":{uc_base:"1f697",uc_full:"1f697",shortnames:[],category:"travel"},":red_circle:":{uc_base:"1f534",uc_full:"1f534",shortnames:[],category:"symbols"},":red_envelope:":{uc_base:"1f9e7",uc_full:"1f9e7",shortnames:[],category:"objects"},":red_haired:":{uc_base:"1f9b0",uc_full:"1f9b0",shortnames:[],category:"people"},":red_square:":{uc_base:"1f7e5",uc_full:"1f7e5",shortnames:[],category:"symbols"},":regional_indicator_a:":{uc_base:"1f1e6",uc_full:"1f1e6",shortnames:[],category:"regional"},":regional_indicator_b:":{uc_base:"1f1e7",uc_full:"1f1e7",shortnames:[],category:"regional"},":regional_indicator_c:":{uc_base:"1f1e8",uc_full:"1f1e8",shortnames:[],category:"regional"},":regional_indicator_d:":{uc_base:"1f1e9",uc_full:"1f1e9",shortnames:[],category:"regional"},":regional_indicator_e:":{uc_base:"1f1ea",uc_full:"1f1ea",shortnames:[],category:"regional"},":regional_indicator_f:":{uc_base:"1f1eb",uc_full:"1f1eb",shortnames:[],category:"regional"},":regional_indicator_g:":{uc_base:"1f1ec",uc_full:"1f1ec",shortnames:[],category:"regional"},":regional_indicator_h:":{uc_base:"1f1ed",uc_full:"1f1ed",shortnames:[],category:"regional"},":regional_indicator_i:":{uc_base:"1f1ee",uc_full:"1f1ee",shortnames:[],category:"regional"},":regional_indicator_j:":{uc_base:"1f1ef",uc_full:"1f1ef",shortnames:[],category:"regional"},":regional_indicator_k:":{uc_base:"1f1f0",uc_full:"1f1f0",shortnames:[],category:"regional"},":regional_indicator_l:":{uc_base:"1f1f1",uc_full:"1f1f1",shortnames:[],category:"regional"},":regional_indicator_m:":{uc_base:"1f1f2",uc_full:"1f1f2",shortnames:[],category:"regional"},":regional_indicator_n:":{uc_base:"1f1f3",uc_full:"1f1f3",shortnames:[],category:"regional"},":regional_indicator_o:":{uc_base:"1f1f4",uc_full:"1f1f4",shortnames:[],category:"regional"},":regional_indicator_p:":{uc_base:"1f1f5",uc_full:"1f1f5",shortnames:[],category:"regional"},":regional_indicator_q:":{uc_base:"1f1f6",uc_full:"1f1f6",shortnames:[],category:"regional"},":regional_indicator_r:":{uc_base:"1f1f7",uc_full:"1f1f7",shortnames:[],category:"regional"},":regional_indicator_s:":{uc_base:"1f1f8",uc_full:"1f1f8",shortnames:[],category:"regional"},":regional_indicator_t:":{uc_base:"1f1f9",uc_full:"1f1f9",shortnames:[],category:"regional"},":regional_indicator_u:":{uc_base:"1f1fa",uc_full:"1f1fa",shortnames:[],category:"regional"},":regional_indicator_v:":{uc_base:"1f1fb",uc_full:"1f1fb",shortnames:[],category:"regional"},":regional_indicator_w:":{uc_base:"1f1fc",uc_full:"1f1fc",shortnames:[],category:"regional"},":regional_indicator_x:":{uc_base:"1f1fd",uc_full:"1f1fd",shortnames:[],category:"regional"},":regional_indicator_y:":{uc_base:"1f1fe",uc_full:"1f1fe",shortnames:[],category:"regional"},":regional_indicator_z:":{uc_base:"1f1ff",uc_full:"1f1ff",shortnames:[],category:"regional"},":relieved:":{uc_base:"1f60c",uc_full:"1f60c",shortnames:[],category:"people"},":reminder_ribbon:":{uc_base:"1f397",uc_full:"1f397-fe0f",shortnames:[],category:"activity"},":repeat:":{uc_base:"1f501",uc_full:"1f501",shortnames:[],category:"symbols"},":repeat_one:":{uc_base:"1f502",uc_full:"1f502",shortnames:[],category:"symbols"},":restroom:":{uc_base:"1f6bb",uc_full:"1f6bb",shortnames:[],category:"symbols"},":revolving_hearts:":{uc_base:"1f49e",uc_full:"1f49e",shortnames:[],category:"symbols"},":rhino:":{uc_base:"1f98f",uc_full:"1f98f",shortnames:[":rhinoceros:"],category:"nature"},":ribbon:":{uc_base:"1f380",uc_full:"1f380",shortnames:[],category:"objects"},":rice:":{uc_base:"1f35a",uc_full:"1f35a",shortnames:[],category:"food"},":rice_ball:":{uc_base:"1f359",uc_full:"1f359",shortnames:[],category:"food"},":rice_cracker:":{uc_base:"1f358",uc_full:"1f358",shortnames:[],category:"food"},":rice_scene:":{uc_base:"1f391",uc_full:"1f391",shortnames:[],category:"travel"},":right_facing_fist:":{uc_base:"1f91c",uc_full:"1f91c",shortnames:[":right_fist:"],category:"people"},":ring:":{uc_base:"1f48d",uc_full:"1f48d",shortnames:[],category:"people"},":ringed_planet:":{uc_base:"1fa90",uc_full:"1fa90",shortnames:[],category:"nature"},":robot:":{uc_base:"1f916",uc_full:"1f916",shortnames:[":robot_face:"],category:"people"},":rock:":{uc_base:"1faa8",uc_full:"1faa8",shortnames:[],category:"nature"},":rocket:":{uc_base:"1f680",uc_full:"1f680",shortnames:[],category:"travel"},":rofl:":{uc_base:"1f923",uc_full:"1f923",shortnames:[":rolling_on_the_floor_laughing:"],category:"people"},":roll_of_paper:":{uc_base:"1f9fb",uc_full:"1f9fb",shortnames:[],category:"objects"},":roller_coaster:":{uc_base:"1f3a2",uc_full:"1f3a2",shortnames:[],category:"travel"},":roller_skate:":{uc_base:"1f6fc",uc_full:"1f6fc",shortnames:[],category:"activity"},":rolling_eyes:":{uc_base:"1f644",uc_full:"1f644",shortnames:[":face_with_rolling_eyes:"],category:"people"},":rooster:":{uc_base:"1f413",uc_full:"1f413",shortnames:[],category:"nature"},":rose:":{uc_base:"1f339",uc_full:"1f339",shortnames:[],category:"nature"},":rosette:":{uc_base:"1f3f5",uc_full:"1f3f5-fe0f",shortnames:[],category:"activity"},":rotating_light:":{uc_base:"1f6a8",uc_full:"1f6a8",shortnames:[],category:"travel"},":round_pushpin:":{uc_base:"1f4cd",uc_full:"1f4cd",shortnames:[],category:"objects"},":rugby_football:":{uc_base:"1f3c9",uc_full:"1f3c9",shortnames:[],category:"activity"},":running_shirt_with_sash:":{uc_base:"1f3bd",uc_full:"1f3bd",shortnames:[],category:"activity"},":sa:":{uc_base:"1f202",uc_full:"1f202-fe0f",shortnames:[],category:"symbols"},":safety_pin:":{uc_base:"1f9f7",uc_full:"1f9f7",shortnames:[],category:"objects"},":safety_vest:":{uc_base:"1f9ba",uc_full:"1f9ba",shortnames:[],category:"people"},":sake:":{uc_base:"1f376",uc_full:"1f376",shortnames:[],category:"food"},":salad:":{uc_base:"1f957",uc_full:"1f957",shortnames:[":green_salad:"],category:"food"},":salt:":{uc_base:"1f9c2",uc_full:"1f9c2",shortnames:[],category:"food"},":sandal:":{uc_base:"1f461",uc_full:"1f461",shortnames:[],category:"people"},":sandwich:":{uc_base:"1f96a",uc_full:"1f96a",shortnames:[],category:"food"},":santa:":{uc_base:"1f385",uc_full:"1f385",shortnames:[],category:"people"},":sari:":{uc_base:"1f97b",uc_full:"1f97b",shortnames:[],category:"people"},":satellite:":{uc_base:"1f4e1",uc_full:"1f4e1",shortnames:[],category:"objects"},":satellite_orbital:":{uc_base:"1f6f0",uc_full:"1f6f0-fe0f",shortnames:[],category:"travel"},":sauropod:":{uc_base:"1f995",uc_full:"1f995",shortnames:[],category:"nature"},":saxophone:":{uc_base:"1f3b7",uc_full:"1f3b7",shortnames:[],category:"activity"},":scarf:":{uc_base:"1f9e3",uc_full:"1f9e3",shortnames:[],category:"people"},":school:":{uc_base:"1f3eb",uc_full:"1f3eb",shortnames:[],category:"travel"},":school_satchel:":{uc_base:"1f392",uc_full:"1f392",shortnames:[],category:"people"},":scooter:":{uc_base:"1f6f4",uc_full:"1f6f4",shortnames:[],category:"travel"},":scorpion:":{uc_base:"1f982",uc_full:"1f982",shortnames:[],category:"nature"},":scream:":{uc_base:"1f631",uc_full:"1f631",shortnames:[],category:"people"},":scream_cat:":{uc_base:"1f640",uc_full:"1f640",shortnames:[],category:"people"},":screwdriver:":{uc_base:"1fa9b",uc_full:"1fa9b",shortnames:[],category:"objects"},":scroll:":{uc_base:"1f4dc",uc_full:"1f4dc",shortnames:[],category:"objects"},":seal:":{uc_base:"1f9ad",uc_full:"1f9ad",shortnames:[],category:"nature"},":seat:":{uc_base:"1f4ba",uc_full:"1f4ba",shortnames:[],category:"travel"},":second_place:":{uc_base:"1f948",uc_full:"1f948",shortnames:[":second_place_medal:"],category:"activity"},":see_no_evil:":{uc_base:"1f648",uc_full:"1f648",shortnames:[],category:"nature"},":seedling:":{uc_base:"1f331",uc_full:"1f331",shortnames:[],category:"nature"},":selfie:":{uc_base:"1f933",uc_full:"1f933",shortnames:[],category:"people"},":sewing_needle:":{uc_base:"1faa1",uc_full:"1faa1",shortnames:[],category:"objects"},":shallow_pan_of_food:":{uc_base:"1f958",uc_full:"1f958",shortnames:[":paella:"],category:"food"},":shark:":{uc_base:"1f988",uc_full:"1f988",shortnames:[],category:"nature"},":shaved_ice:":{uc_base:"1f367",uc_full:"1f367",shortnames:[],category:"food"},":sheep:":{uc_base:"1f411",uc_full:"1f411",shortnames:[],category:"nature"},":shell:":{uc_base:"1f41a",uc_full:"1f41a",shortnames:[],category:"nature"},":shield:":{uc_base:"1f6e1",uc_full:"1f6e1-fe0f",shortnames:[],category:"objects"},":ship:":{uc_base:"1f6a2",uc_full:"1f6a2",shortnames:[],category:"travel"},":shirt:":{uc_base:"1f455",uc_full:"1f455",shortnames:[],category:"people"},":shopping_bags:":{uc_base:"1f6cd",uc_full:"1f6cd-fe0f",shortnames:[],category:"objects"},":shopping_cart:":{uc_base:"1f6d2",uc_full:"1f6d2",shortnames:[":shopping_trolley:"],category:"objects"},":shorts:":{uc_base:"1fa73",uc_full:"1fa73",shortnames:[],category:"people"},":shower:":{uc_base:"1f6bf",uc_full:"1f6bf",shortnames:[],category:"objects"},":shrimp:":{uc_base:"1f990",uc_full:"1f990",shortnames:[],category:"nature"},":shushing_face:":{uc_base:"1f92b",uc_full:"1f92b",shortnames:[],category:"people"},":signal_strength:":{uc_base:"1f4f6",uc_full:"1f4f6",shortnames:[],category:"symbols"},":six_pointed_star:":{uc_base:"1f52f",uc_full:"1f52f",shortnames:[],category:"symbols"},":skateboard:":{uc_base:"1f6f9",uc_full:"1f6f9",shortnames:[],category:"activity"},":ski:":{uc_base:"1f3bf",uc_full:"1f3bf",shortnames:[],category:"activity"},":skull:":{uc_base:"1f480",uc_full:"1f480",shortnames:[":skeleton:"],category:"people"},":skunk:":{uc_base:"1f9a8",uc_full:"1f9a8",shortnames:[],category:"nature"},":sled:":{uc_base:"1f6f7",uc_full:"1f6f7",shortnames:[],category:"activity"},":sleeping:":{uc_base:"1f634",uc_full:"1f634",shortnames:[],category:"people"},":sleeping_accommodation:":{uc_base:"1f6cc",uc_full:"1f6cc",shortnames:[],category:"objects"},":sleepy:":{uc_base:"1f62a",uc_full:"1f62a",shortnames:[],category:"people"},":slight_frown:":{uc_base:"1f641",uc_full:"1f641",shortnames:[":slightly_frowning_face:"],category:"people"},":slight_smile:":{uc_base:"1f642",uc_full:"1f642",shortnames:[":slightly_smiling_face:"],category:"people"},":slot_machine:":{uc_base:"1f3b0",uc_full:"1f3b0",shortnames:[],category:"activity"},":sloth:":{uc_base:"1f9a5",uc_full:"1f9a5",shortnames:[],category:"nature"},":small_blue_diamond:":{uc_base:"1f539",uc_full:"1f539",shortnames:[],category:"symbols"},":small_orange_diamond:":{uc_base:"1f538",uc_full:"1f538",shortnames:[],category:"symbols"},":small_red_triangle:":{uc_base:"1f53a",uc_full:"1f53a",shortnames:[],category:"symbols"},":small_red_triangle_down:":{uc_base:"1f53b",uc_full:"1f53b",shortnames:[],category:"symbols"},":smile:":{uc_base:"1f604",uc_full:"1f604",shortnames:[],category:"people"},":smile_cat:":{uc_base:"1f638",uc_full:"1f638",shortnames:[],category:"people"},":smiley:":{uc_base:"1f603",uc_full:"1f603",shortnames:[],category:"people"},":smiley_cat:":{uc_base:"1f63a",uc_full:"1f63a",shortnames:[],category:"people"},":smiling_face_with_3_hearts:":{uc_base:"1f970",uc_full:"1f970",shortnames:[],category:"people"},":smiling_face_with_tear:":{uc_base:"1f972",uc_full:"1f972",shortnames:[],category:"people"},":smiling_imp:":{uc_base:"1f608",uc_full:"1f608",shortnames:[],category:"people"},":smirk:":{uc_base:"1f60f",uc_full:"1f60f",shortnames:[],category:"people"},":smirk_cat:":{uc_base:"1f63c",uc_full:"1f63c",shortnames:[],category:"people"},":smoking:":{uc_base:"1f6ac",uc_full:"1f6ac",shortnames:[],category:"objects"},":snail:":{uc_base:"1f40c",uc_full:"1f40c",shortnames:[],category:"nature"},":snake:":{uc_base:"1f40d",uc_full:"1f40d",shortnames:[],category:"nature"},":sneezing_face:":{uc_base:"1f927",uc_full:"1f927",shortnames:[":sneeze:"],category:"people"},":snowboarder:":{uc_base:"1f3c2",uc_full:"1f3c2",shortnames:[],category:"activity"},":soap:":{uc_base:"1f9fc",uc_full:"1f9fc",shortnames:[],category:"objects"},":sob:":{uc_base:"1f62d",uc_full:"1f62d",shortnames:[],category:"people"},":socks:":{uc_base:"1f9e6",uc_full:"1f9e6",shortnames:[],category:"people"},":softball:":{uc_base:"1f94e",uc_full:"1f94e",shortnames:[],category:"activity"},":soon:":{uc_base:"1f51c",uc_full:"1f51c",shortnames:[],category:"symbols"},":sos:":{uc_base:"1f198",uc_full:"1f198",shortnames:[],category:"symbols"},":sound:":{uc_base:"1f509",uc_full:"1f509",shortnames:[],category:"symbols"},":space_invader:":{uc_base:"1f47e",uc_full:"1f47e",shortnames:[],category:"people"},":spaghetti:":{uc_base:"1f35d",uc_full:"1f35d",shortnames:[],category:"food"},":sparkler:":{uc_base:"1f387",uc_full:"1f387",shortnames:[],category:"travel"},":sparkling_heart:":{uc_base:"1f496",uc_full:"1f496",shortnames:[],category:"symbols"},":speak_no_evil:":{uc_base:"1f64a",uc_full:"1f64a",shortnames:[],category:"nature"},":speaker:":{uc_base:"1f508",uc_full:"1f508",shortnames:[],category:"symbols"},":speaking_head:":{uc_base:"1f5e3",uc_full:"1f5e3-fe0f",shortnames:[":speaking_head_in_silhouette:"],category:"people"},":speech_balloon:":{uc_base:"1f4ac",uc_full:"1f4ac",shortnames:[],category:"symbols"},":speech_left:":{uc_base:"1f5e8",uc_full:"1f5e8-fe0f",shortnames:[":left_speech_bubble:"],category:"symbols"},":speedboat:":{uc_base:"1f6a4",uc_full:"1f6a4",shortnames:[],category:"travel"},":spider:":{uc_base:"1f577",uc_full:"1f577-fe0f",shortnames:[],category:"nature"},":spider_web:":{uc_base:"1f578",uc_full:"1f578-fe0f",shortnames:[],category:"nature"},":sponge:":{uc_base:"1f9fd",uc_full:"1f9fd",shortnames:[],category:"objects"},":spoon:":{uc_base:"1f944",uc_full:"1f944",shortnames:[],category:"food"},":squeeze_bottle:":{uc_base:"1f9f4",uc_full:"1f9f4",shortnames:[],category:"objects"},":squid:":{uc_base:"1f991",uc_full:"1f991",shortnames:[],category:"nature"},":stadium:":{uc_base:"1f3df",uc_full:"1f3df-fe0f",shortnames:[],category:"travel"},":star2:":{uc_base:"1f31f",uc_full:"1f31f",shortnames:[],category:"nature"},":star_struck:":{uc_base:"1f929",uc_full:"1f929",shortnames:[],category:"people"},":stars:":{uc_base:"1f320",uc_full:"1f320",shortnames:[],category:"travel"},":station:":{uc_base:"1f689",uc_full:"1f689",shortnames:[],category:"travel"},":statue_of_liberty:":{uc_base:"1f5fd",uc_full:"1f5fd",shortnames:[],category:"travel"},":steam_locomotive:":{uc_base:"1f682",uc_full:"1f682",shortnames:[],category:"travel"},":stethoscope:":{uc_base:"1fa7a",uc_full:"1fa7a",shortnames:[],category:"objects"},":stew:":{uc_base:"1f372",uc_full:"1f372",shortnames:[],category:"food"},":straight_ruler:":{uc_base:"1f4cf",uc_full:"1f4cf",shortnames:[],category:"objects"},":strawberry:":{uc_base:"1f353",uc_full:"1f353",shortnames:[],category:"food"},":stuck_out_tongue:":{uc_base:"1f61b",uc_full:"1f61b",shortnames:[],category:"people"},":stuck_out_tongue_closed_eyes:":{uc_base:"1f61d",uc_full:"1f61d",shortnames:[],category:"people"},":stuck_out_tongue_winking_eye:":{uc_base:"1f61c",uc_full:"1f61c",shortnames:[],category:"people"},":stuffed_flatbread:":{uc_base:"1f959",uc_full:"1f959",shortnames:[":stuffed_pita:"],category:"food"},":sun_with_face:":{uc_base:"1f31e",uc_full:"1f31e",shortnames:[],category:"nature"},":sunflower:":{uc_base:"1f33b",uc_full:"1f33b",shortnames:[],category:"nature"},":sunglasses:":{uc_base:"1f60e",uc_full:"1f60e",shortnames:[],category:"people"},":sunrise:":{uc_base:"1f305",uc_full:"1f305",shortnames:[],category:"travel"},":sunrise_over_mountains:":{uc_base:"1f304",uc_full:"1f304",shortnames:[],category:"travel"},":superhero:":{uc_base:"1f9b8",uc_full:"1f9b8",shortnames:[],category:"people"},":supervillain:":{uc_base:"1f9b9",uc_full:"1f9b9",shortnames:[],category:"people"},":sushi:":{uc_base:"1f363",uc_full:"1f363",shortnames:[],category:"food"},":suspension_railway:":{uc_base:"1f69f",uc_full:"1f69f",shortnames:[],category:"travel"},":swan:":{uc_base:"1f9a2",uc_full:"1f9a2",shortnames:[],category:"nature"},":sweat:":{uc_base:"1f613",uc_full:"1f613",shortnames:[],category:"people"},":sweat_drops:":{uc_base:"1f4a6",uc_full:"1f4a6",shortnames:[],category:"nature"},":sweat_smile:":{uc_base:"1f605",uc_full:"1f605",shortnames:[],category:"people"},":sweet_potato:":{uc_base:"1f360",uc_full:"1f360",shortnames:[],category:"food"},":symbols:":{uc_base:"1f523",uc_full:"1f523",shortnames:[],category:"symbols"},":synagogue:":{uc_base:"1f54d",uc_full:"1f54d",shortnames:[],category:"travel"},":syringe:":{uc_base:"1f489",uc_full:"1f489",shortnames:[],category:"objects"},":t_rex:":{uc_base:"1f996",uc_full:"1f996",shortnames:[],category:"nature"},":taco:":{uc_base:"1f32e",uc_full:"1f32e",shortnames:[],category:"food"},":tada:":{uc_base:"1f389",uc_full:"1f389",shortnames:[],category:"objects"},":takeout_box:":{uc_base:"1f961",uc_full:"1f961",shortnames:[],category:"food"},":tamale:":{uc_base:"1fad4",uc_full:"1fad4",shortnames:[],category:"food"},":tanabata_tree:":{uc_base:"1f38b",uc_full:"1f38b",shortnames:[],category:"nature"},":tangerine:":{uc_base:"1f34a",uc_full:"1f34a",shortnames:[],category:"food"},":taxi:":{uc_base:"1f695",uc_full:"1f695",shortnames:[],category:"travel"},":tea:":{uc_base:"1f375",uc_full:"1f375",shortnames:[],category:"food"},":teapot:":{uc_base:"1fad6",uc_full:"1fad6",shortnames:[],category:"food"},":teddy_bear:":{uc_base:"1f9f8",uc_full:"1f9f8",shortnames:[],category:"objects"},":telephone_receiver:":{uc_base:"1f4de",uc_full:"1f4de",shortnames:[],category:"objects"},":telescope:":{uc_base:"1f52d",uc_full:"1f52d",shortnames:[],category:"objects"},":tennis:":{uc_base:"1f3be",uc_full:"1f3be",shortnames:[],category:"activity"},":test_tube:":{uc_base:"1f9ea",uc_full:"1f9ea",shortnames:[],category:"objects"},":thermometer:":{uc_base:"1f321",uc_full:"1f321-fe0f",shortnames:[],category:"objects"},":thermometer_face:":{uc_base:"1f912",uc_full:"1f912",shortnames:[":face_with_thermometer:"],category:"people"},":thinking:":{uc_base:"1f914",uc_full:"1f914",shortnames:[":thinking_face:"],category:"people"},":third_place:":{uc_base:"1f949",uc_full:"1f949",shortnames:[":third_place_medal:"],category:"activity"},":thong_sandal:":{uc_base:"1fa74",uc_full:"1fa74",shortnames:[],category:"people"},":thought_balloon:":{uc_base:"1f4ad",uc_full:"1f4ad",shortnames:[],category:"symbols"},":thread:":{uc_base:"1f9f5",uc_full:"1f9f5",shortnames:[],category:"people"},":thumbsdown:":{uc_base:"1f44e",uc_full:"1f44e",shortnames:[":-1:",":thumbdown:"],category:"people"},":thumbsup:":{uc_base:"1f44d",uc_full:"1f44d",shortnames:[":+1:",":thumbup:"],category:"people"},":ticket:":{uc_base:"1f3ab",uc_full:"1f3ab",shortnames:[],category:"activity"},":tickets:":{uc_base:"1f39f",uc_full:"1f39f-fe0f",shortnames:[":admission_tickets:"],category:"activity"},":tiger2:":{uc_base:"1f405",uc_full:"1f405",shortnames:[],category:"nature"},":tiger:":{uc_base:"1f42f",uc_full:"1f42f",shortnames:[],category:"nature"},":tired_face:":{uc_base:"1f62b",uc_full:"1f62b",shortnames:[],category:"people"},":toilet:":{uc_base:"1f6bd",uc_full:"1f6bd",shortnames:[],category:"objects"},":tokyo_tower:":{uc_base:"1f5fc",uc_full:"1f5fc",shortnames:[],category:"travel"},":tomato:":{uc_base:"1f345",uc_full:"1f345",shortnames:[],category:"food"},":tone1:":{uc_base:"1f3fb",uc_full:"1f3fb",shortnames:[],category:"modifier"},":tone2:":{uc_base:"1f3fc",uc_full:"1f3fc",shortnames:[],category:"modifier"},":tone3:":{uc_base:"1f3fd",uc_full:"1f3fd",shortnames:[],category:"modifier"},":tone4:":{uc_base:"1f3fe",uc_full:"1f3fe",shortnames:[],category:"modifier"},":tone5:":{uc_base:"1f3ff",uc_full:"1f3ff",shortnames:[],category:"modifier"},":tongue:":{uc_base:"1f445",uc_full:"1f445",shortnames:[],category:"people"},":toolbox:":{uc_base:"1f9f0",uc_full:"1f9f0",shortnames:[],category:"objects"},":tools:":{uc_base:"1f6e0",uc_full:"1f6e0-fe0f",shortnames:[":hammer_and_wrench:"],category:"objects"},":tooth:":{uc_base:"1f9b7",uc_full:"1f9b7",shortnames:[],category:"people"},":toothbrush:":{uc_base:"1faa5",uc_full:"1faa5",shortnames:[],category:"objects"},":top:":{uc_base:"1f51d",uc_full:"1f51d",shortnames:[],category:"symbols"},":tophat:":{uc_base:"1f3a9",uc_full:"1f3a9",shortnames:[],category:"people"},":trackball:":{uc_base:"1f5b2",uc_full:"1f5b2-fe0f",shortnames:[],category:"objects"},":tractor:":{uc_base:"1f69c",uc_full:"1f69c",shortnames:[],category:"travel"},":traffic_light:":{uc_base:"1f6a5",uc_full:"1f6a5",shortnames:[],category:"travel"},":train2:":{uc_base:"1f686",uc_full:"1f686",shortnames:[],category:"travel"},":train:":{uc_base:"1f68b",uc_full:"1f68b",shortnames:[],category:"travel"},":tram:":{uc_base:"1f68a",uc_full:"1f68a",shortnames:[],category:"travel"},":triangular_flag_on_post:":{uc_base:"1f6a9",uc_full:"1f6a9",shortnames:[],category:"flags"},":triangular_ruler:":{uc_base:"1f4d0",uc_full:"1f4d0",shortnames:[],category:"objects"},":trident:":{uc_base:"1f531",uc_full:"1f531",shortnames:[],category:"symbols"},":triumph:":{uc_base:"1f624",uc_full:"1f624",shortnames:[],category:"people"},":trolleybus:":{uc_base:"1f68e",uc_full:"1f68e",shortnames:[],category:"travel"},":trophy:":{uc_base:"1f3c6",uc_full:"1f3c6",shortnames:[],category:"activity"},":tropical_drink:":{uc_base:"1f379",uc_full:"1f379",shortnames:[],category:"food"},":tropical_fish:":{uc_base:"1f420",uc_full:"1f420",shortnames:[],category:"nature"},":truck:":{uc_base:"1f69a",uc_full:"1f69a",shortnames:[],category:"travel"},":trumpet:":{uc_base:"1f3ba",uc_full:"1f3ba",shortnames:[],category:"activity"},":tulip:":{uc_base:"1f337",uc_full:"1f337",shortnames:[],category:"nature"},":tumbler_glass:":{uc_base:"1f943",uc_full:"1f943",shortnames:[":whisky:"],category:"food"},":turkey:":{uc_base:"1f983",uc_full:"1f983",shortnames:[],category:"nature"},":turtle:":{uc_base:"1f422",uc_full:"1f422",shortnames:[],category:"nature"},":tv:":{uc_base:"1f4fa",uc_full:"1f4fa",shortnames:[],category:"objects"},":twisted_rightwards_arrows:":{uc_base:"1f500",uc_full:"1f500",shortnames:[],category:"symbols"},":two_hearts:":{uc_base:"1f495",uc_full:"1f495",shortnames:[],category:"symbols"},":two_men_holding_hands:":{uc_base:"1f46c",uc_full:"1f46c",shortnames:[],category:"people"},":two_women_holding_hands:":{uc_base:"1f46d",uc_full:"1f46d",shortnames:[],category:"people"},":u5272:":{uc_base:"1f239",uc_full:"1f239",shortnames:[],category:"symbols"},":u5408:":{uc_base:"1f234",uc_full:"1f234",shortnames:[],category:"symbols"},":u55b6:":{uc_base:"1f23a",uc_full:"1f23a",shortnames:[],category:"symbols"},":u6307:":{uc_base:"1f22f",uc_full:"1f22f",shortnames:[],category:"symbols"},":u6708:":{uc_base:"1f237",uc_full:"1f237-fe0f",shortnames:[],category:"symbols"},":u6709:":{uc_base:"1f236",uc_full:"1f236",shortnames:[],category:"symbols"},":u6e80:":{uc_base:"1f235",uc_full:"1f235",shortnames:[],category:"symbols"},":u7121:":{uc_base:"1f21a",uc_full:"1f21a",shortnames:[],category:"symbols"},":u7533:":{uc_base:"1f238",uc_full:"1f238",shortnames:[],category:"symbols"},":u7981:":{uc_base:"1f232",uc_full:"1f232",shortnames:[],category:"symbols"},":u7a7a:":{uc_base:"1f233",uc_full:"1f233",shortnames:[],category:"symbols"},":unamused:":{uc_base:"1f612",uc_full:"1f612",shortnames:[],category:"people"},":underage:":{uc_base:"1f51e",uc_full:"1f51e",shortnames:[],category:"symbols"},":unicorn:":{uc_base:"1f984",uc_full:"1f984",shortnames:[":unicorn_face:"],category:"nature"},":unlock:":{uc_base:"1f513",uc_full:"1f513",shortnames:[],category:"objects"},":up:":{uc_base:"1f199",uc_full:"1f199",shortnames:[],category:"symbols"},":upside_down:":{uc_base:"1f643",uc_full:"1f643",shortnames:[":upside_down_face:"],category:"people"},":vampire:":{uc_base:"1f9db",uc_full:"1f9db",shortnames:[],category:"people"},":vertical_traffic_light:":{uc_base:"1f6a6",uc_full:"1f6a6",shortnames:[],category:"travel"},":vhs:":{uc_base:"1f4fc",uc_full:"1f4fc",shortnames:[],category:"objects"},":vibration_mode:":{uc_base:"1f4f3",uc_full:"1f4f3",shortnames:[],category:"symbols"},":video_camera:":{uc_base:"1f4f9",uc_full:"1f4f9",shortnames:[],category:"objects"},":video_game:":{uc_base:"1f3ae",uc_full:"1f3ae",shortnames:[],category:"activity"},":violin:":{uc_base:"1f3bb",uc_full:"1f3bb",shortnames:[],category:"activity"},":volcano:":{uc_base:"1f30b",uc_full:"1f30b",shortnames:[],category:"travel"},":volleyball:":{uc_base:"1f3d0",uc_full:"1f3d0",shortnames:[],category:"activity"},":vs:":{uc_base:"1f19a",uc_full:"1f19a",shortnames:[],category:"symbols"},":vulcan:":{uc_base:"1f596",uc_full:"1f596",shortnames:[":raised_hand_with_part_between_middle_and_ring_fingers:"],category:"people"},":waffle:":{uc_base:"1f9c7",uc_full:"1f9c7",shortnames:[],category:"food"},":waning_crescent_moon:":{uc_base:"1f318",uc_full:"1f318",shortnames:[],category:"nature"},":waning_gibbous_moon:":{uc_base:"1f316",uc_full:"1f316",shortnames:[],category:"nature"},":wastebasket:":{uc_base:"1f5d1",uc_full:"1f5d1-fe0f",shortnames:[],category:"objects"},":water_buffalo:":{uc_base:"1f403",uc_full:"1f403",shortnames:[],category:"nature"},":watermelon:":{uc_base:"1f349",uc_full:"1f349",shortnames:[],category:"food"},":wave:":{uc_base:"1f44b",uc_full:"1f44b",shortnames:[],category:"people"},":waxing_crescent_moon:":{uc_base:"1f312",uc_full:"1f312",shortnames:[],category:"nature"},":waxing_gibbous_moon:":{uc_base:"1f314",uc_full:"1f314",shortnames:[],category:"nature"},":wc:":{uc_base:"1f6be",uc_full:"1f6be",shortnames:[],category:"symbols"},":weary:":{uc_base:"1f629",uc_full:"1f629",shortnames:[],category:"people"},":wedding:":{uc_base:"1f492",uc_full:"1f492",shortnames:[],category:"travel"},":whale2:":{uc_base:"1f40b",uc_full:"1f40b",shortnames:[],category:"nature"},":whale:":{uc_base:"1f433",uc_full:"1f433",shortnames:[],category:"nature"},":white_flower:":{uc_base:"1f4ae",uc_full:"1f4ae",shortnames:[],category:"symbols"},":white_haired:":{uc_base:"1f9b3",uc_full:"1f9b3",shortnames:[],category:"people"},":white_heart:":{uc_base:"1f90d",uc_full:"1f90d",shortnames:[],category:"symbols"},":white_square_button:":{uc_base:"1f533",uc_full:"1f533",shortnames:[],category:"symbols"},":white_sun_cloud:":{uc_base:"1f325",uc_full:"1f325-fe0f",shortnames:[":white_sun_behind_cloud:"],category:"nature"},":white_sun_rain_cloud:":{uc_base:"1f326",uc_full:"1f326-fe0f",shortnames:[":white_sun_behind_cloud_with_rain:"],category:"nature"},":white_sun_small_cloud:":{uc_base:"1f324",uc_full:"1f324-fe0f",shortnames:[":white_sun_with_small_cloud:"],category:"nature"},":wilted_rose:":{uc_base:"1f940",uc_full:"1f940",shortnames:[":wilted_flower:"],category:"nature"},":wind_blowing_face:":{uc_base:"1f32c",uc_full:"1f32c-fe0f",shortnames:[],category:"nature"},":wind_chime:":{uc_base:"1f390",uc_full:"1f390",shortnames:[],category:"objects"},":window:":{uc_base:"1fa9f",uc_full:"1fa9f",shortnames:[],category:"objects"},":wine_glass:":{uc_base:"1f377",uc_full:"1f377",shortnames:[],category:"food"},":wink:":{uc_base:"1f609",uc_full:"1f609",shortnames:[],category:"people"},":wolf:":{uc_base:"1f43a",uc_full:"1f43a",shortnames:[], -category:"nature"},":woman:":{uc_base:"1f469",uc_full:"1f469",shortnames:[],category:"people"},":woman_with_headscarf:":{uc_base:"1f9d5",uc_full:"1f9d5",shortnames:[],category:"people"},":womans_clothes:":{uc_base:"1f45a",uc_full:"1f45a",shortnames:[],category:"people"},":womans_flat_shoe:":{uc_base:"1f97f",uc_full:"1f97f",shortnames:[],category:"people"},":womans_hat:":{uc_base:"1f452",uc_full:"1f452",shortnames:[],category:"people"},":womens:":{uc_base:"1f6ba",uc_full:"1f6ba",shortnames:[],category:"symbols"},":wood:":{uc_base:"1fab5",uc_full:"1fab5",shortnames:[],category:"nature"},":woozy_face:":{uc_base:"1f974",uc_full:"1f974",shortnames:[],category:"people"},":worm:":{uc_base:"1fab1",uc_full:"1fab1",shortnames:[],category:"nature"},":worried:":{uc_base:"1f61f",uc_full:"1f61f",shortnames:[],category:"people"},":wrench:":{uc_base:"1f527",uc_full:"1f527",shortnames:[],category:"objects"},":yarn:":{uc_base:"1f9f6",uc_full:"1f9f6",shortnames:[],category:"people"},":yawning_face:":{uc_base:"1f971",uc_full:"1f971",shortnames:[],category:"people"},":yellow_circle:":{uc_base:"1f7e1",uc_full:"1f7e1",shortnames:[],category:"symbols"},":yellow_heart:":{uc_base:"1f49b",uc_full:"1f49b",shortnames:[],category:"symbols"},":yellow_square:":{uc_base:"1f7e8",uc_full:"1f7e8",shortnames:[],category:"symbols"},":yen:":{uc_base:"1f4b4",uc_full:"1f4b4",shortnames:[],category:"objects"},":yo_yo:":{uc_base:"1fa80",uc_full:"1fa80",shortnames:[],category:"activity"},":yum:":{uc_base:"1f60b",uc_full:"1f60b",shortnames:[],category:"people"},":zany_face:":{uc_base:"1f92a",uc_full:"1f92a",shortnames:[],category:"people"},":zebra:":{uc_base:"1f993",uc_full:"1f993",shortnames:[],category:"nature"},":zipper_mouth:":{uc_base:"1f910",uc_full:"1f910",shortnames:[":zipper_mouth_face:"],category:"people"},":zombie:":{uc_base:"1f9df",uc_full:"1f9df",shortnames:[],category:"people"},":zzz:":{uc_base:"1f4a4",uc_full:"1f4a4",shortnames:[],category:"symbols"},":airplane:":{uc_base:"2708",uc_full:"2708-fe0f",shortnames:[],category:"travel"},":alarm_clock:":{uc_base:"23f0",uc_full:"23f0",shortnames:[],category:"objects"},":alembic:":{uc_base:"2697",uc_full:"2697-fe0f",shortnames:[],category:"objects"},":anchor:":{uc_base:"2693",uc_full:"2693",shortnames:[],category:"travel"},":aquarius:":{uc_base:"2652",uc_full:"2652",shortnames:[],category:"symbols"},":aries:":{uc_base:"2648",uc_full:"2648",shortnames:[],category:"symbols"},":arrow_backward:":{uc_base:"25c0",uc_full:"25c0-fe0f",shortnames:[],category:"symbols"},":arrow_double_down:":{uc_base:"23ec",uc_full:"23ec",shortnames:[],category:"symbols"},":arrow_double_up:":{uc_base:"23eb",uc_full:"23eb",shortnames:[],category:"symbols"},":arrow_down:":{uc_base:"2b07",uc_full:"2b07-fe0f",shortnames:[],category:"symbols"},":arrow_forward:":{uc_base:"25b6",uc_full:"25b6-fe0f",shortnames:[],category:"symbols"},":arrow_heading_down:":{uc_base:"2935",uc_full:"2935-fe0f",shortnames:[],category:"symbols"},":arrow_heading_up:":{uc_base:"2934",uc_full:"2934-fe0f",shortnames:[],category:"symbols"},":arrow_left:":{uc_base:"2b05",uc_full:"2b05-fe0f",shortnames:[],category:"symbols"},":arrow_lower_left:":{uc_base:"2199",uc_full:"2199-fe0f",shortnames:[],category:"symbols"},":arrow_lower_right:":{uc_base:"2198",uc_full:"2198-fe0f",shortnames:[],category:"symbols"},":arrow_right:":{uc_base:"27a1",uc_full:"27a1-fe0f",shortnames:[],category:"symbols"},":arrow_right_hook:":{uc_base:"21aa",uc_full:"21aa-fe0f",shortnames:[],category:"symbols"},":arrow_up:":{uc_base:"2b06",uc_full:"2b06-fe0f",shortnames:[],category:"symbols"},":arrow_up_down:":{uc_base:"2195",uc_full:"2195-fe0f",shortnames:[],category:"symbols"},":arrow_upper_left:":{uc_base:"2196",uc_full:"2196-fe0f",shortnames:[],category:"symbols"},":arrow_upper_right:":{uc_base:"2197",uc_full:"2197-fe0f",shortnames:[],category:"symbols"},":asterisk_symbol:":{uc_base:"002a",uc_full:"002a-fe0f",shortnames:[],category:"symbols"},":atom:":{uc_base:"269b",uc_full:"269b-fe0f",shortnames:[":atom_symbol:"],category:"symbols"},":ballot_box_with_check:":{uc_base:"2611",uc_full:"2611-fe0f",shortnames:[],category:"symbols"},":bangbang:":{uc_base:"203c",uc_full:"203c-fe0f",shortnames:[],category:"symbols"},":baseball:":{uc_base:"26be",uc_full:"26be",shortnames:[],category:"activity"},":beach_umbrella:":{uc_base:"26f1",uc_full:"26f1-fe0f",shortnames:[":umbrella_on_ground:"],category:"travel"},":biohazard:":{uc_base:"2623",uc_full:"2623-fe0f",shortnames:[":biohazard_sign:"],category:"symbols"},":black_circle:":{uc_base:"26ab",uc_full:"26ab",shortnames:[],category:"symbols"},":black_large_square:":{uc_base:"2b1b",uc_full:"2b1b",shortnames:[],category:"symbols"},":black_medium_small_square:":{uc_base:"25fe",uc_full:"25fe",shortnames:[],category:"symbols"},":black_medium_square:":{uc_base:"25fc",uc_full:"25fc-fe0f",shortnames:[],category:"symbols"},":black_nib:":{uc_base:"2712",uc_full:"2712-fe0f",shortnames:[],category:"objects"},":black_small_square:":{uc_base:"25aa",uc_full:"25aa-fe0f",shortnames:[],category:"symbols"},":cancer:":{uc_base:"264b",uc_full:"264b",shortnames:[],category:"symbols"},":capricorn:":{uc_base:"2651",uc_full:"2651",shortnames:[],category:"symbols"},":chains:":{uc_base:"26d3",uc_full:"26d3-fe0f",shortnames:[],category:"objects"},":chess_pawn:":{uc_base:"265f",uc_full:"265f-fe0f",shortnames:[],category:"activity"},":church:":{uc_base:"26ea",uc_full:"26ea",shortnames:[],category:"travel"},":cloud:":{uc_base:"2601",uc_full:"2601-fe0f",shortnames:[],category:"nature"},":clubs:":{uc_base:"2663",uc_full:"2663-fe0f",shortnames:[],category:"symbols"},":coffee:":{uc_base:"2615",uc_full:"2615",shortnames:[],category:"food"},":coffin:":{uc_base:"26b0",uc_full:"26b0-fe0f",shortnames:[],category:"objects"},":comet:":{uc_base:"2604",uc_full:"2604-fe0f",shortnames:[],category:"nature"},":congratulations:":{uc_base:"3297",uc_full:"3297-fe0f",shortnames:[],category:"symbols"},":copyright:":{uc_base:"00a9",uc_full:"00a9-fe0f",shortnames:[],category:"symbols"},":cross:":{uc_base:"271d",uc_full:"271d-fe0f",shortnames:[":latin_cross:"],category:"symbols"},":crossed_swords:":{uc_base:"2694",uc_full:"2694-fe0f",shortnames:[],category:"objects"},":curly_loop:":{uc_base:"27b0",uc_full:"27b0",shortnames:[],category:"symbols"},":diamonds:":{uc_base:"2666",uc_full:"2666-fe0f",shortnames:[],category:"symbols"},":digit_eight:":{uc_base:"0038",uc_full:"0038-fe0f",shortnames:[],category:"symbols"},":digit_five:":{uc_base:"0035",uc_full:"0035-fe0f",shortnames:[],category:"symbols"},":digit_four:":{uc_base:"0034",uc_full:"0034-fe0f",shortnames:[],category:"symbols"},":digit_nine:":{uc_base:"0039",uc_full:"0039-fe0f",shortnames:[],category:"symbols"},":digit_one:":{uc_base:"0031",uc_full:"0031-fe0f",shortnames:[],category:"symbols"},":digit_seven:":{uc_base:"0037",uc_full:"0037-fe0f",shortnames:[],category:"symbols"},":digit_six:":{uc_base:"0036",uc_full:"0036-fe0f",shortnames:[],category:"symbols"},":digit_three:":{uc_base:"0033",uc_full:"0033-fe0f",shortnames:[],category:"symbols"},":digit_two:":{uc_base:"0032",uc_full:"0032-fe0f",shortnames:[],category:"symbols"},":digit_zero:":{uc_base:"0030",uc_full:"0030-fe0f",shortnames:[],category:"symbols"},":eight_pointed_black_star:":{uc_base:"2734",uc_full:"2734-fe0f",shortnames:[],category:"symbols"},":eight_spoked_asterisk:":{uc_base:"2733",uc_full:"2733-fe0f",shortnames:[],category:"symbols"},":eject:":{uc_base:"23cf",uc_full:"23cf-fe0f",shortnames:[":eject_symbol:"],category:"symbols"},":envelope:":{uc_base:"2709",uc_full:"2709-fe0f",shortnames:[],category:"objects"},":exclamation:":{uc_base:"2757",uc_full:"2757",shortnames:[],category:"symbols"},":fast_forward:":{uc_base:"23e9",uc_full:"23e9",shortnames:[],category:"symbols"},":female_sign:":{uc_base:"2640",uc_full:"2640-fe0f",shortnames:[],category:"symbols"},":ferry:":{uc_base:"26f4",uc_full:"26f4-fe0f",shortnames:[],category:"travel"},":fist:":{uc_base:"270a",uc_full:"270a",shortnames:[],category:"people"},":fleur-de-lis:":{uc_base:"269c",uc_full:"269c-fe0f",shortnames:[],category:"symbols"},":fountain:":{uc_base:"26f2",uc_full:"26f2",shortnames:[],category:"travel"},":frowning2:":{uc_base:"2639",uc_full:"2639-fe0f",shortnames:[":white_frowning_face:"],category:"people"},":fuelpump:":{uc_base:"26fd",uc_full:"26fd",shortnames:[],category:"travel"},":gear:":{uc_base:"2699",uc_full:"2699-fe0f",shortnames:[],category:"objects"},":gemini:":{uc_base:"264a",uc_full:"264a",shortnames:[],category:"symbols"},":golf:":{uc_base:"26f3",uc_full:"26f3",shortnames:[],category:"activity"},":grey_exclamation:":{uc_base:"2755",uc_full:"2755",shortnames:[],category:"symbols"},":grey_question:":{uc_base:"2754",uc_full:"2754",shortnames:[],category:"symbols"},":hammer_pick:":{uc_base:"2692",uc_full:"2692-fe0f",shortnames:[":hammer_and_pick:"],category:"objects"},":heart:":{uc_base:"2764",uc_full:"2764-fe0f",shortnames:[],category:"symbols"},":heart_exclamation:":{uc_base:"2763",uc_full:"2763-fe0f",shortnames:[":heavy_heart_exclamation_mark_ornament:"],category:"symbols"},":hearts:":{uc_base:"2665",uc_full:"2665-fe0f",shortnames:[],category:"symbols"},":heavy_check_mark:":{uc_base:"2714",uc_full:"2714-fe0f",shortnames:[],category:"symbols"},":heavy_division_sign:":{uc_base:"2797",uc_full:"2797",shortnames:[],category:"symbols"},":heavy_minus_sign:":{uc_base:"2796",uc_full:"2796",shortnames:[],category:"symbols"},":heavy_multiplication_x:":{uc_base:"2716",uc_full:"2716-fe0f",shortnames:[],category:"symbols"},":heavy_plus_sign:":{uc_base:"2795",uc_full:"2795",shortnames:[],category:"symbols"},":helmet_with_cross:":{uc_base:"26d1",uc_full:"26d1-fe0f",shortnames:[":helmet_with_white_cross:"],category:"people"},":hotsprings:":{uc_base:"2668",uc_full:"2668-fe0f",shortnames:[],category:"symbols"},":hourglass:":{uc_base:"231b",uc_full:"231b",shortnames:[],category:"objects"},":hourglass_flowing_sand:":{uc_base:"23f3",uc_full:"23f3",shortnames:[],category:"objects"},":ice_skate:":{uc_base:"26f8",uc_full:"26f8-fe0f",shortnames:[],category:"activity"},":infinity:":{uc_base:"267e",uc_full:"267e-fe0f",shortnames:[],category:"symbols"},":information_source:":{uc_base:"2139",uc_full:"2139-fe0f",shortnames:[],category:"symbols"},":interrobang:":{uc_base:"2049",uc_full:"2049-fe0f",shortnames:[],category:"symbols"},":keyboard:":{uc_base:"2328",uc_full:"2328-fe0f",shortnames:[],category:"objects"},":left_right_arrow:":{uc_base:"2194",uc_full:"2194-fe0f",shortnames:[],category:"symbols"},":leftwards_arrow_with_hook:":{uc_base:"21a9",uc_full:"21a9-fe0f",shortnames:[],category:"symbols"},":leo:":{uc_base:"264c",uc_full:"264c",shortnames:[],category:"symbols"},":libra:":{uc_base:"264e",uc_full:"264e",shortnames:[],category:"symbols"},":loop:":{uc_base:"27bf",uc_full:"27bf",shortnames:[],category:"symbols"},":m:":{uc_base:"24c2",uc_full:"24c2-fe0f",shortnames:[],category:"symbols"},":male_sign:":{uc_base:"2642",uc_full:"2642-fe0f",shortnames:[],category:"symbols"},":medical_symbol:":{uc_base:"2695",uc_full:"2695-fe0f",shortnames:[],category:"symbols"},":mountain:":{uc_base:"26f0",uc_full:"26f0-fe0f",shortnames:[],category:"travel"},":negative_squared_cross_mark:":{uc_base:"274e",uc_full:"274e",shortnames:[],category:"symbols"},":no_entry:":{uc_base:"26d4",uc_full:"26d4",shortnames:[],category:"symbols"},":o:":{uc_base:"2b55",uc_full:"2b55",shortnames:[],category:"symbols"},":ophiuchus:":{uc_base:"26ce",uc_full:"26ce",shortnames:[],category:"symbols"},":orthodox_cross:":{uc_base:"2626",uc_full:"2626-fe0f",shortnames:[],category:"symbols"},":part_alternation_mark:":{uc_base:"303d",uc_full:"303d-fe0f",shortnames:[],category:"symbols"},":partly_sunny:":{uc_base:"26c5",uc_full:"26c5",shortnames:[],category:"nature"},":pause_button:":{uc_base:"23f8",uc_full:"23f8-fe0f",shortnames:[":double_vertical_bar:"],category:"symbols"},":peace:":{uc_base:"262e",uc_full:"262e-fe0f",shortnames:[":peace_symbol:"],category:"symbols"},":pencil2:":{uc_base:"270f",uc_full:"270f-fe0f",shortnames:[],category:"objects"},":person_bouncing_ball:":{uc_base:"26f9",uc_full:"26f9",shortnames:[":basketball_player:",":person_with_ball:"],category:"activity"},":pick:":{uc_base:"26cf",uc_full:"26cf-fe0f",shortnames:[],category:"objects"},":pisces:":{uc_base:"2653",uc_full:"2653",shortnames:[],category:"symbols"},":play_pause:":{uc_base:"23ef",uc_full:"23ef-fe0f",shortnames:[],category:"symbols"},":point_up:":{uc_base:"261d",uc_full:"261d-fe0f",shortnames:[],category:"people"},":pound_symbol:":{uc_base:"0023",uc_full:"0023-fe0f",shortnames:[],category:"symbols"},":question:":{uc_base:"2753",uc_full:"2753",shortnames:[],category:"symbols"},":radioactive:":{uc_base:"2622",uc_full:"2622-fe0f",shortnames:[":radioactive_sign:"],category:"symbols"},":raised_hand:":{uc_base:"270b",uc_full:"270b",shortnames:[],category:"people"},":record_button:":{uc_base:"23fa",uc_full:"23fa-fe0f",shortnames:[],category:"symbols"},":recycle:":{uc_base:"267b",uc_full:"267b-fe0f",shortnames:[],category:"symbols"},":registered:":{uc_base:"00ae",uc_full:"00ae-fe0f",shortnames:[],category:"symbols"},":relaxed:":{uc_base:"263a",uc_full:"263a-fe0f",shortnames:[],category:"people"},":rewind:":{uc_base:"23ea",uc_full:"23ea",shortnames:[],category:"symbols"},":sagittarius:":{uc_base:"2650",uc_full:"2650",shortnames:[],category:"symbols"},":sailboat:":{uc_base:"26f5",uc_full:"26f5",shortnames:[],category:"travel"},":scales:":{uc_base:"2696",uc_full:"2696-fe0f",shortnames:[],category:"objects"},":scissors:":{uc_base:"2702",uc_full:"2702-fe0f",shortnames:[],category:"objects"},":scorpius:":{uc_base:"264f",uc_full:"264f",shortnames:[],category:"symbols"},":secret:":{uc_base:"3299",uc_full:"3299-fe0f",shortnames:[],category:"symbols"},":shamrock:":{uc_base:"2618",uc_full:"2618-fe0f",shortnames:[],category:"nature"},":shinto_shrine:":{uc_base:"26e9",uc_full:"26e9-fe0f",shortnames:[],category:"travel"},":skier:":{uc_base:"26f7",uc_full:"26f7-fe0f",shortnames:[],category:"activity"},":skull_crossbones:":{uc_base:"2620",uc_full:"2620-fe0f",shortnames:[":skull_and_crossbones:"],category:"people"},":snowflake:":{uc_base:"2744",uc_full:"2744-fe0f",shortnames:[],category:"nature"},":snowman2:":{uc_base:"2603",uc_full:"2603-fe0f",shortnames:[],category:"nature"},":snowman:":{uc_base:"26c4",uc_full:"26c4",shortnames:[],category:"nature"},":soccer:":{uc_base:"26bd",uc_full:"26bd",shortnames:[],category:"activity"},":spades:":{uc_base:"2660",uc_full:"2660-fe0f",shortnames:[],category:"symbols"},":sparkle:":{uc_base:"2747",uc_full:"2747-fe0f",shortnames:[],category:"symbols"},":sparkles:":{uc_base:"2728",uc_full:"2728",shortnames:[],category:"nature"},":star:":{uc_base:"2b50",uc_full:"2b50",shortnames:[],category:"nature"},":star_and_crescent:":{uc_base:"262a",uc_full:"262a-fe0f",shortnames:[],category:"symbols"},":star_of_david:":{uc_base:"2721",uc_full:"2721-fe0f",shortnames:[],category:"symbols"},":stop_button:":{uc_base:"23f9",uc_full:"23f9-fe0f",shortnames:[],category:"symbols"},":stopwatch:":{uc_base:"23f1",uc_full:"23f1-fe0f",shortnames:[],category:"objects"},":sunny:":{uc_base:"2600",uc_full:"2600-fe0f",shortnames:[],category:"nature"},":taurus:":{uc_base:"2649",uc_full:"2649",shortnames:[],category:"symbols"},":telephone:":{uc_base:"260e",uc_full:"260e-fe0f",shortnames:[],category:"objects"},":tent:":{uc_base:"26fa",uc_full:"26fa",shortnames:[],category:"travel"},":thunder_cloud_rain:":{uc_base:"26c8",uc_full:"26c8-fe0f",shortnames:[":thunder_cloud_and_rain:"],category:"nature"},":timer:":{uc_base:"23f2",uc_full:"23f2-fe0f",shortnames:[":timer_clock:"],category:"objects"},":tm:":{uc_base:"2122",uc_full:"2122-fe0f",shortnames:[],category:"symbols"},":track_next:":{uc_base:"23ed",uc_full:"23ed-fe0f",shortnames:[":next_track:"],category:"symbols"},":track_previous:":{uc_base:"23ee",uc_full:"23ee-fe0f",shortnames:[":previous_track:"],category:"symbols"},":transgender_symbol:":{uc_base:"26a7",uc_full:"26a7",shortnames:[],category:"symbols"},":umbrella2:":{uc_base:"2602",uc_full:"2602-fe0f",shortnames:[],category:"nature"},":umbrella:":{uc_base:"2614",uc_full:"2614",shortnames:[],category:"nature"},":urn:":{uc_base:"26b1",uc_full:"26b1-fe0f",shortnames:[":funeral_urn:"],category:"objects"},":v:":{uc_base:"270c",uc_full:"270c-fe0f",shortnames:[],category:"people"},":virgo:":{uc_base:"264d",uc_full:"264d",shortnames:[],category:"symbols"},":warning:":{uc_base:"26a0",uc_full:"26a0-fe0f",shortnames:[],category:"symbols"},":watch:":{uc_base:"231a",uc_full:"231a",shortnames:[],category:"objects"},":wavy_dash:":{uc_base:"3030",uc_full:"3030-fe0f",shortnames:[],category:"symbols"},":wheel_of_dharma:":{uc_base:"2638",uc_full:"2638-fe0f",shortnames:[],category:"symbols"},":wheelchair:":{uc_base:"267f",uc_full:"267f",shortnames:[],category:"symbols"},":white_check_mark:":{uc_base:"2705",uc_full:"2705",shortnames:[],category:"symbols"},":white_circle:":{uc_base:"26aa",uc_full:"26aa",shortnames:[],category:"symbols"},":white_large_square:":{uc_base:"2b1c",uc_full:"2b1c",shortnames:[],category:"symbols"},":white_medium_small_square:":{uc_base:"25fd",uc_full:"25fd",shortnames:[],category:"symbols"},":white_medium_square:":{uc_base:"25fb",uc_full:"25fb-fe0f",shortnames:[],category:"symbols"},":white_small_square:":{uc_base:"25ab",uc_full:"25ab-fe0f",shortnames:[],category:"symbols"},":writing_hand:":{uc_base:"270d",uc_full:"270d-fe0f",shortnames:[],category:"people"},":x:":{uc_base:"274c",uc_full:"274c",shortnames:[],category:"symbols"},":yin_yang:":{uc_base:"262f",uc_full:"262f-fe0f",shortnames:[],category:"symbols"},":zap:":{uc_base:"26a1",uc_full:"26a1",shortnames:[],category:"nature"}},ns.asciiList={"*\\0/*":"1f646","*\\O/*":"1f646","-___-":"1f611",":'-)":"1f602","':-)":"1f605","':-D":"1f605",">:-)":"1f606","':-(":"1f613",">:-(":"1f620",":'-(":"1f622","O:-)":"1f607","0:-3":"1f607","0:-)":"1f607","0;^)":"1f607","O;-)":"1f607","0;-)":"1f607","O:-3":"1f607","-__-":"1f611",":-\xde":"1f61b","</3":"1f494",":')":"1f602",":-D":"1f603","':)":"1f605","'=)":"1f605","':D":"1f605","'=D":"1f605",">:)":"1f606",">;)":"1f606",">=)":"1f606",";-)":"1f609","*-)":"1f609",";-]":"1f609",";^)":"1f609","':(":"1f613","'=(":"1f613",":-*":"1f618",":^*":"1f618",">:P":"1f61c","X-P":"1f61c",">:[":"1f61e",":-(":"1f61e",":-[":"1f61e",">:(":"1f620",":'(":"1f622",";-(":"1f622",">.<":"1f623","#-)":"1f635","%-)":"1f635","X-)":"1f635","\\0/":"1f646","\\O/":"1f646","0:3":"1f607","0:)":"1f607","O:)":"1f607","O=)":"1f607","O:3":"1f607","B-)":"1f60e","8-)":"1f60e","B-D":"1f60e","8-D":"1f60e","-_-":"1f611",">:\\":"1f615",">:/":"1f615",":-/":"1f615",":-.":"1f615",":-P":"1f61b",":\xde":"1f61b",":-b":"1f61b",":-O":"1f62e",O_O:"1f62e",">:O":"1f62e",":-X":"1f636",":-#":"1f636",":-)":"1f642","(y)":"1f44d","<3":"2764-fe0f","=D":"1f603",";)":"1f609","*)":"1f609",";]":"1f609",";D":"1f609",":*":"1f618","=*":"1f618",":(":"1f61e",":[":"1f61e","=(":"1f61e",":@":"1f620",";(":"1f622","D:":"1f628",":$":"1f633","=$":"1f633","#)":"1f635","%)":"1f635","X)":"1f635","B)":"1f60e","8)":"1f60e",":/":"1f615",":\\":"1f615","=/":"1f615","=\\":"1f615",":L":"1f615","=L":"1f615",":P":"1f61b","=P":"1f61b",":b":"1f61b",":O":"1f62e",":X":"1f636",":#":"1f636","=X":"1f636","=#":"1f636",":)":"1f642","=]":"1f642","=)":"1f642",":]":"1f642",":D":"1f604"},ns.asciiRegexp="(\\*\\\\0\\/\\*|\\*\\\\O\\/\\*|\\-___\\-|\\:'\\-\\)|'\\:\\-\\)|'\\:\\-D|\\>\\:\\-\\)|>\\:\\-\\)|'\\:\\-\\(|\\>\\:\\-\\(|>\\:\\-\\(|\\:'\\-\\(|O\\:\\-\\)|0\\:\\-3|0\\:\\-\\)|0;\\^\\)|O;\\-\\)|0;\\-\\)|O\\:\\-3|\\-__\\-|\\:\\-\xde|\\:\\-\xde|\\<\\/3|<\\/3|\\:'\\)|\\:\\-D|'\\:\\)|'\\=\\)|'\\:D|'\\=D|\\>\\:\\)|>\\:\\)|\\>;\\)|>;\\)|\\>\\=\\)|>\\=\\)|;\\-\\)|\\*\\-\\)|;\\-\\]|;\\^\\)|'\\:\\(|'\\=\\(|\\:\\-\\*|\\:\\^\\*|\\>\\:P|>\\:P|X\\-P|\\>\\:\\[|>\\:\\[|\\:\\-\\(|\\:\\-\\[|\\>\\:\\(|>\\:\\(|\\:'\\(|;\\-\\(|\\>\\.\\<|>\\.<|#\\-\\)|%\\-\\)|X\\-\\)|\\\\0\\/|\\\\O\\/|0\\:3|0\\:\\)|O\\:\\)|O\\=\\)|O\\:3|B\\-\\)|8\\-\\)|B\\-D|8\\-D|\\-_\\-|\\>\\:\\\\|>\\:\\\\|\\>\\:\\/|>\\:\\/|\\:\\-\\/|\\:\\-\\.|\\:\\-P|\\:\xde|\\:\xde|\\:\\-b|\\:\\-O|O_O|\\>\\:O|>\\:O|\\:\\-X|\\:\\-#|\\:\\-\\)|\\(y\\)|\\<3|<3|\\=D|;\\)|\\*\\)|;\\]|;D|\\:\\*|\\=\\*|\\:\\(|\\:\\[|\\=\\(|\\:@|;\\(|D\\:|\\:\\$|\\=\\$|#\\)|%\\)|X\\)|B\\)|8\\)|\\:\\/|\\:\\\\|\\=\\/|\\=\\\\|\\:L|\\=L|\\:P|\\=P|\\:b|\\:O|\\:X|\\:#|\\=X|\\=#|\\:\\)|\\=\\]|\\=\\)|\\:\\]|\\:D)",ns.emojiVersion="6.5",ns.emojiSize="32",ns.blacklistChars="",ns.imagePathPNG="https://cdn.jsdelivr.net/joypixels/assets/"+ns.emojiVersion+"/png/unicode/",ns.defaultPathPNG=ns.imagePathPNG,ns.fileExtension=".png",ns.imageTitleTag=!0,ns.sprites=!1,ns.unicodeAlt=!0,ns.ascii=!1,ns.riskyMatchAscii=!1,ns.regAscii=new RegExp("<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|((\\s|^)"+ns.asciiRegexp+"(?=\\s|$|[!,.?]))","gi"),ns.regAsciiRisky=new RegExp("<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|(()"+ns.asciiRegexp+"())","gi"),ns.regUnicode=new RegExp("<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|(?:[\u1f91D[\u1f3fB-\u1f3fF]\u200d\u1f9f1\u200d\u1f91D[\u1f3fB-\u1f3fF]])|(?:\ud83c\udff3)\ufe0f?\u200d?(?:\ud83c\udf08)|(?:\ud83d\udc41)\ufe0f?\u200d?(?:\ud83d\udde8)\ufe0f?|[#-9]\ufe0f?\u20e3|(?:(?:\ud83c\udff4)(?:\udb40[\udc60-\udcff]){1,6})|(?:\ud83c[\udde0-\uddff]){2}|(?:\ud83d[\udc68\udc69])\ufe0f?(?:\ud83c[\udffa-\udfff])?\u200d?(?:[\u2695\u2696\u2708]|\ud83c[\udf3e-\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92])|(?:\ud83d[\udc68\udc69]|\ud83e[\uddd0-\udddf])(?:\ud83c[\udffa-\udfff])?\u200d?[\u2640\u2642\u2695\u2696\u2708]?\ufe0f?|(?:(?:\u2764|\ud83d[\udc66-\udc69\udc8b])[\u200d\ufe0f]{0,2}){1,3}(?:\u2764|\ud83d[\udc66-\udc69\udc8b])|(?:(?:\u2764|\ud83d[\udc66-\udc69\udc8b])\ufe0f?){2,4}|(?:\ud83d[\udc68\udc69\udc6e\udc71-\udc87\udd75\ude45-\ude4e]|\ud83e[\udd26\udd37]|\ud83c[\udfc3-\udfcc]|\ud83e[\udd38-\udd3e]|\ud83d[\udea3-\udeb6]|\u26f9|\ud83d\udc6f)\ufe0f?(?:\ud83c[\udffb-\udfff])?\u200d?[\u2640\u2642]?\ufe0f?|(?:[\u261d\u26f9\u270a-\u270d]|\ud83c[\udf85-\udfcc]|\ud83d[\udc42-\udcaa\udd74-\udd96\ude45-\ude4f\udea3-\udecc]|\ud83e[\udd18-\udd3e])\ufe0f?(?:\ud83c[\udffb-\udfff])|(?:[\u2194-\u2199\u21a9-\u21aa]\ufe0f?|[#*]|[\u3030\u303d]\ufe0f?|(?:\ud83c[\udd70-\udd71]|\ud83c\udd8e|\ud83c[\udd91-\udd9a])\ufe0f?|\u24c2\ufe0f?|[\u3297\u3299]\ufe0f?|(?:\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51])\ufe0f?|[\u203c\u2049]\ufe0f?|[\u25aa-\u25ab\u25b6\u25c0\u25fb-\u25fe]\ufe0f?|[\xa9\xae]\ufe0f?|[\u2122\u2139]\ufe0f?|\ud83c\udc04\ufe0f?|[\u2b05-\u2b07\u2b1b-\u2b1c\u2b50\u2b55]\ufe0f?|[\u231a-\u231b\u2328\u23cf\u23e9-\u23f3\u23f8-\u23fa]\ufe0f?|\ud83c\udccf|[\u2934\u2935]\ufe0f?)|[\u2700-\u27bf]\ufe0f?|[\ud800-\udbff][\udc00-\udfff]\ufe0f?|[\u2600-\u26ff]\ufe0f?|[0-9]\ufe0f","g"),ns.convert=function(unicode){if(unicode.indexOf("-")>-1){for(var parts=[],s=unicode.split("-"),i=0;i<s.length;i++){var part=parseInt(s[i],16);if(part>=65536&&1114111>=part){var hi=Math.floor((part-65536)/1024)+55296,lo=(part-65536)%1024+56320;part=String.fromCharCode(hi)+String.fromCharCode(lo)}else part=String.fromCharCode(part);parts.push(part)}return parts.join("")}var s=parseInt(unicode,16);if(s>=65536&&1114111>=s){var hi=Math.floor((s-65536)/1024)+55296,lo=(s-65536)%1024+56320;return String.fromCharCode(hi)+String.fromCharCode(lo)}return String.fromCharCode(s)},ns.shortnameLookup=[],ns.altShortNames=[],ns.unicodeCharRegexCached=null;var emoji,tmpShortNames=[];for(emoji in ns.emojiList)if(ns.emojiList.hasOwnProperty(emoji)||""===emoji){tmpShortNames.push(emoji.replace(/[+]/g,"\\$&"));var cp=ns.convert(ns.emojiList[emoji].uc_full),i=0;for(ns.shortnameLookup[cp]=emoji.replace(/[+]/g,"\\$&"),i=0;i<ns.emojiList[emoji].shortnames.length;i++)tmpShortNames.push(ns.emojiList[emoji].shortnames[i].replace(/[+]/g,"\\$&")),ns.altShortNames[ns.emojiList[emoji].shortnames[i]]=emoji}ns.shortnames=tmpShortNames.join("|"),ns.regShortNames=new RegExp("<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|("+ns.shortnames+")","gi"),ns.init=function(){ns.unicodeCharRegex()},ns.toImage=function(str){return str=ns.toShort(str),str=ns.shortnameToImage(str)},ns.unicodeToImage=function(str){return str},ns.unifyUnicode=function(str){return str=ns.toShort(str),str=ns.shortnameToUnicode(str)},ns.shortnameToAscii=function(str){var unicode,unicodeToAscii=ns.objectFlip(ns.asciiList);return str=str.replace(ns.regShortNames,function(shortname){return"undefined"!=typeof shortname&&""!==shortname&&shortname in ns.emojiList?(unicode=ns.emojiList[shortname].uc_full,"undefined"!=typeof unicodeToAscii[unicode]?unicodeToAscii[unicode]:shortname):shortname})},ns.shortnameToUnicode=function(str){var unicode,fname;if(str=str.replace(ns.regShortNames,function(shortname){if("undefined"==typeof shortname||""===shortname)return shortname;if(!(shortname in ns.emojiList)){if(!(shortname in ns.altShortNames))return shortname;shortname=ns.altShortNames[shortname]}return unicode=ns.emojiList[shortname].uc_full.toUpperCase(),fname=ns.emojiList[shortname].uc_base,ns.convert(unicode)}),ns.ascii){var asciiRX=ns.riskyMatchAscii?ns.regAsciiRisky:ns.regAscii;str=str.replace(asciiRX,function(entire,m1,m2,m3){return"undefined"!=typeof m3&&""!==m3&&ns.unescapeHTML(m3)in ns.asciiList?(m3=ns.unescapeHTML(m3),unicode=ns.asciiList[m3].toUpperCase(),m2+ns.convert(unicode)):entire})}return str},ns.shortnameToImage=function(str){var replaceWith,shortname,unicode,fname,alt,category,title,size,ePath;if(str=str.replace(ns.regShortNames,function(shortname){if("undefined"==typeof shortname||""===shortname)return shortname;if(!(shortname in ns.emojiList)){if(!(shortname in ns.altShortNames))return shortname;shortname=ns.altShortNames[shortname]}return unicode=ns.emojiList[shortname].uc_full,fname=ns.emojiList[shortname].uc_base,category=fname.indexOf("-1f3f")>=0?"diversity":ns.emojiList[shortname].category,title=ns.imageTitleTag?'title="'+shortname+'"':"",size="32"==ns.spriteSize||"64"==ns.spriteSize?ns.spriteSize:"32",ePath=ns.defaultPathPNG!==ns.imagePathPNG?ns.imagePathPNG:ns.defaultPathPNG+ns.emojiSize+"/",alt=ns.unicodeAlt?ns.convert(unicode.toUpperCase()):shortname,replaceWith=ns.sprites?'<span class="joypixels joypixels-'+size+"-"+category+" _"+fname+'" '+title+">"+alt+"</span>":'<img class="joypixels" alt="'+alt+'" '+title+' src="'+ePath+fname+ns.fileExtension+'"/>'}),ns.ascii){var asciiRX=ns.riskyMatchAscii?ns.regAsciiRisky:ns.regAscii;str=str.replace(asciiRX,function(entire,m1,m2,m3){if("undefined"==typeof m3||""===m3||!(ns.unescapeHTML(m3)in ns.asciiList))return entire;m3=ns.unescapeHTML(m3),unicode=ns.asciiList[m3];var mappedUnicode=ns.mapUnicodeToShort();return shortname=mappedUnicode[unicode],category=unicode.indexOf("-1f3f")>=0?"diversity":ns.emojiList[shortname].category,title=ns.imageTitleTag?'title="'+ns.escapeHTML(m3)+'"':"",size="32"==ns.spriteSize||"64"==ns.spriteSize?ns.spriteSize:"32",ePath=ns.defaultPathPNG!==ns.imagePathPNG?ns.imagePathPNG:ns.defaultPathPNG+ns.emojiSize+"/",alt=ns.unicodeAlt?ns.convert(unicode.toUpperCase()):ns.escapeHTML(m3),unicode=unicode.replace("-fe0f",""),replaceWith=ns.sprites?m2+'<span class="joypixels joypixels-'+size+"-"+category+" _"+unicode+'" '+title+">"+alt+"</span>":m2+'<img class="joypixels" alt="'+alt+'" '+title+' src="'+ePath+unicode+ns.fileExtension+'"/>'})}return str},ns.toShort=function(str){var find=ns.unicodeCharRegex();return str=ns.replaceAll(str,find)},ns.escapeHTML=function(string){var escaped={"&":"&","<":"<",">":">",'"':""","'":"'"};return string.replace(/[&<>"']/g,function(match){return escaped[match]})},ns.unescapeHTML=function(string){var unescaped={"&":"&","&":"&","&":"&","<":"<","<":"<","<":"<",">":">",">":">",">":">",""":'"',""":'"',""":'"',"'":"'","'":"'","'":"'"};return string.replace(/&(?:amp|#38|#x26|lt|#60|#x3C|gt|#62|#x3E|apos|#39|#x27|quot|#34|#x22);/gi,function(match){return unescaped[match]})},ns.shortnameConversionMap=function(){var emoji,map=[];for(emoji in ns.emojiList)ns.emojiList.hasOwnProperty(emoji)&&""!==emoji&&(map[ns.convert(ns.emojiList[emoji].uc_full)]=emoji);return map},ns.unicodeCharRegex=function(){if(!ns.unicodeCharRegexCached){var map=[];for(emoji in ns.emojiList)ns.emojiList.hasOwnProperty(emoji)&&""!==emoji&&map.push(ns.convert(ns.emojiList[emoji].uc_full));ns.unicodeCharRegexCached=map.join("|")}return ns.unicodeCharRegexCached},ns.mapEmojiList=function(addToMapStorage){for(var shortname in ns.emojiList)if(ns.emojiList.hasOwnProperty(shortname)){var unicode=ns.emojiList[shortname].uc_full;addToMapStorage(unicode,shortname)}},ns.mapUnicodeToShort=function(){return ns.memMapShortToUnicode||(ns.memMapShortToUnicode={},ns.mapEmojiList(function(unicode,shortname){ns.memMapShortToUnicode[unicode]=shortname})),ns.memMapShortToUnicode},ns.memorizeReplacement=function(){if(!ns.unicodeReplacementRegEx||!ns.memMapShortToUnicodeCharacters){var unicodeList=[];ns.memMapShortToUnicodeCharacters={},ns.mapEmojiList(function(unicode,shortname){var emojiCharacter=ns.convert(unicode);ns.memMapShortToUnicodeCharacters[emojiCharacter]=shortname,unicodeList.push(emojiCharacter)}),ns.unicodeReplacementRegEx=unicodeList.join("|")}},ns.mapUnicodeCharactersToShort=function(){return ns.memorizeReplacement(),ns.memMapShortToUnicodeCharacters},ns.objectFlip=function(obj){var key,tmp_obj={};for(key in obj)obj.hasOwnProperty(key)&&(tmp_obj[obj[key]]=key);return tmp_obj},ns.escapeRegExp=function(string){return string.replace(/[-[\]{}()*+?.,;:&\\^$#\s]/g,"\\$&")},ns.replaceAll=function(string,find){var escapedFind=ns.escapeRegExp(find),search=new RegExp("<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|("+escapedFind+")","gi"),replace=function(entire,m1){return"undefined"==typeof m1||""===m1?entire:ns.shortnameLookup[m1]};return string.replace(search,replace)}}(this.joypixels=this.joypixels||{}),"object"==typeof module&&(module.exports=this.joypixels); \ No newline at end of file +!(function (ns) { + (ns.emojiList = { + ':england:': { + uc_base: '1f3f4-e0067-e0062-e0065-e006e-e0067-e007f', + uc_full: '1f3f4-e0067-e0062-e0065-e006e-e0067-e007f', + shortnames: [], + category: 'flags', + }, + ':scotland:': { + uc_base: '1f3f4-e0067-e0062-e0073-e0063-e0074-e007f', + uc_full: '1f3f4-e0067-e0062-e0073-e0063-e0074-e007f', + shortnames: [], + category: 'flags', + }, + ':wales:': { + uc_base: '1f3f4-e0067-e0062-e0077-e006c-e0073-e007f', + uc_full: '1f3f4-e0067-e0062-e0077-e006c-e0073-e007f', + shortnames: [], + category: 'flags', + }, + ':kiss_man_man_tone1:': { + uc_base: '1f468-1f3fb-2764-1f48b-1f468-1f3fb', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_man_man_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone1_tone2:': { + uc_base: '1f468-1f3fb-2764-1f48b-1f468-1f3fc', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_man_man_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone1_tone3:': { + uc_base: '1f468-1f3fb-2764-1f48b-1f468-1f3fd', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_man_man_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone1_tone4:': { + uc_base: '1f468-1f3fb-2764-1f48b-1f468-1f3fe', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_man_man_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone1_tone5:': { + uc_base: '1f468-1f3fb-2764-1f48b-1f468-1f3ff', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_man_man_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone2:': { + uc_base: '1f468-1f3fc-2764-1f48b-1f468-1f3fc', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_man_man_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone2_tone1:': { + uc_base: '1f468-1f3fc-2764-1f48b-1f468-1f3fb', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_man_man_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone2_tone3:': { + uc_base: '1f468-1f3fc-2764-1f48b-1f468-1f3fd', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_man_man_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone2_tone4:': { + uc_base: '1f468-1f3fc-2764-1f48b-1f468-1f3fe', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_man_man_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone2_tone5:': { + uc_base: '1f468-1f3fc-2764-1f48b-1f468-1f3ff', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_man_man_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone3:': { + uc_base: '1f468-1f3fd-2764-1f48b-1f468-1f3fd', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_man_man_medium_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone3_tone1:': { + uc_base: '1f468-1f3fd-2764-1f48b-1f468-1f3fb', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_man_man_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone3_tone2:': { + uc_base: '1f468-1f3fd-2764-1f48b-1f468-1f3fc', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_man_man_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone3_tone4:': { + uc_base: '1f468-1f3fd-2764-1f48b-1f468-1f3fe', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_man_man_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone3_tone5:': { + uc_base: '1f468-1f3fd-2764-1f48b-1f468-1f3ff', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_man_man_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone4:': { + uc_base: '1f468-1f3fe-2764-1f48b-1f468-1f3fe', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_man_man_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone4_tone1:': { + uc_base: '1f468-1f3fe-2764-1f48b-1f468-1f3fb', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_man_man_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone4_tone2:': { + uc_base: '1f468-1f3fe-2764-1f48b-1f468-1f3fc', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_man_man_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone4_tone3:': { + uc_base: '1f468-1f3fe-2764-1f48b-1f468-1f3fd', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_man_man_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone4_tone5:': { + uc_base: '1f468-1f3fe-2764-1f48b-1f468-1f3ff', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_man_man_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone5:': { + uc_base: '1f468-1f3ff-2764-1f48b-1f468-1f3ff', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_man_man_dark_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone5_tone1:': { + uc_base: '1f468-1f3ff-2764-1f48b-1f468-1f3fb', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_man_man_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone5_tone2:': { + uc_base: '1f468-1f3ff-2764-1f48b-1f468-1f3fc', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_man_man_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone5_tone3:': { + uc_base: '1f468-1f3ff-2764-1f48b-1f468-1f3fd', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_man_man_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_man_man_tone5_tone4:': { + uc_base: '1f468-1f3ff-2764-1f48b-1f468-1f3fe', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_man_man_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone1_tone2:': { + uc_base: '1f9d1-1f3fb-2764-1f48b-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc', + shortnames: [':kiss_person_person_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone1_tone3:': { + uc_base: '1f9d1-1f3fb-2764-1f48b-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd', + shortnames: [':kiss_person_person_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone1_tone4:': { + uc_base: '1f9d1-1f3fb-2764-1f48b-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe', + shortnames: [':kiss_person_person_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone1_tone5:': { + uc_base: '1f9d1-1f3fb-2764-1f48b-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff', + shortnames: [':kiss_person_person_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone2_tone1:': { + uc_base: '1f9d1-1f3fc-2764-1f48b-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb', + shortnames: [':kiss_person_person_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone2_tone3:': { + uc_base: '1f9d1-1f3fc-2764-1f48b-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd', + shortnames: [':kiss_person_person_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone2_tone4:': { + uc_base: '1f9d1-1f3fc-2764-1f48b-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe', + shortnames: [':kiss_person_person_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone2_tone5:': { + uc_base: '1f9d1-1f3fc-2764-1f48b-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff', + shortnames: [':kiss_person_person_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone3_tone1:': { + uc_base: '1f9d1-1f3fd-2764-1f48b-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb', + shortnames: [':kiss_person_person_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone3_tone2:': { + uc_base: '1f9d1-1f3fd-2764-1f48b-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc', + shortnames: [':kiss_person_person_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone3_tone4:': { + uc_base: '1f9d1-1f3fd-2764-1f48b-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe', + shortnames: [':kiss_person_person_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone3_tone5:': { + uc_base: '1f9d1-1f3fd-2764-1f48b-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff', + shortnames: [':kiss_person_person_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone4_tone1:': { + uc_base: '1f9d1-1f3fe-2764-1f48b-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb', + shortnames: [':kiss_person_person_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone4_tone2:': { + uc_base: '1f9d1-1f3fe-2764-1f48b-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc', + shortnames: [':kiss_person_person_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone4_tone3:': { + uc_base: '1f9d1-1f3fe-2764-1f48b-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd', + shortnames: [':kiss_person_person_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone4_tone5:': { + uc_base: '1f9d1-1f3fe-2764-1f48b-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3ff', + shortnames: [':kiss_person_person_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone5_tone1:': { + uc_base: '1f9d1-1f3ff-2764-1f48b-1f9d1-1f3fb', + uc_full: '1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fb', + shortnames: [':kiss_person_person_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone5_tone2:': { + uc_base: '1f9d1-1f3ff-2764-1f48b-1f9d1-1f3fc', + uc_full: '1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fc', + shortnames: [':kiss_person_person_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone5_tone3:': { + uc_base: '1f9d1-1f3ff-2764-1f48b-1f9d1-1f3fd', + uc_full: '1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fd', + shortnames: [':kiss_person_person_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_person_person_tone5_tone4:': { + uc_base: '1f9d1-1f3ff-2764-1f48b-1f9d1-1f3fe', + uc_full: '1f9d1-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f9d1-1f3fe', + shortnames: [':kiss_person_person_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone1:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f468-1f3fb', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_woman_man_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone1_tone2:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f468-1f3fc', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_woman_man_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone1_tone3:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f468-1f3fd', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_woman_man_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone1_tone4:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f468-1f3fe', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_woman_man_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone1_tone5:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f468-1f3ff', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_woman_man_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone2:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f468-1f3fc', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_woman_man_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone2_tone1:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f468-1f3fb', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_woman_man_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone2_tone3:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f468-1f3fd', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_woman_man_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone2_tone4:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f468-1f3fe', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_woman_man_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone2_tone5:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f468-1f3ff', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_woman_man_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone3:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f468-1f3fd', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_woman_man_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone3_tone1:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f468-1f3fb', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_woman_man_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone3_tone2:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f468-1f3fc', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_woman_man_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone3_tone4:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f468-1f3fe', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_woman_man_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone3_tone5:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f468-1f3ff', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_woman_man_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone4:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f468-1f3fe', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_woman_man_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone4_tone1:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f468-1f3fb', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_woman_man_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone4_tone2:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f468-1f3fc', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_woman_man_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone4_tone3:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f468-1f3fd', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_woman_man_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone4_tone5:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f468-1f3ff', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_woman_man_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone5:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f468-1f3ff', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3ff', + shortnames: [':kiss_woman_man_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone5_tone1:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f468-1f3fb', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fb', + shortnames: [':kiss_woman_man_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone5_tone2:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f468-1f3fc', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fc', + shortnames: [':kiss_woman_man_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone5_tone3:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f468-1f3fd', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fd', + shortnames: [':kiss_woman_man_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_man_tone5_tone4:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f468-1f3fe', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f468-1f3fe', + shortnames: [':kiss_woman_man_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone1:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f469-1f3fb', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb', + shortnames: [':kiss_woman_woman_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone1_tone2:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f469-1f3fc', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc', + shortnames: [':kiss_woman_woman_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone1_tone3:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f469-1f3fd', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd', + shortnames: [':kiss_woman_woman_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone1_tone4:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f469-1f3fe', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe', + shortnames: [':kiss_woman_woman_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone1_tone5:': { + uc_base: '1f469-1f3fb-2764-1f48b-1f469-1f3ff', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff', + shortnames: [':kiss_woman_woman_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone2:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f469-1f3fc', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc', + shortnames: [':kiss_woman_woman_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone2_tone1:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f469-1f3fb', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb', + shortnames: [':kiss_woman_woman_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone2_tone3:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f469-1f3fd', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd', + shortnames: [':kiss_woman_woman_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone2_tone4:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f469-1f3fe', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe', + shortnames: [':kiss_woman_woman_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone2_tone5:': { + uc_base: '1f469-1f3fc-2764-1f48b-1f469-1f3ff', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff', + shortnames: [':kiss_woman_woman_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone3:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f469-1f3fd', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd', + shortnames: [':kiss_woman_woman_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone3_tone1:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f469-1f3fb', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb', + shortnames: [':kiss_woman_woman_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone3_tone2:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f469-1f3fc', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc', + shortnames: [':kiss_woman_woman_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone3_tone4:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f469-1f3fe', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe', + shortnames: [':kiss_woman_woman_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone3_tone5:': { + uc_base: '1f469-1f3fd-2764-1f48b-1f469-1f3ff', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff', + shortnames: [':kiss_woman_woman_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone4:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f469-1f3fe', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe', + shortnames: [':kiss_woman_woman_medium_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone4_tone1:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f469-1f3fb', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb', + shortnames: [':kiss_woman_woman_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone4_tone2:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f469-1f3fc', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc', + shortnames: [':kiss_woman_woman_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone4_tone3:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f469-1f3fd', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd', + shortnames: [':kiss_woman_woman_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone4_tone5:': { + uc_base: '1f469-1f3fe-2764-1f48b-1f469-1f3ff', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff', + shortnames: [':kiss_woman_woman_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone5:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f469-1f3ff', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3ff', + shortnames: [':kiss_woman_woman_dark_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone5_tone1:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f469-1f3fb', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fb', + shortnames: [':kiss_woman_woman_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone5_tone2:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f469-1f3fc', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fc', + shortnames: [':kiss_woman_woman_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone5_tone3:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f469-1f3fd', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fd', + shortnames: [':kiss_woman_woman_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':kiss_woman_woman_tone5_tone4:': { + uc_base: '1f469-1f3ff-2764-1f48b-1f469-1f3fe', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f48b-200d-1f469-1f3fe', + shortnames: [':kiss_woman_woman_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone1_tone2:': { + uc_base: '1f468-1f3fb-1f91d-1f468-1f3fc', + uc_full: '1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc', + shortnames: [':men_holding_hands_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone1_tone3:': { + uc_base: '1f468-1f3fb-1f91d-1f468-1f3fd', + uc_full: '1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd', + shortnames: [':men_holding_hands_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone1_tone4:': { + uc_base: '1f468-1f3fb-1f91d-1f468-1f3fe', + uc_full: '1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe', + shortnames: [':men_holding_hands_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone1_tone5:': { + uc_base: '1f468-1f3fb-1f91d-1f468-1f3ff', + uc_full: '1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff', + shortnames: [':men_holding_hands_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone2_tone1:': { + uc_base: '1f468-1f3fc-1f91d-1f468-1f3fb', + uc_full: '1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb', + shortnames: [':men_holding_hands_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone2_tone3:': { + uc_base: '1f468-1f3fc-1f91d-1f468-1f3fd', + uc_full: '1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd', + shortnames: [':men_holding_hands_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone2_tone4:': { + uc_base: '1f468-1f3fc-1f91d-1f468-1f3fe', + uc_full: '1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe', + shortnames: [':men_holding_hands_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone2_tone5:': { + uc_base: '1f468-1f3fc-1f91d-1f468-1f3ff', + uc_full: '1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff', + shortnames: [':men_holding_hands_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone3_tone1:': { + uc_base: '1f468-1f3fd-1f91d-1f468-1f3fb', + uc_full: '1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb', + shortnames: [':men_holding_hands_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone3_tone2:': { + uc_base: '1f468-1f3fd-1f91d-1f468-1f3fc', + uc_full: '1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc', + shortnames: [':men_holding_hands_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone3_tone4:': { + uc_base: '1f468-1f3fd-1f91d-1f468-1f3fe', + uc_full: '1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe', + shortnames: [':men_holding_hands_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone3_tone5:': { + uc_base: '1f468-1f3fd-1f91d-1f468-1f3ff', + uc_full: '1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff', + shortnames: [':men_holding_hands_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone4_tone1:': { + uc_base: '1f468-1f3fe-1f91d-1f468-1f3fb', + uc_full: '1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb', + shortnames: [':men_holding_hands_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone4_tone2:': { + uc_base: '1f468-1f3fe-1f91d-1f468-1f3fc', + uc_full: '1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc', + shortnames: [':men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone4_tone3:': { + uc_base: '1f468-1f3fe-1f91d-1f468-1f3fd', + uc_full: '1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd', + shortnames: [':men_holding_hands_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone4_tone5:': { + uc_base: '1f468-1f3fe-1f91d-1f468-1f3ff', + uc_full: '1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff', + shortnames: [':men_holding_hands_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone5_tone1:': { + uc_base: '1f468-1f3ff-1f91d-1f468-1f3fb', + uc_full: '1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb', + shortnames: [':men_holding_hands_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone5_tone2:': { + uc_base: '1f468-1f3ff-1f91d-1f468-1f3fc', + uc_full: '1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc', + shortnames: [':men_holding_hands_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone5_tone3:': { + uc_base: '1f468-1f3ff-1f91d-1f468-1f3fd', + uc_full: '1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd', + shortnames: [':men_holding_hands_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone5_tone4:': { + uc_base: '1f468-1f3ff-1f91d-1f468-1f3fe', + uc_full: '1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe', + shortnames: [':men_holding_hands_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone1:': { + uc_base: '1f9d1-1f3fb-1f91d-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb', + shortnames: [':people_holding_hands_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone1_tone2:': { + uc_base: '1f9d1-1f3fb-1f91d-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc', + shortnames: [':people_holding_hands_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone1_tone3:': { + uc_base: '1f9d1-1f3fb-1f91d-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd', + shortnames: [':people_holding_hands_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone1_tone4:': { + uc_base: '1f9d1-1f3fb-1f91d-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe', + shortnames: [':people_holding_hands_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone1_tone5:': { + uc_base: '1f9d1-1f3fb-1f91d-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff', + shortnames: [':people_holding_hands_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone2:': { + uc_base: '1f9d1-1f3fc-1f91d-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc', + shortnames: [':people_holding_hands_medium_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone2_tone1:': { + uc_base: '1f9d1-1f3fc-1f91d-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb', + shortnames: [':people_holding_hands_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone2_tone3:': { + uc_base: '1f9d1-1f3fc-1f91d-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd', + shortnames: [':people_holding_hands_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone2_tone4:': { + uc_base: '1f9d1-1f3fc-1f91d-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe', + shortnames: [':people_holding_hands_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone2_tone5:': { + uc_base: '1f9d1-1f3fc-1f91d-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff', + shortnames: [':people_holding_hands_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone3:': { + uc_base: '1f9d1-1f3fd-1f91d-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd', + shortnames: [':people_holding_hands_medium_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone3_tone1:': { + uc_base: '1f9d1-1f3fd-1f91d-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb', + shortnames: [':people_holding_hands_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone3_tone2:': { + uc_base: '1f9d1-1f3fd-1f91d-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc', + shortnames: [':people_holding_hands_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone3_tone4:': { + uc_base: '1f9d1-1f3fd-1f91d-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe', + shortnames: [':people_holding_hands_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone3_tone5:': { + uc_base: '1f9d1-1f3fd-1f91d-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff', + shortnames: [':people_holding_hands_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone4:': { + uc_base: '1f9d1-1f3fe-1f91d-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe', + shortnames: [':people_holding_hands_medium_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone4_tone1:': { + uc_base: '1f9d1-1f3fe-1f91d-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb', + shortnames: [':people_holding_hands_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone4_tone2:': { + uc_base: '1f9d1-1f3fe-1f91d-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc', + shortnames: [':people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone4_tone3:': { + uc_base: '1f9d1-1f3fe-1f91d-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd', + shortnames: [':people_holding_hands_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone4_tone5:': { + uc_base: '1f9d1-1f3fe-1f91d-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff', + shortnames: [':people_holding_hands_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone5:': { + uc_base: '1f9d1-1f3ff-1f91d-1f9d1-1f3ff', + uc_full: '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff', + shortnames: [':people_holding_hands_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone5_tone1:': { + uc_base: '1f9d1-1f3ff-1f91d-1f9d1-1f3fb', + uc_full: '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb', + shortnames: [':people_holding_hands_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone5_tone2:': { + uc_base: '1f9d1-1f3ff-1f91d-1f9d1-1f3fc', + uc_full: '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc', + shortnames: [':people_holding_hands_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone5_tone3:': { + uc_base: '1f9d1-1f3ff-1f91d-1f9d1-1f3fd', + uc_full: '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd', + shortnames: [':people_holding_hands_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':people_holding_hands_tone5_tone4:': { + uc_base: '1f9d1-1f3ff-1f91d-1f9d1-1f3fe', + uc_full: '1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe', + shortnames: [':people_holding_hands_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone1_tone2:': { + uc_base: '1f469-1f3fb-1f91d-1f468-1f3fc', + uc_full: '1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc', + shortnames: [':woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone1_tone3:': { + uc_base: '1f469-1f3fb-1f91d-1f468-1f3fd', + uc_full: '1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd', + shortnames: [':woman_and_man_holding_hands_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone1_tone4:': { + uc_base: '1f469-1f3fb-1f91d-1f468-1f3fe', + uc_full: '1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe', + shortnames: [':woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone1_tone5:': { + uc_base: '1f469-1f3fb-1f91d-1f468-1f3ff', + uc_full: '1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff', + shortnames: [':woman_and_man_holding_hands_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone2_tone1:': { + uc_base: '1f469-1f3fc-1f91d-1f468-1f3fb', + uc_full: '1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb', + shortnames: [':woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone2_tone3:': { + uc_base: '1f469-1f3fc-1f91d-1f468-1f3fd', + uc_full: '1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd', + shortnames: [':woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone2_tone4:': { + uc_base: '1f469-1f3fc-1f91d-1f468-1f3fe', + uc_full: '1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe', + shortnames: [':woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone2_tone5:': { + uc_base: '1f469-1f3fc-1f91d-1f468-1f3ff', + uc_full: '1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff', + shortnames: [':woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone3_tone1:': { + uc_base: '1f469-1f3fd-1f91d-1f468-1f3fb', + uc_full: '1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb', + shortnames: [':woman_and_man_holding_hands_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone3_tone2:': { + uc_base: '1f469-1f3fd-1f91d-1f468-1f3fc', + uc_full: '1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc', + shortnames: [':woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone3_tone4:': { + uc_base: '1f469-1f3fd-1f91d-1f468-1f3fe', + uc_full: '1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe', + shortnames: [':woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone3_tone5:': { + uc_base: '1f469-1f3fd-1f91d-1f468-1f3ff', + uc_full: '1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff', + shortnames: [':woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone4_tone1:': { + uc_base: '1f469-1f3fe-1f91d-1f468-1f3fb', + uc_full: '1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb', + shortnames: [':woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone4_tone2:': { + uc_base: '1f469-1f3fe-1f91d-1f468-1f3fc', + uc_full: '1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc', + shortnames: [':woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone4_tone3:': { + uc_base: '1f469-1f3fe-1f91d-1f468-1f3fd', + uc_full: '1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd', + shortnames: [':woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone4_tone5:': { + uc_base: '1f469-1f3fe-1f91d-1f468-1f3ff', + uc_full: '1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff', + shortnames: [':woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone5_tone1:': { + uc_base: '1f469-1f3ff-1f91d-1f468-1f3fb', + uc_full: '1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb', + shortnames: [':woman_and_man_holding_hands_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone5_tone2:': { + uc_base: '1f469-1f3ff-1f91d-1f468-1f3fc', + uc_full: '1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc', + shortnames: [':woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone5_tone3:': { + uc_base: '1f469-1f3ff-1f91d-1f468-1f3fd', + uc_full: '1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd', + shortnames: [':woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone5_tone4:': { + uc_base: '1f469-1f3ff-1f91d-1f468-1f3fe', + uc_full: '1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe', + shortnames: [':woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone1_tone2:': { + uc_base: '1f469-1f3fb-1f91d-1f469-1f3fc', + uc_full: '1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc', + shortnames: [':women_holding_hands_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone1_tone3:': { + uc_base: '1f469-1f3fb-1f91d-1f469-1f3fd', + uc_full: '1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd', + shortnames: [':women_holding_hands_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone1_tone4:': { + uc_base: '1f469-1f3fb-1f91d-1f469-1f3fe', + uc_full: '1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe', + shortnames: [':women_holding_hands_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone1_tone5:': { + uc_base: '1f469-1f3fb-1f91d-1f469-1f3ff', + uc_full: '1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff', + shortnames: [':women_holding_hands_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone2_tone1:': { + uc_base: '1f469-1f3fc-1f91d-1f469-1f3fb', + uc_full: '1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb', + shortnames: [':women_holding_hands_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone2_tone3:': { + uc_base: '1f469-1f3fc-1f91d-1f469-1f3fd', + uc_full: '1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd', + shortnames: [':women_holding_hands_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone2_tone4:': { + uc_base: '1f469-1f3fc-1f91d-1f469-1f3fe', + uc_full: '1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe', + shortnames: [':women_holding_hands_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone2_tone5:': { + uc_base: '1f469-1f3fc-1f91d-1f469-1f3ff', + uc_full: '1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff', + shortnames: [':women_holding_hands_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone3_tone1:': { + uc_base: '1f469-1f3fd-1f91d-1f469-1f3fb', + uc_full: '1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb', + shortnames: [':women_holding_hands_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone3_tone2:': { + uc_base: '1f469-1f3fd-1f91d-1f469-1f3fc', + uc_full: '1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc', + shortnames: [':women_holding_hands_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone3_tone4:': { + uc_base: '1f469-1f3fd-1f91d-1f469-1f3fe', + uc_full: '1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe', + shortnames: [':women_holding_hands_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone3_tone5:': { + uc_base: '1f469-1f3fd-1f91d-1f469-1f3ff', + uc_full: '1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff', + shortnames: [':women_holding_hands_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone4_tone1:': { + uc_base: '1f469-1f3fe-1f91d-1f469-1f3fb', + uc_full: '1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb', + shortnames: [':women_holding_hands_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone4_tone2:': { + uc_base: '1f469-1f3fe-1f91d-1f469-1f3fc', + uc_full: '1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc', + shortnames: [':women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone4_tone3:': { + uc_base: '1f469-1f3fe-1f91d-1f469-1f3fd', + uc_full: '1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd', + shortnames: [':women_holding_hands_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone4_tone5:': { + uc_base: '1f469-1f3fe-1f91d-1f469-1f3ff', + uc_full: '1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff', + shortnames: [':women_holding_hands_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone5_tone1:': { + uc_base: '1f469-1f3ff-1f91d-1f469-1f3fb', + uc_full: '1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb', + shortnames: [':women_holding_hands_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone5_tone2:': { + uc_base: '1f469-1f3ff-1f91d-1f469-1f3fc', + uc_full: '1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc', + shortnames: [':women_holding_hands_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone5_tone3:': { + uc_base: '1f469-1f3ff-1f91d-1f469-1f3fd', + uc_full: '1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd', + shortnames: [':women_holding_hands_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone5_tone4:': { + uc_base: '1f469-1f3ff-1f91d-1f469-1f3fe', + uc_full: '1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe', + shortnames: [':women_holding_hands_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone1:': { + uc_base: '1f468-1f3fb-2764-1f468-1f3fb', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_man_man_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone1_tone2:': { + uc_base: '1f468-1f3fb-2764-1f468-1f3fc', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_man_man_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone1_tone3:': { + uc_base: '1f468-1f3fb-2764-1f468-1f3fd', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_man_man_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone1_tone4:': { + uc_base: '1f468-1f3fb-2764-1f468-1f3fe', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_man_man_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone1_tone5:': { + uc_base: '1f468-1f3fb-2764-1f468-1f3ff', + uc_full: '1f468-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_man_man_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone2:': { + uc_base: '1f468-1f3fc-2764-1f468-1f3fc', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_man_man_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone2_tone1:': { + uc_base: '1f468-1f3fc-2764-1f468-1f3fb', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_man_man_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone2_tone3:': { + uc_base: '1f468-1f3fc-2764-1f468-1f3fd', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_man_man_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone2_tone4:': { + uc_base: '1f468-1f3fc-2764-1f468-1f3fe', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_man_man_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone2_tone5:': { + uc_base: '1f468-1f3fc-2764-1f468-1f3ff', + uc_full: '1f468-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_man_man_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone3:': { + uc_base: '1f468-1f3fd-2764-1f468-1f3fd', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_man_man_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone3_tone1:': { + uc_base: '1f468-1f3fd-2764-1f468-1f3fb', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_man_man_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone3_tone2:': { + uc_base: '1f468-1f3fd-2764-1f468-1f3fc', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_man_man_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone3_tone4:': { + uc_base: '1f468-1f3fd-2764-1f468-1f3fe', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_man_man_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone3_tone5:': { + uc_base: '1f468-1f3fd-2764-1f468-1f3ff', + uc_full: '1f468-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_man_man_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone4:': { + uc_base: '1f468-1f3fe-2764-1f468-1f3fe', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_man_man_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone4_tone1:': { + uc_base: '1f468-1f3fe-2764-1f468-1f3fb', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_man_man_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone4_tone2:': { + uc_base: '1f468-1f3fe-2764-1f468-1f3fc', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_man_man_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone4_tone3:': { + uc_base: '1f468-1f3fe-2764-1f468-1f3fd', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_man_man_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone4_tone5:': { + uc_base: '1f468-1f3fe-2764-1f468-1f3ff', + uc_full: '1f468-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_man_man_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone5:': { + uc_base: '1f468-1f3ff-2764-1f468-1f3ff', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_man_man_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone5_tone1:': { + uc_base: '1f468-1f3ff-2764-1f468-1f3fb', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_man_man_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone5_tone2:': { + uc_base: '1f468-1f3ff-2764-1f468-1f3fc', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_man_man_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone5_tone3:': { + uc_base: '1f468-1f3ff-2764-1f468-1f3fd', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_man_man_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_man_man_tone5_tone4:': { + uc_base: '1f468-1f3ff-2764-1f468-1f3fe', + uc_full: '1f468-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_man_man_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone1_tone2:': { + uc_base: '1f9d1-1f3fb-2764-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fc', + shortnames: [':couple_with_heart_person_person_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone1_tone3:': { + uc_base: '1f9d1-1f3fb-2764-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fd', + shortnames: [':couple_with_heart_person_person_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone1_tone4:': { + uc_base: '1f9d1-1f3fb-2764-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3fe', + shortnames: [':couple_with_heart_person_person_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone1_tone5:': { + uc_base: '1f9d1-1f3fb-2764-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fb-200d-2764-fe0f-200d-1f9d1-1f3ff', + shortnames: [':couple_with_heart_person_person_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone2_tone1:': { + uc_base: '1f9d1-1f3fc-2764-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fb', + shortnames: [':couple_with_heart_person_person_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone2_tone3:': { + uc_base: '1f9d1-1f3fc-2764-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fd', + shortnames: [':couple_with_heart_person_person_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone2_tone4:': { + uc_base: '1f9d1-1f3fc-2764-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3fe', + shortnames: [':couple_with_heart_person_person_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone2_tone5:': { + uc_base: '1f9d1-1f3fc-2764-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fc-200d-2764-fe0f-200d-1f9d1-1f3ff', + shortnames: [':couple_with_heart_person_person_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone3_tone1:': { + uc_base: '1f9d1-1f3fd-2764-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fb', + shortnames: [':couple_with_heart_person_person_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone3_tone2:': { + uc_base: '1f9d1-1f3fd-2764-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fc', + shortnames: [':couple_with_heart_person_person_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone3_tone4:': { + uc_base: '1f9d1-1f3fd-2764-1f9d1-1f3fe', + uc_full: '1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3fe', + shortnames: [':couple_with_heart_person_person_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone3_tone5:': { + uc_base: '1f9d1-1f3fd-2764-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fd-200d-2764-fe0f-200d-1f9d1-1f3ff', + shortnames: [':couple_with_heart_person_person_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone4_tone1:': { + uc_base: '1f9d1-1f3fe-2764-1f9d1-1f3fb', + uc_full: '1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fb', + shortnames: [':couple_with_heart_person_person_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone4_tone2:': { + uc_base: '1f9d1-1f3fe-2764-1f9d1-1f3fc', + uc_full: '1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fc', + shortnames: [':couple_with_heart_person_person_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone4_tone3:': { + uc_base: '1f9d1-1f3fe-2764-1f9d1-1f3fd', + uc_full: '1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3fd', + shortnames: [':couple_with_heart_person_person_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone4_tone5:': { + uc_base: '1f9d1-1f3fe-2764-1f9d1-1f3ff', + uc_full: '1f9d1-1f3fe-200d-2764-fe0f-200d-1f9d1-1f3ff', + shortnames: [':couple_with_heart_person_person_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone5_tone1:': { + uc_base: '1f9d1-1f3ff-2764-1f9d1-1f3fb', + uc_full: '1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fb', + shortnames: [':couple_with_heart_person_person_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone5_tone2:': { + uc_base: '1f9d1-1f3ff-2764-1f9d1-1f3fc', + uc_full: '1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fc', + shortnames: [':couple_with_heart_person_person_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone5_tone3:': { + uc_base: '1f9d1-1f3ff-2764-1f9d1-1f3fd', + uc_full: '1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fd', + shortnames: [':couple_with_heart_person_person_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_person_person_tone5_tone4:': { + uc_base: '1f9d1-1f3ff-2764-1f9d1-1f3fe', + uc_full: '1f9d1-1f3ff-200d-2764-fe0f-200d-1f9d1-1f3fe', + shortnames: [':couple_with_heart_person_person_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone1:': { + uc_base: '1f469-1f3fb-2764-1f468-1f3fb', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_woman_man_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone1_tone2:': { + uc_base: '1f469-1f3fb-2764-1f468-1f3fc', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_woman_man_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone1_tone3:': { + uc_base: '1f469-1f3fb-2764-1f468-1f3fd', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_woman_man_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone1_tone4:': { + uc_base: '1f469-1f3fb-2764-1f468-1f3fe', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_woman_man_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone1_tone5:': { + uc_base: '1f469-1f3fb-2764-1f468-1f3ff', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_woman_man_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone2:': { + uc_base: '1f469-1f3fc-2764-1f468-1f3fc', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_woman_man_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone2_tone1:': { + uc_base: '1f469-1f3fc-2764-1f468-1f3fb', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_woman_man_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone2_tone3:': { + uc_base: '1f469-1f3fc-2764-1f468-1f3fd', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_woman_man_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone2_tone4:': { + uc_base: '1f469-1f3fc-2764-1f468-1f3fe', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_woman_man_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone2_tone5:': { + uc_base: '1f469-1f3fc-2764-1f468-1f3ff', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_woman_man_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone3:': { + uc_base: '1f469-1f3fd-2764-1f468-1f3fd', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_woman_man_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone3_tone1:': { + uc_base: '1f469-1f3fd-2764-1f468-1f3fb', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_woman_man_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone3_tone2:': { + uc_base: '1f469-1f3fd-2764-1f468-1f3fc', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_woman_man_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone3_tone4:': { + uc_base: '1f469-1f3fd-2764-1f468-1f3fe', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_woman_man_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone3_tone5:': { + uc_base: '1f469-1f3fd-2764-1f468-1f3ff', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_woman_man_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone4:': { + uc_base: '1f469-1f3fe-2764-1f468-1f3fe', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_woman_man_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone4_tone1:': { + uc_base: '1f469-1f3fe-2764-1f468-1f3fb', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_woman_man_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone4_tone2:': { + uc_base: '1f469-1f3fe-2764-1f468-1f3fc', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_woman_man_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone4_tone3:': { + uc_base: '1f469-1f3fe-2764-1f468-1f3fd', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_woman_man_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone4_tone5:': { + uc_base: '1f469-1f3fe-2764-1f468-1f3ff', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_woman_man_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone5:': { + uc_base: '1f469-1f3ff-2764-1f468-1f3ff', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3ff', + shortnames: [':couple_with_heart_woman_man_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone5_tone1:': { + uc_base: '1f469-1f3ff-2764-1f468-1f3fb', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fb', + shortnames: [':couple_with_heart_woman_man_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone5_tone2:': { + uc_base: '1f469-1f3ff-2764-1f468-1f3fc', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fc', + shortnames: [':couple_with_heart_woman_man_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone5_tone3:': { + uc_base: '1f469-1f3ff-2764-1f468-1f3fd', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fd', + shortnames: [':couple_with_heart_woman_man_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_man_tone5_tone4:': { + uc_base: '1f469-1f3ff-2764-1f468-1f3fe', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f468-1f3fe', + shortnames: [':couple_with_heart_woman_man_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone1:': { + uc_base: '1f469-1f3fb-2764-1f469-1f3fb', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fb', + shortnames: [':couple_with_heart_woman_woman_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone1_tone2:': { + uc_base: '1f469-1f3fb-2764-1f469-1f3fc', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fc', + shortnames: [':couple_with_heart_woman_woman_light_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone1_tone3:': { + uc_base: '1f469-1f3fb-2764-1f469-1f3fd', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fd', + shortnames: [':couple_with_heart_woman_woman_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone1_tone4:': { + uc_base: '1f469-1f3fb-2764-1f469-1f3fe', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3fe', + shortnames: [':couple_with_heart_woman_woman_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone1_tone5:': { + uc_base: '1f469-1f3fb-2764-1f469-1f3ff', + uc_full: '1f469-1f3fb-200d-2764-fe0f-200d-1f469-1f3ff', + shortnames: [':couple_with_heart_woman_woman_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone2:': { + uc_base: '1f469-1f3fc-2764-1f469-1f3fc', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fc', + shortnames: [':couple_with_heart_woman_woman_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone2_tone1:': { + uc_base: '1f469-1f3fc-2764-1f469-1f3fb', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fb', + shortnames: [':couple_with_heart_woman_woman_medium_light_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone2_tone3:': { + uc_base: '1f469-1f3fc-2764-1f469-1f3fd', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fd', + shortnames: [':couple_with_heart_woman_woman_medium_light_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone2_tone4:': { + uc_base: '1f469-1f3fc-2764-1f469-1f3fe', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3fe', + shortnames: [':couple_with_heart_woman_woman_medium_light_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone2_tone5:': { + uc_base: '1f469-1f3fc-2764-1f469-1f3ff', + uc_full: '1f469-1f3fc-200d-2764-fe0f-200d-1f469-1f3ff', + shortnames: [':couple_with_heart_woman_woman_medium_light_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone3:': { + uc_base: '1f469-1f3fd-2764-1f469-1f3fd', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fd', + shortnames: [':couple_with_heart_woman_woman_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone3_tone1:': { + uc_base: '1f469-1f3fd-2764-1f469-1f3fb', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fb', + shortnames: [':couple_with_heart_woman_woman_medium_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone3_tone2:': { + uc_base: '1f469-1f3fd-2764-1f469-1f3fc', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fc', + shortnames: [':couple_with_heart_woman_woman_medium_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone3_tone4:': { + uc_base: '1f469-1f3fd-2764-1f469-1f3fe', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3fe', + shortnames: [':couple_with_heart_woman_woman_medium_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone3_tone5:': { + uc_base: '1f469-1f3fd-2764-1f469-1f3ff', + uc_full: '1f469-1f3fd-200d-2764-fe0f-200d-1f469-1f3ff', + shortnames: [':couple_with_heart_woman_woman_medium_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone4:': { + uc_base: '1f469-1f3fe-2764-1f469-1f3fe', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fe', + shortnames: [':couple_with_heart_woman_woman_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone4_tone1:': { + uc_base: '1f469-1f3fe-2764-1f469-1f3fb', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fb', + shortnames: [':couple_with_heart_woman_woman_medium_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone4_tone2:': { + uc_base: '1f469-1f3fe-2764-1f469-1f3fc', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fc', + shortnames: [':couple_with_heart_woman_woman_medium_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone4_tone3:': { + uc_base: '1f469-1f3fe-2764-1f469-1f3fd', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3fd', + shortnames: [':couple_with_heart_woman_woman_medium_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone4_tone5:': { + uc_base: '1f469-1f3fe-2764-1f469-1f3ff', + uc_full: '1f469-1f3fe-200d-2764-fe0f-200d-1f469-1f3ff', + shortnames: [':couple_with_heart_woman_woman_medium_dark_skin_tone_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone5:': { + uc_base: '1f469-1f3ff-2764-1f469-1f3ff', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3ff', + shortnames: [':couple_with_heart_woman_woman_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone5_tone1:': { + uc_base: '1f469-1f3ff-2764-1f469-1f3fb', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fb', + shortnames: [':couple_with_heart_woman_woman_dark_skin_tone_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone5_tone2:': { + uc_base: '1f469-1f3ff-2764-1f469-1f3fc', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fc', + shortnames: [':couple_with_heart_woman_woman_dark_skin_tone_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone5_tone3:': { + uc_base: '1f469-1f3ff-2764-1f469-1f3fd', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fd', + shortnames: [':couple_with_heart_woman_woman_dark_skin_tone_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_woman_woman_tone5_tone4:': { + uc_base: '1f469-1f3ff-2764-1f469-1f3fe', + uc_full: '1f469-1f3ff-200d-2764-fe0f-200d-1f469-1f3fe', + shortnames: [':couple_with_heart_woman_woman_dark_skin_tone_medium_dark_skin_tone:'], + category: 'people', + }, + ':family_mmbb:': { + uc_base: '1f468-1f468-1f466-1f466', + uc_full: '1f468-200d-1f468-200d-1f466-200d-1f466', + shortnames: [], + category: 'people', + }, + ':family_mmgb:': { + uc_base: '1f468-1f468-1f467-1f466', + uc_full: '1f468-200d-1f468-200d-1f467-200d-1f466', + shortnames: [], + category: 'people', + }, + ':family_mmgg:': { + uc_base: '1f468-1f468-1f467-1f467', + uc_full: '1f468-200d-1f468-200d-1f467-200d-1f467', + shortnames: [], + category: 'people', + }, + ':family_mwbb:': { + uc_base: '1f468-1f469-1f466-1f466', + uc_full: '1f468-200d-1f469-200d-1f466-200d-1f466', + shortnames: [], + category: 'people', + }, + ':family_mwgb:': { + uc_base: '1f468-1f469-1f467-1f466', + uc_full: '1f468-200d-1f469-200d-1f467-200d-1f466', + shortnames: [], + category: 'people', + }, + ':family_mwgg:': { + uc_base: '1f468-1f469-1f467-1f467', + uc_full: '1f468-200d-1f469-200d-1f467-200d-1f467', + shortnames: [], + category: 'people', + }, + ':family_wwbb:': { + uc_base: '1f469-1f469-1f466-1f466', + uc_full: '1f469-200d-1f469-200d-1f466-200d-1f466', + shortnames: [], + category: 'people', + }, + ':family_wwgb:': { + uc_base: '1f469-1f469-1f467-1f466', + uc_full: '1f469-200d-1f469-200d-1f467-200d-1f466', + shortnames: [], + category: 'people', + }, + ':family_wwgg:': { + uc_base: '1f469-1f469-1f467-1f467', + uc_full: '1f469-200d-1f469-200d-1f467-200d-1f467', + shortnames: [], + category: 'people', + }, + ':kiss_mm:': { + uc_base: '1f468-2764-1f48b-1f468', + uc_full: '1f468-200d-2764-fe0f-200d-1f48b-200d-1f468', + shortnames: [':couplekiss_mm:'], + category: 'people', + }, + ':kiss_woman_man:': { + uc_base: '1f469-2764-1f48b-1f468', + uc_full: '1f469-200d-2764-fe0f-200d-1f48b-200d-1f468', + shortnames: [], + category: 'people', + }, + ':kiss_ww:': { + uc_base: '1f469-2764-1f48b-1f469', + uc_full: '1f469-200d-2764-fe0f-200d-1f48b-200d-1f469', + shortnames: [':couplekiss_ww:'], + category: 'people', + }, + ':artist_tone1:': { + uc_base: '1f9d1-1f3fb-1f3a8', + uc_full: '1f9d1-1f3fb-200d-1f3a8', + shortnames: [':artist_light_skin_tone:'], + category: 'people', + }, + ':artist_tone2:': { + uc_base: '1f9d1-1f3fc-1f3a8', + uc_full: '1f9d1-1f3fc-200d-1f3a8', + shortnames: [':artist_medium_light_skin_tone:'], + category: 'people', + }, + ':artist_tone3:': { + uc_base: '1f9d1-1f3fd-1f3a8', + uc_full: '1f9d1-1f3fd-200d-1f3a8', + shortnames: [':artist_medium_skin_tone:'], + category: 'people', + }, + ':artist_tone4:': { + uc_base: '1f9d1-1f3fe-1f3a8', + uc_full: '1f9d1-1f3fe-200d-1f3a8', + shortnames: [':artist_medium_dark_skin_tone:'], + category: 'people', + }, + ':artist_tone5:': { + uc_base: '1f9d1-1f3ff-1f3a8', + uc_full: '1f9d1-1f3ff-200d-1f3a8', + shortnames: [':artist_dark_skin_tone:'], + category: 'people', + }, + ':astronaut_tone1:': { + uc_base: '1f9d1-1f3fb-1f680', + uc_full: '1f9d1-1f3fb-200d-1f680', + shortnames: [':astronaut_light_skin_tone:'], + category: 'people', + }, + ':astronaut_tone2:': { + uc_base: '1f9d1-1f3fc-1f680', + uc_full: '1f9d1-1f3fc-200d-1f680', + shortnames: [':astronaut_medium_light_skin_tone:'], + category: 'people', + }, + ':astronaut_tone3:': { + uc_base: '1f9d1-1f3fd-1f680', + uc_full: '1f9d1-1f3fd-200d-1f680', + shortnames: [':astronaut_medium_skin_tone:'], + category: 'people', + }, + ':astronaut_tone4:': { + uc_base: '1f9d1-1f3fe-1f680', + uc_full: '1f9d1-1f3fe-200d-1f680', + shortnames: [':astronaut_medium_dark_skin_tone:'], + category: 'people', + }, + ':astronaut_tone5:': { + uc_base: '1f9d1-1f3ff-1f680', + uc_full: '1f9d1-1f3ff-200d-1f680', + shortnames: [':astronaut_dark_skin_tone:'], + category: 'people', + }, + ':cook_tone1:': { + uc_base: '1f9d1-1f3fb-1f373', + uc_full: '1f9d1-1f3fb-200d-1f373', + shortnames: [':cook_light_skin_tone:'], + category: 'people', + }, + ':cook_tone2:': { + uc_base: '1f9d1-1f3fc-1f373', + uc_full: '1f9d1-1f3fc-200d-1f373', + shortnames: [':cook_medium_light_skin_tone:'], + category: 'people', + }, + ':cook_tone3:': { + uc_base: '1f9d1-1f3fd-1f373', + uc_full: '1f9d1-1f3fd-200d-1f373', + shortnames: [':cook_medium_skin_tone:'], + category: 'people', + }, + ':cook_tone4:': { + uc_base: '1f9d1-1f3fe-1f373', + uc_full: '1f9d1-1f3fe-200d-1f373', + shortnames: [':cook_medium_dark_skin_tone:'], + category: 'people', + }, + ':cook_tone5:': { + uc_base: '1f9d1-1f3ff-1f373', + uc_full: '1f9d1-1f3ff-200d-1f373', + shortnames: [':cook_dark_skin_tone:'], + category: 'people', + }, + ':factory_worker_tone1:': { + uc_base: '1f9d1-1f3fb-1f3ed', + uc_full: '1f9d1-1f3fb-200d-1f3ed', + shortnames: [':factory_worker_light_skin_tone:'], + category: 'people', + }, + ':factory_worker_tone2:': { + uc_base: '1f9d1-1f3fc-1f3ed', + uc_full: '1f9d1-1f3fc-200d-1f3ed', + shortnames: [':factory_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':factory_worker_tone3:': { + uc_base: '1f9d1-1f3fd-1f3ed', + uc_full: '1f9d1-1f3fd-200d-1f3ed', + shortnames: [':factory_worker_medium_skin_tone:'], + category: 'people', + }, + ':factory_worker_tone4:': { + uc_base: '1f9d1-1f3fe-1f3ed', + uc_full: '1f9d1-1f3fe-200d-1f3ed', + shortnames: [':factory_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':factory_worker_tone5:': { + uc_base: '1f9d1-1f3ff-1f3ed', + uc_full: '1f9d1-1f3ff-200d-1f3ed', + shortnames: [':factory_worker_dark_skin_tone:'], + category: 'people', + }, + ':family_man_boy_boy:': { uc_base: '1f468-1f466-1f466', uc_full: '1f468-200d-1f466-200d-1f466', shortnames: [], category: 'people' }, + ':family_man_girl_boy:': { uc_base: '1f468-1f467-1f466', uc_full: '1f468-200d-1f467-200d-1f466', shortnames: [], category: 'people' }, + ':family_man_girl_girl:': { uc_base: '1f468-1f467-1f467', uc_full: '1f468-200d-1f467-200d-1f467', shortnames: [], category: 'people' }, + ':family_man_woman_boy:': { uc_base: '1f468-1f469-1f466', uc_full: '1f468-200d-1f469-200d-1f466', shortnames: [], category: 'people' }, + ':family_mmb:': { uc_base: '1f468-1f468-1f466', uc_full: '1f468-200d-1f468-200d-1f466', shortnames: [], category: 'people' }, + ':family_mmg:': { uc_base: '1f468-1f468-1f467', uc_full: '1f468-200d-1f468-200d-1f467', shortnames: [], category: 'people' }, + ':family_mwg:': { uc_base: '1f468-1f469-1f467', uc_full: '1f468-200d-1f469-200d-1f467', shortnames: [], category: 'people' }, + ':family_woman_boy_boy:': { uc_base: '1f469-1f466-1f466', uc_full: '1f469-200d-1f466-200d-1f466', shortnames: [], category: 'people' }, + ':family_woman_girl_boy:': { uc_base: '1f469-1f467-1f466', uc_full: '1f469-200d-1f467-200d-1f466', shortnames: [], category: 'people' }, + ':family_woman_girl_girl:': { + uc_base: '1f469-1f467-1f467', + uc_full: '1f469-200d-1f467-200d-1f467', + shortnames: [], + category: 'people', + }, + ':family_wwb:': { uc_base: '1f469-1f469-1f466', uc_full: '1f469-200d-1f469-200d-1f466', shortnames: [], category: 'people' }, + ':family_wwg:': { uc_base: '1f469-1f469-1f467', uc_full: '1f469-200d-1f469-200d-1f467', shortnames: [], category: 'people' }, + ':farmer_tone1:': { + uc_base: '1f9d1-1f3fb-1f33e', + uc_full: '1f9d1-1f3fb-200d-1f33e', + shortnames: [':farmer_light_skin_tone:'], + category: 'people', + }, + ':farmer_tone2:': { + uc_base: '1f9d1-1f3fc-1f33e', + uc_full: '1f9d1-1f3fc-200d-1f33e', + shortnames: [':farmer_medium_light_skin_tone:'], + category: 'people', + }, + ':farmer_tone3:': { + uc_base: '1f9d1-1f3fd-1f33e', + uc_full: '1f9d1-1f3fd-200d-1f33e', + shortnames: [':farmer_medium_skin_tone:'], + category: 'people', + }, + ':farmer_tone4:': { + uc_base: '1f9d1-1f3fe-1f33e', + uc_full: '1f9d1-1f3fe-200d-1f33e', + shortnames: [':farmer_medium_dark_skin_tone:'], + category: 'people', + }, + ':farmer_tone5:': { + uc_base: '1f9d1-1f3ff-1f33e', + uc_full: '1f9d1-1f3ff-200d-1f33e', + shortnames: [':farmer_dark_skin_tone:'], + category: 'people', + }, + ':firefighter_tone1:': { + uc_base: '1f9d1-1f3fb-1f692', + uc_full: '1f9d1-1f3fb-200d-1f692', + shortnames: [':firefighter_light_skin_tone:'], + category: 'people', + }, + ':firefighter_tone2:': { + uc_base: '1f9d1-1f3fc-1f692', + uc_full: '1f9d1-1f3fc-200d-1f692', + shortnames: [':firefighter_medium_light_skin_tone:'], + category: 'people', + }, + ':firefighter_tone3:': { + uc_base: '1f9d1-1f3fd-1f692', + uc_full: '1f9d1-1f3fd-200d-1f692', + shortnames: [':firefighter_medium_skin_tone:'], + category: 'people', + }, + ':firefighter_tone4:': { + uc_base: '1f9d1-1f3fe-1f692', + uc_full: '1f9d1-1f3fe-200d-1f692', + shortnames: [':firefighter_medium_dark_skin_tone:'], + category: 'people', + }, + ':firefighter_tone5:': { + uc_base: '1f9d1-1f3ff-1f692', + uc_full: '1f9d1-1f3ff-200d-1f692', + shortnames: [':firefighter_dark_skin_tone:'], + category: 'people', + }, + ':man_artist_tone1:': { + uc_base: '1f468-1f3fb-1f3a8', + uc_full: '1f468-1f3fb-200d-1f3a8', + shortnames: [':man_artist_light_skin_tone:'], + category: 'people', + }, + ':man_artist_tone2:': { + uc_base: '1f468-1f3fc-1f3a8', + uc_full: '1f468-1f3fc-200d-1f3a8', + shortnames: [':man_artist_medium_light_skin_tone:'], + category: 'people', + }, + ':man_artist_tone3:': { + uc_base: '1f468-1f3fd-1f3a8', + uc_full: '1f468-1f3fd-200d-1f3a8', + shortnames: [':man_artist_medium_skin_tone:'], + category: 'people', + }, + ':man_artist_tone4:': { + uc_base: '1f468-1f3fe-1f3a8', + uc_full: '1f468-1f3fe-200d-1f3a8', + shortnames: [':man_artist_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_artist_tone5:': { + uc_base: '1f468-1f3ff-1f3a8', + uc_full: '1f468-1f3ff-200d-1f3a8', + shortnames: [':man_artist_dark_skin_tone:'], + category: 'people', + }, + ':man_astronaut_tone1:': { + uc_base: '1f468-1f3fb-1f680', + uc_full: '1f468-1f3fb-200d-1f680', + shortnames: [':man_astronaut_light_skin_tone:'], + category: 'people', + }, + ':man_astronaut_tone2:': { + uc_base: '1f468-1f3fc-1f680', + uc_full: '1f468-1f3fc-200d-1f680', + shortnames: [':man_astronaut_medium_light_skin_tone:'], + category: 'people', + }, + ':man_astronaut_tone3:': { + uc_base: '1f468-1f3fd-1f680', + uc_full: '1f468-1f3fd-200d-1f680', + shortnames: [':man_astronaut_medium_skin_tone:'], + category: 'people', + }, + ':man_astronaut_tone4:': { + uc_base: '1f468-1f3fe-1f680', + uc_full: '1f468-1f3fe-200d-1f680', + shortnames: [':man_astronaut_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_astronaut_tone5:': { + uc_base: '1f468-1f3ff-1f680', + uc_full: '1f468-1f3ff-200d-1f680', + shortnames: [':man_astronaut_dark_skin_tone:'], + category: 'people', + }, + ':man_bald_tone1:': { + uc_base: '1f468-1f3fb-1f9b2', + uc_full: '1f468-1f3fb-200d-1f9b2', + shortnames: [':man_bald_light_skin_tone:'], + category: 'people', + }, + ':man_bald_tone2:': { + uc_base: '1f468-1f3fc-1f9b2', + uc_full: '1f468-1f3fc-200d-1f9b2', + shortnames: [':man_bald_medium_light_skin_tone:'], + category: 'people', + }, + ':man_bald_tone3:': { + uc_base: '1f468-1f3fd-1f9b2', + uc_full: '1f468-1f3fd-200d-1f9b2', + shortnames: [':man_bald_medium_skin_tone:'], + category: 'people', + }, + ':man_bald_tone4:': { + uc_base: '1f468-1f3fe-1f9b2', + uc_full: '1f468-1f3fe-200d-1f9b2', + shortnames: [':man_bald_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_bald_tone5:': { + uc_base: '1f468-1f3ff-1f9b2', + uc_full: '1f468-1f3ff-200d-1f9b2', + shortnames: [':man_bald_dark_skin_tone:'], + category: 'people', + }, + ':man_cook_tone1:': { + uc_base: '1f468-1f3fb-1f373', + uc_full: '1f468-1f3fb-200d-1f373', + shortnames: [':man_cook_light_skin_tone:'], + category: 'people', + }, + ':man_cook_tone2:': { + uc_base: '1f468-1f3fc-1f373', + uc_full: '1f468-1f3fc-200d-1f373', + shortnames: [':man_cook_medium_light_skin_tone:'], + category: 'people', + }, + ':man_cook_tone3:': { + uc_base: '1f468-1f3fd-1f373', + uc_full: '1f468-1f3fd-200d-1f373', + shortnames: [':man_cook_medium_skin_tone:'], + category: 'people', + }, + ':man_cook_tone4:': { + uc_base: '1f468-1f3fe-1f373', + uc_full: '1f468-1f3fe-200d-1f373', + shortnames: [':man_cook_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_cook_tone5:': { + uc_base: '1f468-1f3ff-1f373', + uc_full: '1f468-1f3ff-200d-1f373', + shortnames: [':man_cook_dark_skin_tone:'], + category: 'people', + }, + ':man_curly_haired_tone1:': { + uc_base: '1f468-1f3fb-1f9b1', + uc_full: '1f468-1f3fb-200d-1f9b1', + shortnames: [':man_curly_haired_light_skin_tone:'], + category: 'people', + }, + ':man_curly_haired_tone2:': { + uc_base: '1f468-1f3fc-1f9b1', + uc_full: '1f468-1f3fc-200d-1f9b1', + shortnames: [':man_curly_haired_medium_light_skin_tone:'], + category: 'people', + }, + ':man_curly_haired_tone3:': { + uc_base: '1f468-1f3fd-1f9b1', + uc_full: '1f468-1f3fd-200d-1f9b1', + shortnames: [':man_curly_haired_medium_skin_tone:'], + category: 'people', + }, + ':man_curly_haired_tone4:': { + uc_base: '1f468-1f3fe-1f9b1', + uc_full: '1f468-1f3fe-200d-1f9b1', + shortnames: [':man_curly_haired_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_curly_haired_tone5:': { + uc_base: '1f468-1f3ff-1f9b1', + uc_full: '1f468-1f3ff-200d-1f9b1', + shortnames: [':man_curly_haired_dark_skin_tone:'], + category: 'people', + }, + ':man_factory_worker_tone1:': { + uc_base: '1f468-1f3fb-1f3ed', + uc_full: '1f468-1f3fb-200d-1f3ed', + shortnames: [':man_factory_worker_light_skin_tone:'], + category: 'people', + }, + ':man_factory_worker_tone2:': { + uc_base: '1f468-1f3fc-1f3ed', + uc_full: '1f468-1f3fc-200d-1f3ed', + shortnames: [':man_factory_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':man_factory_worker_tone3:': { + uc_base: '1f468-1f3fd-1f3ed', + uc_full: '1f468-1f3fd-200d-1f3ed', + shortnames: [':man_factory_worker_medium_skin_tone:'], + category: 'people', + }, + ':man_factory_worker_tone4:': { + uc_base: '1f468-1f3fe-1f3ed', + uc_full: '1f468-1f3fe-200d-1f3ed', + shortnames: [':man_factory_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_factory_worker_tone5:': { + uc_base: '1f468-1f3ff-1f3ed', + uc_full: '1f468-1f3ff-200d-1f3ed', + shortnames: [':man_factory_worker_dark_skin_tone:'], + category: 'people', + }, + ':man_farmer_tone1:': { + uc_base: '1f468-1f3fb-1f33e', + uc_full: '1f468-1f3fb-200d-1f33e', + shortnames: [':man_farmer_light_skin_tone:'], + category: 'people', + }, + ':man_farmer_tone2:': { + uc_base: '1f468-1f3fc-1f33e', + uc_full: '1f468-1f3fc-200d-1f33e', + shortnames: [':man_farmer_medium_light_skin_tone:'], + category: 'people', + }, + ':man_farmer_tone3:': { + uc_base: '1f468-1f3fd-1f33e', + uc_full: '1f468-1f3fd-200d-1f33e', + shortnames: [':man_farmer_medium_skin_tone:'], + category: 'people', + }, + ':man_farmer_tone4:': { + uc_base: '1f468-1f3fe-1f33e', + uc_full: '1f468-1f3fe-200d-1f33e', + shortnames: [':man_farmer_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_farmer_tone5:': { + uc_base: '1f468-1f3ff-1f33e', + uc_full: '1f468-1f3ff-200d-1f33e', + shortnames: [':man_farmer_dark_skin_tone:'], + category: 'people', + }, + ':man_feeding_baby_tone1:': { + uc_base: '1f468-1f3fb-1f37c', + uc_full: '1f468-1f3fb-200d-1f37c', + shortnames: [':man_feeding_baby_light_skin_tone:'], + category: 'people', + }, + ':man_feeding_baby_tone2:': { + uc_base: '1f468-1f3fc-1f37c', + uc_full: '1f468-1f3fc-200d-1f37c', + shortnames: [':man_feeding_baby_medium_light_skin_tone:'], + category: 'people', + }, + ':man_feeding_baby_tone3:': { + uc_base: '1f468-1f3fd-1f37c', + uc_full: '1f468-1f3fd-200d-1f37c', + shortnames: [':man_feeding_baby_medium_skin_tone:'], + category: 'people', + }, + ':man_feeding_baby_tone4:': { + uc_base: '1f468-1f3fe-1f37c', + uc_full: '1f468-1f3fe-200d-1f37c', + shortnames: [':man_feeding_baby_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_feeding_baby_tone5:': { + uc_base: '1f468-1f3ff-1f37c', + uc_full: '1f468-1f3ff-200d-1f37c', + shortnames: [':man_feeding_baby_dark_skin_tone:'], + category: 'people', + }, + ':man_firefighter_tone1:': { + uc_base: '1f468-1f3fb-1f692', + uc_full: '1f468-1f3fb-200d-1f692', + shortnames: [':man_firefighter_light_skin_tone:'], + category: 'people', + }, + ':man_firefighter_tone2:': { + uc_base: '1f468-1f3fc-1f692', + uc_full: '1f468-1f3fc-200d-1f692', + shortnames: [':man_firefighter_medium_light_skin_tone:'], + category: 'people', + }, + ':man_firefighter_tone3:': { + uc_base: '1f468-1f3fd-1f692', + uc_full: '1f468-1f3fd-200d-1f692', + shortnames: [':man_firefighter_medium_skin_tone:'], + category: 'people', + }, + ':man_firefighter_tone4:': { + uc_base: '1f468-1f3fe-1f692', + uc_full: '1f468-1f3fe-200d-1f692', + shortnames: [':man_firefighter_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_firefighter_tone5:': { + uc_base: '1f468-1f3ff-1f692', + uc_full: '1f468-1f3ff-200d-1f692', + shortnames: [':man_firefighter_dark_skin_tone:'], + category: 'people', + }, + ':man_in_manual_wheelchair_tone1:': { + uc_base: '1f468-1f3fb-1f9bd', + uc_full: '1f468-1f3fb-200d-1f9bd', + shortnames: [':man_in_manual_wheelchair_light_skin_tone:'], + category: 'people', + }, + ':man_in_manual_wheelchair_tone2:': { + uc_base: '1f468-1f3fc-1f9bd', + uc_full: '1f468-1f3fc-200d-1f9bd', + shortnames: [':man_in_manual_wheelchair_medium_light_skin_tone:'], + category: 'people', + }, + ':man_in_manual_wheelchair_tone3:': { + uc_base: '1f468-1f3fd-1f9bd', + uc_full: '1f468-1f3fd-200d-1f9bd', + shortnames: [':man_in_manual_wheelchair_medium_skin_tone:'], + category: 'people', + }, + ':man_in_manual_wheelchair_tone4:': { + uc_base: '1f468-1f3fe-1f9bd', + uc_full: '1f468-1f3fe-200d-1f9bd', + shortnames: [':man_in_manual_wheelchair_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_in_manual_wheelchair_tone5:': { + uc_base: '1f468-1f3ff-1f9bd', + uc_full: '1f468-1f3ff-200d-1f9bd', + shortnames: [':man_in_manual_wheelchair_dark_skin_tone:'], + category: 'people', + }, + ':man_in_motorized_wheelchair_tone1:': { + uc_base: '1f468-1f3fb-1f9bc', + uc_full: '1f468-1f3fb-200d-1f9bc', + shortnames: [':man_in_motorized_wheelchair_light_skin_tone:'], + category: 'people', + }, + ':man_in_motorized_wheelchair_tone2:': { + uc_base: '1f468-1f3fc-1f9bc', + uc_full: '1f468-1f3fc-200d-1f9bc', + shortnames: [':man_in_motorized_wheelchair_medium_light_skin_tone:'], + category: 'people', + }, + ':man_in_motorized_wheelchair_tone3:': { + uc_base: '1f468-1f3fd-1f9bc', + uc_full: '1f468-1f3fd-200d-1f9bc', + shortnames: [':man_in_motorized_wheelchair_medium_skin_tone:'], + category: 'people', + }, + ':man_in_motorized_wheelchair_tone4:': { + uc_base: '1f468-1f3fe-1f9bc', + uc_full: '1f468-1f3fe-200d-1f9bc', + shortnames: [':man_in_motorized_wheelchair_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_in_motorized_wheelchair_tone5:': { + uc_base: '1f468-1f3ff-1f9bc', + uc_full: '1f468-1f3ff-200d-1f9bc', + shortnames: [':man_in_motorized_wheelchair_dark_skin_tone:'], + category: 'people', + }, + ':man_mechanic_tone1:': { + uc_base: '1f468-1f3fb-1f527', + uc_full: '1f468-1f3fb-200d-1f527', + shortnames: [':man_mechanic_light_skin_tone:'], + category: 'people', + }, + ':man_mechanic_tone2:': { + uc_base: '1f468-1f3fc-1f527', + uc_full: '1f468-1f3fc-200d-1f527', + shortnames: [':man_mechanic_medium_light_skin_tone:'], + category: 'people', + }, + ':man_mechanic_tone3:': { + uc_base: '1f468-1f3fd-1f527', + uc_full: '1f468-1f3fd-200d-1f527', + shortnames: [':man_mechanic_medium_skin_tone:'], + category: 'people', + }, + ':man_mechanic_tone4:': { + uc_base: '1f468-1f3fe-1f527', + uc_full: '1f468-1f3fe-200d-1f527', + shortnames: [':man_mechanic_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_mechanic_tone5:': { + uc_base: '1f468-1f3ff-1f527', + uc_full: '1f468-1f3ff-200d-1f527', + shortnames: [':man_mechanic_dark_skin_tone:'], + category: 'people', + }, + ':man_office_worker_tone1:': { + uc_base: '1f468-1f3fb-1f4bc', + uc_full: '1f468-1f3fb-200d-1f4bc', + shortnames: [':man_office_worker_light_skin_tone:'], + category: 'people', + }, + ':man_office_worker_tone2:': { + uc_base: '1f468-1f3fc-1f4bc', + uc_full: '1f468-1f3fc-200d-1f4bc', + shortnames: [':man_office_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':man_office_worker_tone3:': { + uc_base: '1f468-1f3fd-1f4bc', + uc_full: '1f468-1f3fd-200d-1f4bc', + shortnames: [':man_office_worker_medium_skin_tone:'], + category: 'people', + }, + ':man_office_worker_tone4:': { + uc_base: '1f468-1f3fe-1f4bc', + uc_full: '1f468-1f3fe-200d-1f4bc', + shortnames: [':man_office_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_office_worker_tone5:': { + uc_base: '1f468-1f3ff-1f4bc', + uc_full: '1f468-1f3ff-200d-1f4bc', + shortnames: [':man_office_worker_dark_skin_tone:'], + category: 'people', + }, + ':man_red_haired_tone1:': { + uc_base: '1f468-1f3fb-1f9b0', + uc_full: '1f468-1f3fb-200d-1f9b0', + shortnames: [':man_red_haired_light_skin_tone:'], + category: 'people', + }, + ':man_red_haired_tone2:': { + uc_base: '1f468-1f3fc-1f9b0', + uc_full: '1f468-1f3fc-200d-1f9b0', + shortnames: [':man_red_haired_medium_light_skin_tone:'], + category: 'people', + }, + ':man_red_haired_tone3:': { + uc_base: '1f468-1f3fd-1f9b0', + uc_full: '1f468-1f3fd-200d-1f9b0', + shortnames: [':man_red_haired_medium_skin_tone:'], + category: 'people', + }, + ':man_red_haired_tone4:': { + uc_base: '1f468-1f3fe-1f9b0', + uc_full: '1f468-1f3fe-200d-1f9b0', + shortnames: [':man_red_haired_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_red_haired_tone5:': { + uc_base: '1f468-1f3ff-1f9b0', + uc_full: '1f468-1f3ff-200d-1f9b0', + shortnames: [':man_red_haired_dark_skin_tone:'], + category: 'people', + }, + ':man_scientist_tone1:': { + uc_base: '1f468-1f3fb-1f52c', + uc_full: '1f468-1f3fb-200d-1f52c', + shortnames: [':man_scientist_light_skin_tone:'], + category: 'people', + }, + ':man_scientist_tone2:': { + uc_base: '1f468-1f3fc-1f52c', + uc_full: '1f468-1f3fc-200d-1f52c', + shortnames: [':man_scientist_medium_light_skin_tone:'], + category: 'people', + }, + ':man_scientist_tone3:': { + uc_base: '1f468-1f3fd-1f52c', + uc_full: '1f468-1f3fd-200d-1f52c', + shortnames: [':man_scientist_medium_skin_tone:'], + category: 'people', + }, + ':man_scientist_tone4:': { + uc_base: '1f468-1f3fe-1f52c', + uc_full: '1f468-1f3fe-200d-1f52c', + shortnames: [':man_scientist_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_scientist_tone5:': { + uc_base: '1f468-1f3ff-1f52c', + uc_full: '1f468-1f3ff-200d-1f52c', + shortnames: [':man_scientist_dark_skin_tone:'], + category: 'people', + }, + ':man_singer_tone1:': { + uc_base: '1f468-1f3fb-1f3a4', + uc_full: '1f468-1f3fb-200d-1f3a4', + shortnames: [':man_singer_light_skin_tone:'], + category: 'people', + }, + ':man_singer_tone2:': { + uc_base: '1f468-1f3fc-1f3a4', + uc_full: '1f468-1f3fc-200d-1f3a4', + shortnames: [':man_singer_medium_light_skin_tone:'], + category: 'people', + }, + ':man_singer_tone3:': { + uc_base: '1f468-1f3fd-1f3a4', + uc_full: '1f468-1f3fd-200d-1f3a4', + shortnames: [':man_singer_medium_skin_tone:'], + category: 'people', + }, + ':man_singer_tone4:': { + uc_base: '1f468-1f3fe-1f3a4', + uc_full: '1f468-1f3fe-200d-1f3a4', + shortnames: [':man_singer_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_singer_tone5:': { + uc_base: '1f468-1f3ff-1f3a4', + uc_full: '1f468-1f3ff-200d-1f3a4', + shortnames: [':man_singer_dark_skin_tone:'], + category: 'people', + }, + ':man_student_tone1:': { + uc_base: '1f468-1f3fb-1f393', + uc_full: '1f468-1f3fb-200d-1f393', + shortnames: [':man_student_light_skin_tone:'], + category: 'people', + }, + ':man_student_tone2:': { + uc_base: '1f468-1f3fc-1f393', + uc_full: '1f468-1f3fc-200d-1f393', + shortnames: [':man_student_medium_light_skin_tone:'], + category: 'people', + }, + ':man_student_tone3:': { + uc_base: '1f468-1f3fd-1f393', + uc_full: '1f468-1f3fd-200d-1f393', + shortnames: [':man_student_medium_skin_tone:'], + category: 'people', + }, + ':man_student_tone4:': { + uc_base: '1f468-1f3fe-1f393', + uc_full: '1f468-1f3fe-200d-1f393', + shortnames: [':man_student_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_student_tone5:': { + uc_base: '1f468-1f3ff-1f393', + uc_full: '1f468-1f3ff-200d-1f393', + shortnames: [':man_student_dark_skin_tone:'], + category: 'people', + }, + ':man_teacher_tone1:': { + uc_base: '1f468-1f3fb-1f3eb', + uc_full: '1f468-1f3fb-200d-1f3eb', + shortnames: [':man_teacher_light_skin_tone:'], + category: 'people', + }, + ':man_teacher_tone2:': { + uc_base: '1f468-1f3fc-1f3eb', + uc_full: '1f468-1f3fc-200d-1f3eb', + shortnames: [':man_teacher_medium_light_skin_tone:'], + category: 'people', + }, + ':man_teacher_tone3:': { + uc_base: '1f468-1f3fd-1f3eb', + uc_full: '1f468-1f3fd-200d-1f3eb', + shortnames: [':man_teacher_medium_skin_tone:'], + category: 'people', + }, + ':man_teacher_tone4:': { + uc_base: '1f468-1f3fe-1f3eb', + uc_full: '1f468-1f3fe-200d-1f3eb', + shortnames: [':man_teacher_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_teacher_tone5:': { + uc_base: '1f468-1f3ff-1f3eb', + uc_full: '1f468-1f3ff-200d-1f3eb', + shortnames: [':man_teacher_dark_skin_tone:'], + category: 'people', + }, + ':man_technologist_tone1:': { + uc_base: '1f468-1f3fb-1f4bb', + uc_full: '1f468-1f3fb-200d-1f4bb', + shortnames: [':man_technologist_light_skin_tone:'], + category: 'people', + }, + ':man_technologist_tone2:': { + uc_base: '1f468-1f3fc-1f4bb', + uc_full: '1f468-1f3fc-200d-1f4bb', + shortnames: [':man_technologist_medium_light_skin_tone:'], + category: 'people', + }, + ':man_technologist_tone3:': { + uc_base: '1f468-1f3fd-1f4bb', + uc_full: '1f468-1f3fd-200d-1f4bb', + shortnames: [':man_technologist_medium_skin_tone:'], + category: 'people', + }, + ':man_technologist_tone4:': { + uc_base: '1f468-1f3fe-1f4bb', + uc_full: '1f468-1f3fe-200d-1f4bb', + shortnames: [':man_technologist_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_technologist_tone5:': { + uc_base: '1f468-1f3ff-1f4bb', + uc_full: '1f468-1f3ff-200d-1f4bb', + shortnames: [':man_technologist_dark_skin_tone:'], + category: 'people', + }, + ':man_white_haired_tone1:': { + uc_base: '1f468-1f3fb-1f9b3', + uc_full: '1f468-1f3fb-200d-1f9b3', + shortnames: [':man_white_haired_light_skin_tone:'], + category: 'people', + }, + ':man_white_haired_tone2:': { + uc_base: '1f468-1f3fc-1f9b3', + uc_full: '1f468-1f3fc-200d-1f9b3', + shortnames: [':man_white_haired_medium_light_skin_tone:'], + category: 'people', + }, + ':man_white_haired_tone3:': { + uc_base: '1f468-1f3fd-1f9b3', + uc_full: '1f468-1f3fd-200d-1f9b3', + shortnames: [':man_white_haired_medium_skin_tone:'], + category: 'people', + }, + ':man_white_haired_tone4:': { + uc_base: '1f468-1f3fe-1f9b3', + uc_full: '1f468-1f3fe-200d-1f9b3', + shortnames: [':man_white_haired_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_white_haired_tone5:': { + uc_base: '1f468-1f3ff-1f9b3', + uc_full: '1f468-1f3ff-200d-1f9b3', + shortnames: [':man_white_haired_dark_skin_tone:'], + category: 'people', + }, + ':man_with_probing_cane_tone1:': { + uc_base: '1f468-1f3fb-1f9af', + uc_full: '1f468-1f3fb-200d-1f9af', + shortnames: [':man_with_probing_cane_light_skin_tone:'], + category: 'people', + }, + ':man_with_probing_cane_tone2:': { + uc_base: '1f468-1f3fc-1f9af', + uc_full: '1f468-1f3fc-200d-1f9af', + shortnames: [':man_with_probing_cane_medium_light_skin_tone:'], + category: 'people', + }, + ':man_with_probing_cane_tone3:': { + uc_base: '1f468-1f3fd-1f9af', + uc_full: '1f468-1f3fd-200d-1f9af', + shortnames: [':man_with_probing_cane_medium_skin_tone:'], + category: 'people', + }, + ':man_with_probing_cane_tone4:': { + uc_base: '1f468-1f3fe-1f9af', + uc_full: '1f468-1f3fe-200d-1f9af', + shortnames: [':man_with_probing_cane_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_with_probing_cane_tone5:': { + uc_base: '1f468-1f3ff-1f9af', + uc_full: '1f468-1f3ff-200d-1f9af', + shortnames: [':man_with_probing_cane_dark_skin_tone:'], + category: 'people', + }, + ':mechanic_tone1:': { + uc_base: '1f9d1-1f3fb-1f527', + uc_full: '1f9d1-1f3fb-200d-1f527', + shortnames: [':mechanic_light_skin_tone:'], + category: 'people', + }, + ':mechanic_tone2:': { + uc_base: '1f9d1-1f3fc-1f527', + uc_full: '1f9d1-1f3fc-200d-1f527', + shortnames: [':mechanic_medium_light_skin_tone:'], + category: 'people', + }, + ':mechanic_tone3:': { + uc_base: '1f9d1-1f3fd-1f527', + uc_full: '1f9d1-1f3fd-200d-1f527', + shortnames: [':mechanic_medium_skin_tone:'], + category: 'people', + }, + ':mechanic_tone4:': { + uc_base: '1f9d1-1f3fe-1f527', + uc_full: '1f9d1-1f3fe-200d-1f527', + shortnames: [':mechanic_medium_dark_skin_tone:'], + category: 'people', + }, + ':mechanic_tone5:': { + uc_base: '1f9d1-1f3ff-1f527', + uc_full: '1f9d1-1f3ff-200d-1f527', + shortnames: [':mechanic_dark_skin_tone:'], + category: 'people', + }, + ':mx_claus_tone1:': { + uc_base: '1f9d1-1f3fb-1f384', + uc_full: '1f9d1-1f3fb-200d-1f384', + shortnames: [':mx_claus_light_skin_tone:'], + category: 'people', + }, + ':mx_claus_tone2:': { + uc_base: '1f9d1-1f3fc-1f384', + uc_full: '1f9d1-1f3fc-200d-1f384', + shortnames: [':mx_claus_medium_light_skin_tone:'], + category: 'people', + }, + ':mx_claus_tone3:': { + uc_base: '1f9d1-1f3fd-1f384', + uc_full: '1f9d1-1f3fd-200d-1f384', + shortnames: [':mx_claus_medium_skin_tone:'], + category: 'people', + }, + ':mx_claus_tone4:': { + uc_base: '1f9d1-1f3fe-1f384', + uc_full: '1f9d1-1f3fe-200d-1f384', + shortnames: [':mx_claus_medium_dark_skin_tone:'], + category: 'people', + }, + ':mx_claus_tone5:': { + uc_base: '1f9d1-1f3ff-1f384', + uc_full: '1f9d1-1f3ff-200d-1f384', + shortnames: [':mx_claus_dark_skin_tone:'], + category: 'people', + }, + ':office_worker_tone1:': { + uc_base: '1f9d1-1f3fb-1f4bc', + uc_full: '1f9d1-1f3fb-200d-1f4bc', + shortnames: [':office_worker_light_skin_tone:'], + category: 'people', + }, + ':office_worker_tone2:': { + uc_base: '1f9d1-1f3fc-1f4bc', + uc_full: '1f9d1-1f3fc-200d-1f4bc', + shortnames: [':office_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':office_worker_tone3:': { + uc_base: '1f9d1-1f3fd-1f4bc', + uc_full: '1f9d1-1f3fd-200d-1f4bc', + shortnames: [':office_worker_medium_skin_tone:'], + category: 'people', + }, + ':office_worker_tone4:': { + uc_base: '1f9d1-1f3fe-1f4bc', + uc_full: '1f9d1-1f3fe-200d-1f4bc', + shortnames: [':office_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':office_worker_tone5:': { + uc_base: '1f9d1-1f3ff-1f4bc', + uc_full: '1f9d1-1f3ff-200d-1f4bc', + shortnames: [':office_worker_dark_skin_tone:'], + category: 'people', + }, + ':people_holding_hands:': { uc_base: '1f9d1-1f91d-1f9d1', uc_full: '1f9d1-200d-1f91d-200d-1f9d1', shortnames: [], category: 'people' }, + ':person_feeding_baby_tone1:': { + uc_base: '1f9d1-1f3fb-1f37c', + uc_full: '1f9d1-1f3fb-200d-1f37c', + shortnames: [':person_feeding_baby_light_skin_tone:'], + category: 'people', + }, + ':person_feeding_baby_tone2:': { + uc_base: '1f9d1-1f3fc-1f37c', + uc_full: '1f9d1-1f3fc-200d-1f37c', + shortnames: [':person_feeding_baby_medium_light_skin_tone:'], + category: 'people', + }, + ':person_feeding_baby_tone3:': { + uc_base: '1f9d1-1f3fd-1f37c', + uc_full: '1f9d1-1f3fd-200d-1f37c', + shortnames: [':person_feeding_baby_medium_skin_tone:'], + category: 'people', + }, + ':person_feeding_baby_tone4:': { + uc_base: '1f9d1-1f3fe-1f37c', + uc_full: '1f9d1-1f3fe-200d-1f37c', + shortnames: [':person_feeding_baby_medium_dark_skin_tone:'], + category: 'people', + }, + ':person_feeding_baby_tone5:': { + uc_base: '1f9d1-1f3ff-1f37c', + uc_full: '1f9d1-1f3ff-200d-1f37c', + shortnames: [':person_feeding_baby_dark_skin_tone:'], + category: 'people', + }, + ':person_in_manual_wheelchair_tone1:': { + uc_base: '1f9d1-1f3fb-1f9bd', + uc_full: '1f9d1-1f3fb-200d-1f9bd', + shortnames: [':person_in_manual_wheelchair_light_skin_tone:'], + category: 'people', + }, + ':person_in_manual_wheelchair_tone2:': { + uc_base: '1f9d1-1f3fc-1f9bd', + uc_full: '1f9d1-1f3fc-200d-1f9bd', + shortnames: [':person_in_manual_wheelchair_medium_light_skin_tone:'], + category: 'people', + }, + ':person_in_manual_wheelchair_tone3:': { + uc_base: '1f9d1-1f3fd-1f9bd', + uc_full: '1f9d1-1f3fd-200d-1f9bd', + shortnames: [':person_in_manual_wheelchair_medium_skin_tone:'], + category: 'people', + }, + ':person_in_manual_wheelchair_tone4:': { + uc_base: '1f9d1-1f3fe-1f9bd', + uc_full: '1f9d1-1f3fe-200d-1f9bd', + shortnames: [':person_in_manual_wheelchair_medium_dark_skin_tone:'], + category: 'people', + }, + ':person_in_manual_wheelchair_tone5:': { + uc_base: '1f9d1-1f3ff-1f9bd', + uc_full: '1f9d1-1f3ff-200d-1f9bd', + shortnames: [':person_in_manual_wheelchair_dark_skin_tone:'], + category: 'people', + }, + ':person_in_motorized_wheelchair_tone1:': { + uc_base: '1f9d1-1f3fb-1f9bc', + uc_full: '1f9d1-1f3fb-200d-1f9bc', + shortnames: [':person_in_motorized_wheelchair_light_skin_tone:'], + category: 'people', + }, + ':person_in_motorized_wheelchair_tone2:': { + uc_base: '1f9d1-1f3fc-1f9bc', + uc_full: '1f9d1-1f3fc-200d-1f9bc', + shortnames: [':person_in_motorized_wheelchair_medium_light_skin_tone:'], + category: 'people', + }, + ':person_in_motorized_wheelchair_tone3:': { + uc_base: '1f9d1-1f3fd-1f9bc', + uc_full: '1f9d1-1f3fd-200d-1f9bc', + shortnames: [':person_in_motorized_wheelchair_medium_skin_tone:'], + category: 'people', + }, + ':person_in_motorized_wheelchair_tone4:': { + uc_base: '1f9d1-1f3fe-1f9bc', + uc_full: '1f9d1-1f3fe-200d-1f9bc', + shortnames: [':person_in_motorized_wheelchair_medium_dark_skin_tone:'], + category: 'people', + }, + ':person_in_motorized_wheelchair_tone5:': { + uc_base: '1f9d1-1f3ff-1f9bc', + uc_full: '1f9d1-1f3ff-200d-1f9bc', + shortnames: [':person_in_motorized_wheelchair_dark_skin_tone:'], + category: 'people', + }, + ':person_tone1_bald:': { + uc_base: '1f9d1-1f3fb-1f9b2', + uc_full: '1f9d1-1f3fb-200d-1f9b2', + shortnames: [':person_light_skin_tone_bald:'], + category: 'people', + }, + ':person_tone1_curly_hair:': { + uc_base: '1f9d1-1f3fb-1f9b1', + uc_full: '1f9d1-1f3fb-200d-1f9b1', + shortnames: [':person_light_skin_tone_curly_hair:'], + category: 'people', + }, + ':person_tone1_red_hair:': { + uc_base: '1f9d1-1f3fb-1f9b0', + uc_full: '1f9d1-1f3fb-200d-1f9b0', + shortnames: [':person_light_skin_tone_red_hair:'], + category: 'people', + }, + ':person_tone1_white_hair:': { + uc_base: '1f9d1-1f3fb-1f9b3', + uc_full: '1f9d1-1f3fb-200d-1f9b3', + shortnames: [':person_light_skin_tone_white_hair:'], + category: 'people', + }, + ':person_tone2_bald:': { + uc_base: '1f9d1-1f3fc-1f9b2', + uc_full: '1f9d1-1f3fc-200d-1f9b2', + shortnames: [':person_medium_light_skin_tone_bald:'], + category: 'people', + }, + ':person_tone2_curly_hair:': { + uc_base: '1f9d1-1f3fc-1f9b1', + uc_full: '1f9d1-1f3fc-200d-1f9b1', + shortnames: [':person_medium_light_skin_tone_curly_hair:'], + category: 'people', + }, + ':person_tone2_red_hair:': { + uc_base: '1f9d1-1f3fc-1f9b0', + uc_full: '1f9d1-1f3fc-200d-1f9b0', + shortnames: [':person_medium_light_skin_tone_red_hair:'], + category: 'people', + }, + ':person_tone2_white_hair:': { + uc_base: '1f9d1-1f3fc-1f9b3', + uc_full: '1f9d1-1f3fc-200d-1f9b3', + shortnames: [':person_medium_light_skin_tone_white_hair:'], + category: 'people', + }, + ':person_tone3_bald:': { + uc_base: '1f9d1-1f3fd-1f9b2', + uc_full: '1f9d1-1f3fd-200d-1f9b2', + shortnames: [':person_medium_skin_tone_bald:'], + category: 'people', + }, + ':person_tone3_curly_hair:': { + uc_base: '1f9d1-1f3fd-1f9b1', + uc_full: '1f9d1-1f3fd-200d-1f9b1', + shortnames: [':person_medium_skin_tone_curly_hair:'], + category: 'people', + }, + ':person_tone3_red_hair:': { + uc_base: '1f9d1-1f3fd-1f9b0', + uc_full: '1f9d1-1f3fd-200d-1f9b0', + shortnames: [':person_medium_skin_tone_red_hair:'], + category: 'people', + }, + ':person_tone3_white_hair:': { + uc_base: '1f9d1-1f3fd-1f9b3', + uc_full: '1f9d1-1f3fd-200d-1f9b3', + shortnames: [':person_medium_skin_tone_white_hair:'], + category: 'people', + }, + ':person_tone4_bald:': { + uc_base: '1f9d1-1f3fe-1f9b2', + uc_full: '1f9d1-1f3fe-200d-1f9b2', + shortnames: [':person_medium_dark_skin_tone_bald:'], + category: 'people', + }, + ':person_tone4_curly_hair:': { + uc_base: '1f9d1-1f3fe-1f9b1', + uc_full: '1f9d1-1f3fe-200d-1f9b1', + shortnames: [':person_medium_dark_skin_tone_curly_hair:'], + category: 'people', + }, + ':person_tone4_red_hair:': { + uc_base: '1f9d1-1f3fe-1f9b0', + uc_full: '1f9d1-1f3fe-200d-1f9b0', + shortnames: [':person_medium_dark_skin_tone_red_hair:'], + category: 'people', + }, + ':person_tone4_white_hair:': { + uc_base: '1f9d1-1f3fe-1f9b3', + uc_full: '1f9d1-1f3fe-200d-1f9b3', + shortnames: [':person_medium_dark_skin_tone_white_hair:'], + category: 'people', + }, + ':person_tone5_bald:': { + uc_base: '1f9d1-1f3ff-1f9b2', + uc_full: '1f9d1-1f3ff-200d-1f9b2', + shortnames: [':person_dark_skin_tone_bald:'], + category: 'people', + }, + ':person_tone5_curly_hair:': { + uc_base: '1f9d1-1f3ff-1f9b1', + uc_full: '1f9d1-1f3ff-200d-1f9b1', + shortnames: [':person_dark_skin_tone_curly_hair:'], + category: 'people', + }, + ':person_tone5_red_hair:': { + uc_base: '1f9d1-1f3ff-1f9b0', + uc_full: '1f9d1-1f3ff-200d-1f9b0', + shortnames: [':person_dark_skin_tone_red_hair:'], + category: 'people', + }, + ':person_tone5_white_hair:': { + uc_base: '1f9d1-1f3ff-1f9b3', + uc_full: '1f9d1-1f3ff-200d-1f9b3', + shortnames: [':person_dark_skin_tone_white_hair:'], + category: 'people', + }, + ':person_with_probing_cane_tone1:': { + uc_base: '1f9d1-1f3fb-1f9af', + uc_full: '1f9d1-1f3fb-200d-1f9af', + shortnames: [':person_with_probing_cane_light_skin_tone:'], + category: 'people', + }, + ':person_with_probing_cane_tone2:': { + uc_base: '1f9d1-1f3fc-1f9af', + uc_full: '1f9d1-1f3fc-200d-1f9af', + shortnames: [':person_with_probing_cane_medium_light_skin_tone:'], + category: 'people', + }, + ':person_with_probing_cane_tone3:': { + uc_base: '1f9d1-1f3fd-1f9af', + uc_full: '1f9d1-1f3fd-200d-1f9af', + shortnames: [':person_with_probing_cane_medium_skin_tone:'], + category: 'people', + }, + ':person_with_probing_cane_tone4:': { + uc_base: '1f9d1-1f3fe-1f9af', + uc_full: '1f9d1-1f3fe-200d-1f9af', + shortnames: [':person_with_probing_cane_medium_dark_skin_tone:'], + category: 'people', + }, + ':person_with_probing_cane_tone5:': { + uc_base: '1f9d1-1f3ff-1f9af', + uc_full: '1f9d1-1f3ff-200d-1f9af', + shortnames: [':person_with_probing_cane_dark_skin_tone:'], + category: 'people', + }, + ':scientist_tone1:': { + uc_base: '1f9d1-1f3fb-1f52c', + uc_full: '1f9d1-1f3fb-200d-1f52c', + shortnames: [':scientist_light_skin_tone:'], + category: 'people', + }, + ':scientist_tone2:': { + uc_base: '1f9d1-1f3fc-1f52c', + uc_full: '1f9d1-1f3fc-200d-1f52c', + shortnames: [':scientist_medium_light_skin_tone:'], + category: 'people', + }, + ':scientist_tone3:': { + uc_base: '1f9d1-1f3fd-1f52c', + uc_full: '1f9d1-1f3fd-200d-1f52c', + shortnames: [':scientist_medium_skin_tone:'], + category: 'people', + }, + ':scientist_tone4:': { + uc_base: '1f9d1-1f3fe-1f52c', + uc_full: '1f9d1-1f3fe-200d-1f52c', + shortnames: [':scientist_medium_dark_skin_tone:'], + category: 'people', + }, + ':scientist_tone5:': { + uc_base: '1f9d1-1f3ff-1f52c', + uc_full: '1f9d1-1f3ff-200d-1f52c', + shortnames: [':scientist_dark_skin_tone:'], + category: 'people', + }, + ':singer_tone1:': { + uc_base: '1f9d1-1f3fb-1f3a4', + uc_full: '1f9d1-1f3fb-200d-1f3a4', + shortnames: [':singer_light_skin_tone:'], + category: 'people', + }, + ':singer_tone2:': { + uc_base: '1f9d1-1f3fc-1f3a4', + uc_full: '1f9d1-1f3fc-200d-1f3a4', + shortnames: [':singer_medium_light_skin_tone:'], + category: 'people', + }, + ':singer_tone3:': { + uc_base: '1f9d1-1f3fd-1f3a4', + uc_full: '1f9d1-1f3fd-200d-1f3a4', + shortnames: [':singer_medium_skin_tone:'], + category: 'people', + }, + ':singer_tone4:': { + uc_base: '1f9d1-1f3fe-1f3a4', + uc_full: '1f9d1-1f3fe-200d-1f3a4', + shortnames: [':singer_medium_dark_skin_tone:'], + category: 'people', + }, + ':singer_tone5:': { + uc_base: '1f9d1-1f3ff-1f3a4', + uc_full: '1f9d1-1f3ff-200d-1f3a4', + shortnames: [':singer_dark_skin_tone:'], + category: 'people', + }, + ':student_tone1:': { + uc_base: '1f9d1-1f3fb-1f393', + uc_full: '1f9d1-1f3fb-200d-1f393', + shortnames: [':student_light_skin_tone:'], + category: 'people', + }, + ':student_tone2:': { + uc_base: '1f9d1-1f3fc-1f393', + uc_full: '1f9d1-1f3fc-200d-1f393', + shortnames: [':student_medium_light_skin_tone:'], + category: 'people', + }, + ':student_tone3:': { + uc_base: '1f9d1-1f3fd-1f393', + uc_full: '1f9d1-1f3fd-200d-1f393', + shortnames: [':student_medium_skin_tone:'], + category: 'people', + }, + ':student_tone4:': { + uc_base: '1f9d1-1f3fe-1f393', + uc_full: '1f9d1-1f3fe-200d-1f393', + shortnames: [':student_medium_dark_skin_tone:'], + category: 'people', + }, + ':student_tone5:': { + uc_base: '1f9d1-1f3ff-1f393', + uc_full: '1f9d1-1f3ff-200d-1f393', + shortnames: [':student_dark_skin_tone:'], + category: 'people', + }, + ':teacher_tone1:': { + uc_base: '1f9d1-1f3fb-1f3eb', + uc_full: '1f9d1-1f3fb-200d-1f3eb', + shortnames: [':teacher_light_skin_tone:'], + category: 'people', + }, + ':teacher_tone2:': { + uc_base: '1f9d1-1f3fc-1f3eb', + uc_full: '1f9d1-1f3fc-200d-1f3eb', + shortnames: [':teacher_medium_light_skin_tone:'], + category: 'people', + }, + ':teacher_tone3:': { + uc_base: '1f9d1-1f3fd-1f3eb', + uc_full: '1f9d1-1f3fd-200d-1f3eb', + shortnames: [':teacher_medium_skin_tone:'], + category: 'people', + }, + ':teacher_tone4:': { + uc_base: '1f9d1-1f3fe-1f3eb', + uc_full: '1f9d1-1f3fe-200d-1f3eb', + shortnames: [':teacher_medium_dark_skin_tone:'], + category: 'people', + }, + ':teacher_tone5:': { + uc_base: '1f9d1-1f3ff-1f3eb', + uc_full: '1f9d1-1f3ff-200d-1f3eb', + shortnames: [':teacher_dark_skin_tone:'], + category: 'people', + }, + ':technologist_tone1:': { + uc_base: '1f9d1-1f3fb-1f4bb', + uc_full: '1f9d1-1f3fb-200d-1f4bb', + shortnames: [':technologist_light_skin_tone:'], + category: 'people', + }, + ':technologist_tone2:': { + uc_base: '1f9d1-1f3fc-1f4bb', + uc_full: '1f9d1-1f3fc-200d-1f4bb', + shortnames: [':technologist_medium_light_skin_tone:'], + category: 'people', + }, + ':technologist_tone3:': { + uc_base: '1f9d1-1f3fd-1f4bb', + uc_full: '1f9d1-1f3fd-200d-1f4bb', + shortnames: [':technologist_medium_skin_tone:'], + category: 'people', + }, + ':technologist_tone4:': { + uc_base: '1f9d1-1f3fe-1f4bb', + uc_full: '1f9d1-1f3fe-200d-1f4bb', + shortnames: [':technologist_medium_dark_skin_tone:'], + category: 'people', + }, + ':technologist_tone5:': { + uc_base: '1f9d1-1f3ff-1f4bb', + uc_full: '1f9d1-1f3ff-200d-1f4bb', + shortnames: [':technologist_dark_skin_tone:'], + category: 'people', + }, + ':woman_artist_tone1:': { + uc_base: '1f469-1f3fb-1f3a8', + uc_full: '1f469-1f3fb-200d-1f3a8', + shortnames: [':woman_artist_light_skin_tone:'], + category: 'people', + }, + ':woman_artist_tone2:': { + uc_base: '1f469-1f3fc-1f3a8', + uc_full: '1f469-1f3fc-200d-1f3a8', + shortnames: [':woman_artist_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_artist_tone3:': { + uc_base: '1f469-1f3fd-1f3a8', + uc_full: '1f469-1f3fd-200d-1f3a8', + shortnames: [':woman_artist_medium_skin_tone:'], + category: 'people', + }, + ':woman_artist_tone4:': { + uc_base: '1f469-1f3fe-1f3a8', + uc_full: '1f469-1f3fe-200d-1f3a8', + shortnames: [':woman_artist_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_artist_tone5:': { + uc_base: '1f469-1f3ff-1f3a8', + uc_full: '1f469-1f3ff-200d-1f3a8', + shortnames: [':woman_artist_dark_skin_tone:'], + category: 'people', + }, + ':woman_astronaut_tone1:': { + uc_base: '1f469-1f3fb-1f680', + uc_full: '1f469-1f3fb-200d-1f680', + shortnames: [':woman_astronaut_light_skin_tone:'], + category: 'people', + }, + ':woman_astronaut_tone2:': { + uc_base: '1f469-1f3fc-1f680', + uc_full: '1f469-1f3fc-200d-1f680', + shortnames: [':woman_astronaut_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_astronaut_tone3:': { + uc_base: '1f469-1f3fd-1f680', + uc_full: '1f469-1f3fd-200d-1f680', + shortnames: [':woman_astronaut_medium_skin_tone:'], + category: 'people', + }, + ':woman_astronaut_tone4:': { + uc_base: '1f469-1f3fe-1f680', + uc_full: '1f469-1f3fe-200d-1f680', + shortnames: [':woman_astronaut_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_astronaut_tone5:': { + uc_base: '1f469-1f3ff-1f680', + uc_full: '1f469-1f3ff-200d-1f680', + shortnames: [':woman_astronaut_dark_skin_tone:'], + category: 'people', + }, + ':woman_bald_tone1:': { + uc_base: '1f469-1f3fb-1f9b2', + uc_full: '1f469-1f3fb-200d-1f9b2', + shortnames: [':woman_bald_light_skin_tone:'], + category: 'people', + }, + ':woman_bald_tone2:': { + uc_base: '1f469-1f3fc-1f9b2', + uc_full: '1f469-1f3fc-200d-1f9b2', + shortnames: [':woman_bald_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_bald_tone3:': { + uc_base: '1f469-1f3fd-1f9b2', + uc_full: '1f469-1f3fd-200d-1f9b2', + shortnames: [':woman_bald_medium_skin_tone:'], + category: 'people', + }, + ':woman_bald_tone4:': { + uc_base: '1f469-1f3fe-1f9b2', + uc_full: '1f469-1f3fe-200d-1f9b2', + shortnames: [':woman_bald_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_bald_tone5:': { + uc_base: '1f469-1f3ff-1f9b2', + uc_full: '1f469-1f3ff-200d-1f9b2', + shortnames: [':woman_bald_dark_skin_tone:'], + category: 'people', + }, + ':woman_cook_tone1:': { + uc_base: '1f469-1f3fb-1f373', + uc_full: '1f469-1f3fb-200d-1f373', + shortnames: [':woman_cook_light_skin_tone:'], + category: 'people', + }, + ':woman_cook_tone2:': { + uc_base: '1f469-1f3fc-1f373', + uc_full: '1f469-1f3fc-200d-1f373', + shortnames: [':woman_cook_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_cook_tone3:': { + uc_base: '1f469-1f3fd-1f373', + uc_full: '1f469-1f3fd-200d-1f373', + shortnames: [':woman_cook_medium_skin_tone:'], + category: 'people', + }, + ':woman_cook_tone4:': { + uc_base: '1f469-1f3fe-1f373', + uc_full: '1f469-1f3fe-200d-1f373', + shortnames: [':woman_cook_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_cook_tone5:': { + uc_base: '1f469-1f3ff-1f373', + uc_full: '1f469-1f3ff-200d-1f373', + shortnames: [':woman_cook_dark_skin_tone:'], + category: 'people', + }, + ':woman_curly_haired_tone1:': { + uc_base: '1f469-1f3fb-1f9b1', + uc_full: '1f469-1f3fb-200d-1f9b1', + shortnames: [':woman_curly_haired_light_skin_tone:'], + category: 'people', + }, + ':woman_curly_haired_tone2:': { + uc_base: '1f469-1f3fc-1f9b1', + uc_full: '1f469-1f3fc-200d-1f9b1', + shortnames: [':woman_curly_haired_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_curly_haired_tone3:': { + uc_base: '1f469-1f3fd-1f9b1', + uc_full: '1f469-1f3fd-200d-1f9b1', + shortnames: [':woman_curly_haired_medium_skin_tone:'], + category: 'people', + }, + ':woman_curly_haired_tone4:': { + uc_base: '1f469-1f3fe-1f9b1', + uc_full: '1f469-1f3fe-200d-1f9b1', + shortnames: [':woman_curly_haired_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_curly_haired_tone5:': { + uc_base: '1f469-1f3ff-1f9b1', + uc_full: '1f469-1f3ff-200d-1f9b1', + shortnames: [':woman_curly_haired_dark_skin_tone:'], + category: 'people', + }, + ':woman_factory_worker_tone1:': { + uc_base: '1f469-1f3fb-1f3ed', + uc_full: '1f469-1f3fb-200d-1f3ed', + shortnames: [':woman_factory_worker_light_skin_tone:'], + category: 'people', + }, + ':woman_factory_worker_tone2:': { + uc_base: '1f469-1f3fc-1f3ed', + uc_full: '1f469-1f3fc-200d-1f3ed', + shortnames: [':woman_factory_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_factory_worker_tone3:': { + uc_base: '1f469-1f3fd-1f3ed', + uc_full: '1f469-1f3fd-200d-1f3ed', + shortnames: [':woman_factory_worker_medium_skin_tone:'], + category: 'people', + }, + ':woman_factory_worker_tone4:': { + uc_base: '1f469-1f3fe-1f3ed', + uc_full: '1f469-1f3fe-200d-1f3ed', + shortnames: [':woman_factory_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_factory_worker_tone5:': { + uc_base: '1f469-1f3ff-1f3ed', + uc_full: '1f469-1f3ff-200d-1f3ed', + shortnames: [':woman_factory_worker_dark_skin_tone:'], + category: 'people', + }, + ':woman_farmer_tone1:': { + uc_base: '1f469-1f3fb-1f33e', + uc_full: '1f469-1f3fb-200d-1f33e', + shortnames: [':woman_farmer_light_skin_tone:'], + category: 'people', + }, + ':woman_farmer_tone2:': { + uc_base: '1f469-1f3fc-1f33e', + uc_full: '1f469-1f3fc-200d-1f33e', + shortnames: [':woman_farmer_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_farmer_tone3:': { + uc_base: '1f469-1f3fd-1f33e', + uc_full: '1f469-1f3fd-200d-1f33e', + shortnames: [':woman_farmer_medium_skin_tone:'], + category: 'people', + }, + ':woman_farmer_tone4:': { + uc_base: '1f469-1f3fe-1f33e', + uc_full: '1f469-1f3fe-200d-1f33e', + shortnames: [':woman_farmer_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_farmer_tone5:': { + uc_base: '1f469-1f3ff-1f33e', + uc_full: '1f469-1f3ff-200d-1f33e', + shortnames: [':woman_farmer_dark_skin_tone:'], + category: 'people', + }, + ':woman_feeding_baby_tone1:': { + uc_base: '1f469-1f3fb-1f37c', + uc_full: '1f469-1f3fb-200d-1f37c', + shortnames: [':woman_feeding_baby_light_skin_tone:'], + category: 'people', + }, + ':woman_feeding_baby_tone2:': { + uc_base: '1f469-1f3fc-1f37c', + uc_full: '1f469-1f3fc-200d-1f37c', + shortnames: [':woman_feeding_baby_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_feeding_baby_tone3:': { + uc_base: '1f469-1f3fd-1f37c', + uc_full: '1f469-1f3fd-200d-1f37c', + shortnames: [':woman_feeding_baby_medium_skin_tone:'], + category: 'people', + }, + ':woman_feeding_baby_tone4:': { + uc_base: '1f469-1f3fe-1f37c', + uc_full: '1f469-1f3fe-200d-1f37c', + shortnames: [':woman_feeding_baby_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_feeding_baby_tone5:': { + uc_base: '1f469-1f3ff-1f37c', + uc_full: '1f469-1f3ff-200d-1f37c', + shortnames: [':woman_feeding_baby_dark_skin_tone:'], + category: 'people', + }, + ':woman_firefighter_tone1:': { + uc_base: '1f469-1f3fb-1f692', + uc_full: '1f469-1f3fb-200d-1f692', + shortnames: [':woman_firefighter_light_skin_tone:'], + category: 'people', + }, + ':woman_firefighter_tone2:': { + uc_base: '1f469-1f3fc-1f692', + uc_full: '1f469-1f3fc-200d-1f692', + shortnames: [':woman_firefighter_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_firefighter_tone3:': { + uc_base: '1f469-1f3fd-1f692', + uc_full: '1f469-1f3fd-200d-1f692', + shortnames: [':woman_firefighter_medium_skin_tone:'], + category: 'people', + }, + ':woman_firefighter_tone4:': { + uc_base: '1f469-1f3fe-1f692', + uc_full: '1f469-1f3fe-200d-1f692', + shortnames: [':woman_firefighter_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_firefighter_tone5:': { + uc_base: '1f469-1f3ff-1f692', + uc_full: '1f469-1f3ff-200d-1f692', + shortnames: [':woman_firefighter_dark_skin_tone:'], + category: 'people', + }, + ':woman_in_manual_wheelchair_tone1:': { + uc_base: '1f469-1f3fb-1f9bd', + uc_full: '1f469-1f3fb-200d-1f9bd', + shortnames: [':woman_in_manual_wheelchair_light_skin_tone:'], + category: 'people', + }, + ':woman_in_manual_wheelchair_tone2:': { + uc_base: '1f469-1f3fc-1f9bd', + uc_full: '1f469-1f3fc-200d-1f9bd', + shortnames: [':woman_in_manual_wheelchair_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_in_manual_wheelchair_tone3:': { + uc_base: '1f469-1f3fd-1f9bd', + uc_full: '1f469-1f3fd-200d-1f9bd', + shortnames: [':woman_in_manual_wheelchair_medium_skin_tone:'], + category: 'people', + }, + ':woman_in_manual_wheelchair_tone4:': { + uc_base: '1f469-1f3fe-1f9bd', + uc_full: '1f469-1f3fe-200d-1f9bd', + shortnames: [':woman_in_manual_wheelchair_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_in_manual_wheelchair_tone5:': { + uc_base: '1f469-1f3ff-1f9bd', + uc_full: '1f469-1f3ff-200d-1f9bd', + shortnames: [':woman_in_manual_wheelchair_dark_skin_tone:'], + category: 'people', + }, + ':woman_in_motorized_wheelchair_tone1:': { + uc_base: '1f469-1f3fb-1f9bc', + uc_full: '1f469-1f3fb-200d-1f9bc', + shortnames: [':woman_in_motorized_wheelchair_light_skin_tone:'], + category: 'people', + }, + ':woman_in_motorized_wheelchair_tone2:': { + uc_base: '1f469-1f3fc-1f9bc', + uc_full: '1f469-1f3fc-200d-1f9bc', + shortnames: [':woman_in_motorized_wheelchair_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_in_motorized_wheelchair_tone3:': { + uc_base: '1f469-1f3fd-1f9bc', + uc_full: '1f469-1f3fd-200d-1f9bc', + shortnames: [':woman_in_motorized_wheelchair_medium_skin_tone:'], + category: 'people', + }, + ':woman_in_motorized_wheelchair_tone4:': { + uc_base: '1f469-1f3fe-1f9bc', + uc_full: '1f469-1f3fe-200d-1f9bc', + shortnames: [':woman_in_motorized_wheelchair_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_in_motorized_wheelchair_tone5:': { + uc_base: '1f469-1f3ff-1f9bc', + uc_full: '1f469-1f3ff-200d-1f9bc', + shortnames: [':woman_in_motorized_wheelchair_dark_skin_tone:'], + category: 'people', + }, + ':woman_mechanic_tone1:': { + uc_base: '1f469-1f3fb-1f527', + uc_full: '1f469-1f3fb-200d-1f527', + shortnames: [':woman_mechanic_light_skin_tone:'], + category: 'people', + }, + ':woman_mechanic_tone2:': { + uc_base: '1f469-1f3fc-1f527', + uc_full: '1f469-1f3fc-200d-1f527', + shortnames: [':woman_mechanic_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_mechanic_tone3:': { + uc_base: '1f469-1f3fd-1f527', + uc_full: '1f469-1f3fd-200d-1f527', + shortnames: [':woman_mechanic_medium_skin_tone:'], + category: 'people', + }, + ':woman_mechanic_tone4:': { + uc_base: '1f469-1f3fe-1f527', + uc_full: '1f469-1f3fe-200d-1f527', + shortnames: [':woman_mechanic_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_mechanic_tone5:': { + uc_base: '1f469-1f3ff-1f527', + uc_full: '1f469-1f3ff-200d-1f527', + shortnames: [':woman_mechanic_dark_skin_tone:'], + category: 'people', + }, + ':woman_office_worker_tone1:': { + uc_base: '1f469-1f3fb-1f4bc', + uc_full: '1f469-1f3fb-200d-1f4bc', + shortnames: [':woman_office_worker_light_skin_tone:'], + category: 'people', + }, + ':woman_office_worker_tone2:': { + uc_base: '1f469-1f3fc-1f4bc', + uc_full: '1f469-1f3fc-200d-1f4bc', + shortnames: [':woman_office_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_office_worker_tone3:': { + uc_base: '1f469-1f3fd-1f4bc', + uc_full: '1f469-1f3fd-200d-1f4bc', + shortnames: [':woman_office_worker_medium_skin_tone:'], + category: 'people', + }, + ':woman_office_worker_tone4:': { + uc_base: '1f469-1f3fe-1f4bc', + uc_full: '1f469-1f3fe-200d-1f4bc', + shortnames: [':woman_office_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_office_worker_tone5:': { + uc_base: '1f469-1f3ff-1f4bc', + uc_full: '1f469-1f3ff-200d-1f4bc', + shortnames: [':woman_office_worker_dark_skin_tone:'], + category: 'people', + }, + ':woman_red_haired_tone1:': { + uc_base: '1f469-1f3fb-1f9b0', + uc_full: '1f469-1f3fb-200d-1f9b0', + shortnames: [':woman_red_haired_light_skin_tone:'], + category: 'people', + }, + ':woman_red_haired_tone2:': { + uc_base: '1f469-1f3fc-1f9b0', + uc_full: '1f469-1f3fc-200d-1f9b0', + shortnames: [':woman_red_haired_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_red_haired_tone3:': { + uc_base: '1f469-1f3fd-1f9b0', + uc_full: '1f469-1f3fd-200d-1f9b0', + shortnames: [':woman_red_haired_medium_skin_tone:'], + category: 'people', + }, + ':woman_red_haired_tone4:': { + uc_base: '1f469-1f3fe-1f9b0', + uc_full: '1f469-1f3fe-200d-1f9b0', + shortnames: [':woman_red_haired_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_red_haired_tone5:': { + uc_base: '1f469-1f3ff-1f9b0', + uc_full: '1f469-1f3ff-200d-1f9b0', + shortnames: [':woman_red_haired_dark_skin_tone:'], + category: 'people', + }, + ':woman_scientist_tone1:': { + uc_base: '1f469-1f3fb-1f52c', + uc_full: '1f469-1f3fb-200d-1f52c', + shortnames: [':woman_scientist_light_skin_tone:'], + category: 'people', + }, + ':woman_scientist_tone2:': { + uc_base: '1f469-1f3fc-1f52c', + uc_full: '1f469-1f3fc-200d-1f52c', + shortnames: [':woman_scientist_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_scientist_tone3:': { + uc_base: '1f469-1f3fd-1f52c', + uc_full: '1f469-1f3fd-200d-1f52c', + shortnames: [':woman_scientist_medium_skin_tone:'], + category: 'people', + }, + ':woman_scientist_tone4:': { + uc_base: '1f469-1f3fe-1f52c', + uc_full: '1f469-1f3fe-200d-1f52c', + shortnames: [':woman_scientist_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_scientist_tone5:': { + uc_base: '1f469-1f3ff-1f52c', + uc_full: '1f469-1f3ff-200d-1f52c', + shortnames: [':woman_scientist_dark_skin_tone:'], + category: 'people', + }, + ':woman_singer_tone1:': { + uc_base: '1f469-1f3fb-1f3a4', + uc_full: '1f469-1f3fb-200d-1f3a4', + shortnames: [':woman_singer_light_skin_tone:'], + category: 'people', + }, + ':woman_singer_tone2:': { + uc_base: '1f469-1f3fc-1f3a4', + uc_full: '1f469-1f3fc-200d-1f3a4', + shortnames: [':woman_singer_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_singer_tone3:': { + uc_base: '1f469-1f3fd-1f3a4', + uc_full: '1f469-1f3fd-200d-1f3a4', + shortnames: [':woman_singer_medium_skin_tone:'], + category: 'people', + }, + ':woman_singer_tone4:': { + uc_base: '1f469-1f3fe-1f3a4', + uc_full: '1f469-1f3fe-200d-1f3a4', + shortnames: [':woman_singer_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_singer_tone5:': { + uc_base: '1f469-1f3ff-1f3a4', + uc_full: '1f469-1f3ff-200d-1f3a4', + shortnames: [':woman_singer_dark_skin_tone:'], + category: 'people', + }, + ':woman_student_tone1:': { + uc_base: '1f469-1f3fb-1f393', + uc_full: '1f469-1f3fb-200d-1f393', + shortnames: [':woman_student_light_skin_tone:'], + category: 'people', + }, + ':woman_student_tone2:': { + uc_base: '1f469-1f3fc-1f393', + uc_full: '1f469-1f3fc-200d-1f393', + shortnames: [':woman_student_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_student_tone3:': { + uc_base: '1f469-1f3fd-1f393', + uc_full: '1f469-1f3fd-200d-1f393', + shortnames: [':woman_student_medium_skin_tone:'], + category: 'people', + }, + ':woman_student_tone4:': { + uc_base: '1f469-1f3fe-1f393', + uc_full: '1f469-1f3fe-200d-1f393', + shortnames: [':woman_student_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_student_tone5:': { + uc_base: '1f469-1f3ff-1f393', + uc_full: '1f469-1f3ff-200d-1f393', + shortnames: [':woman_student_dark_skin_tone:'], + category: 'people', + }, + ':woman_teacher_tone1:': { + uc_base: '1f469-1f3fb-1f3eb', + uc_full: '1f469-1f3fb-200d-1f3eb', + shortnames: [':woman_teacher_light_skin_tone:'], + category: 'people', + }, + ':woman_teacher_tone2:': { + uc_base: '1f469-1f3fc-1f3eb', + uc_full: '1f469-1f3fc-200d-1f3eb', + shortnames: [':woman_teacher_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_teacher_tone3:': { + uc_base: '1f469-1f3fd-1f3eb', + uc_full: '1f469-1f3fd-200d-1f3eb', + shortnames: [':woman_teacher_medium_skin_tone:'], + category: 'people', + }, + ':woman_teacher_tone4:': { + uc_base: '1f469-1f3fe-1f3eb', + uc_full: '1f469-1f3fe-200d-1f3eb', + shortnames: [':woman_teacher_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_teacher_tone5:': { + uc_base: '1f469-1f3ff-1f3eb', + uc_full: '1f469-1f3ff-200d-1f3eb', + shortnames: [':woman_teacher_dark_skin_tone:'], + category: 'people', + }, + ':woman_technologist_tone1:': { + uc_base: '1f469-1f3fb-1f4bb', + uc_full: '1f469-1f3fb-200d-1f4bb', + shortnames: [':woman_technologist_light_skin_tone:'], + category: 'people', + }, + ':woman_technologist_tone2:': { + uc_base: '1f469-1f3fc-1f4bb', + uc_full: '1f469-1f3fc-200d-1f4bb', + shortnames: [':woman_technologist_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_technologist_tone3:': { + uc_base: '1f469-1f3fd-1f4bb', + uc_full: '1f469-1f3fd-200d-1f4bb', + shortnames: [':woman_technologist_medium_skin_tone:'], + category: 'people', + }, + ':woman_technologist_tone4:': { + uc_base: '1f469-1f3fe-1f4bb', + uc_full: '1f469-1f3fe-200d-1f4bb', + shortnames: [':woman_technologist_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_technologist_tone5:': { + uc_base: '1f469-1f3ff-1f4bb', + uc_full: '1f469-1f3ff-200d-1f4bb', + shortnames: [':woman_technologist_dark_skin_tone:'], + category: 'people', + }, + ':woman_white_haired_tone1:': { + uc_base: '1f469-1f3fb-1f9b3', + uc_full: '1f469-1f3fb-200d-1f9b3', + shortnames: [':woman_white_haired_light_skin_tone:'], + category: 'people', + }, + ':woman_white_haired_tone2:': { + uc_base: '1f469-1f3fc-1f9b3', + uc_full: '1f469-1f3fc-200d-1f9b3', + shortnames: [':woman_white_haired_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_white_haired_tone3:': { + uc_base: '1f469-1f3fd-1f9b3', + uc_full: '1f469-1f3fd-200d-1f9b3', + shortnames: [':woman_white_haired_medium_skin_tone:'], + category: 'people', + }, + ':woman_white_haired_tone4:': { + uc_base: '1f469-1f3fe-1f9b3', + uc_full: '1f469-1f3fe-200d-1f9b3', + shortnames: [':woman_white_haired_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_white_haired_tone5:': { + uc_base: '1f469-1f3ff-1f9b3', + uc_full: '1f469-1f3ff-200d-1f9b3', + shortnames: [':woman_white_haired_dark_skin_tone:'], + category: 'people', + }, + ':woman_with_probing_cane_tone1:': { + uc_base: '1f469-1f3fb-1f9af', + uc_full: '1f469-1f3fb-200d-1f9af', + shortnames: [':woman_with_probing_cane_light_skin_tone:'], + category: 'people', + }, + ':woman_with_probing_cane_tone2:': { + uc_base: '1f469-1f3fc-1f9af', + uc_full: '1f469-1f3fc-200d-1f9af', + shortnames: [':woman_with_probing_cane_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_with_probing_cane_tone3:': { + uc_base: '1f469-1f3fd-1f9af', + uc_full: '1f469-1f3fd-200d-1f9af', + shortnames: [':woman_with_probing_cane_medium_skin_tone:'], + category: 'people', + }, + ':woman_with_probing_cane_tone4:': { + uc_base: '1f469-1f3fe-1f9af', + uc_full: '1f469-1f3fe-200d-1f9af', + shortnames: [':woman_with_probing_cane_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_with_probing_cane_tone5:': { + uc_base: '1f469-1f3ff-1f9af', + uc_full: '1f469-1f3ff-200d-1f9af', + shortnames: [':woman_with_probing_cane_dark_skin_tone:'], + category: 'people', + }, + ':blond-haired_man_tone1:': { + uc_base: '1f471-1f3fb-2642', + uc_full: '1f471-1f3fb-200d-2642-fe0f', + shortnames: [':blond-haired_man_light_skin_tone:'], + category: 'people', + }, + ':blond-haired_man_tone2:': { + uc_base: '1f471-1f3fc-2642', + uc_full: '1f471-1f3fc-200d-2642-fe0f', + shortnames: [':blond-haired_man_medium_light_skin_tone:'], + category: 'people', + }, + ':blond-haired_man_tone3:': { + uc_base: '1f471-1f3fd-2642', + uc_full: '1f471-1f3fd-200d-2642-fe0f', + shortnames: [':blond-haired_man_medium_skin_tone:'], + category: 'people', + }, + ':blond-haired_man_tone4:': { + uc_base: '1f471-1f3fe-2642', + uc_full: '1f471-1f3fe-200d-2642-fe0f', + shortnames: [':blond-haired_man_medium_dark_skin_tone:'], + category: 'people', + }, + ':blond-haired_man_tone5:': { + uc_base: '1f471-1f3ff-2642', + uc_full: '1f471-1f3ff-200d-2642-fe0f', + shortnames: [':blond-haired_man_dark_skin_tone:'], + category: 'people', + }, + ':blond-haired_woman_tone1:': { + uc_base: '1f471-1f3fb-2640', + uc_full: '1f471-1f3fb-200d-2640-fe0f', + shortnames: [':blond-haired_woman_light_skin_tone:'], + category: 'people', + }, + ':blond-haired_woman_tone2:': { + uc_base: '1f471-1f3fc-2640', + uc_full: '1f471-1f3fc-200d-2640-fe0f', + shortnames: [':blond-haired_woman_medium_light_skin_tone:'], + category: 'people', + }, + ':blond-haired_woman_tone3:': { + uc_base: '1f471-1f3fd-2640', + uc_full: '1f471-1f3fd-200d-2640-fe0f', + shortnames: [':blond-haired_woman_medium_skin_tone:'], + category: 'people', + }, + ':blond-haired_woman_tone4:': { + uc_base: '1f471-1f3fe-2640', + uc_full: '1f471-1f3fe-200d-2640-fe0f', + shortnames: [':blond-haired_woman_medium_dark_skin_tone:'], + category: 'people', + }, + ':blond-haired_woman_tone5:': { + uc_base: '1f471-1f3ff-2640', + uc_full: '1f471-1f3ff-200d-2640-fe0f', + shortnames: [':blond-haired_woman_dark_skin_tone:'], + category: 'people', + }, + ':couple_mm:': { + uc_base: '1f468-2764-1f468', + uc_full: '1f468-200d-2764-fe0f-200d-1f468', + shortnames: [':couple_with_heart_mm:'], + category: 'people', + }, + ':couple_with_heart_woman_man:': { + uc_base: '1f469-2764-1f468', + uc_full: '1f469-200d-2764-fe0f-200d-1f468', + shortnames: [], + category: 'people', + }, + ':couple_ww:': { + uc_base: '1f469-2764-1f469', + uc_full: '1f469-200d-2764-fe0f-200d-1f469', + shortnames: [':couple_with_heart_ww:'], + category: 'people', + }, + ':deaf_man_tone1:': { + uc_base: '1f9cf-1f3fb-2642', + uc_full: '1f9cf-1f3fb-200d-2642-fe0f', + shortnames: [':deaf_man_light_skin_tone:'], + category: 'people', + }, + ':deaf_man_tone2:': { + uc_base: '1f9cf-1f3fc-2642', + uc_full: '1f9cf-1f3fc-200d-2642-fe0f', + shortnames: [':deaf_man_medium_light_skin_tone:'], + category: 'people', + }, + ':deaf_man_tone3:': { + uc_base: '1f9cf-1f3fd-2642', + uc_full: '1f9cf-1f3fd-200d-2642-fe0f', + shortnames: [':deaf_man_medium_skin_tone:'], + category: 'people', + }, + ':deaf_man_tone4:': { + uc_base: '1f9cf-1f3fe-2642', + uc_full: '1f9cf-1f3fe-200d-2642-fe0f', + shortnames: [':deaf_man_medium_dark_skin_tone:'], + category: 'people', + }, + ':deaf_man_tone5:': { + uc_base: '1f9cf-1f3ff-2642', + uc_full: '1f9cf-1f3ff-200d-2642-fe0f', + shortnames: [':deaf_man_dark_skin_tone:'], + category: 'people', + }, + ':deaf_woman_tone1:': { + uc_base: '1f9cf-1f3fb-2640', + uc_full: '1f9cf-1f3fb-200d-2640-fe0f', + shortnames: [':deaf_woman_light_skin_tone:'], + category: 'people', + }, + ':deaf_woman_tone2:': { + uc_base: '1f9cf-1f3fc-2640', + uc_full: '1f9cf-1f3fc-200d-2640-fe0f', + shortnames: [':deaf_woman_medium_light_skin_tone:'], + category: 'people', + }, + ':deaf_woman_tone3:': { + uc_base: '1f9cf-1f3fd-2640', + uc_full: '1f9cf-1f3fd-200d-2640-fe0f', + shortnames: [':deaf_woman_medium_skin_tone:'], + category: 'people', + }, + ':deaf_woman_tone4:': { + uc_base: '1f9cf-1f3fe-2640', + uc_full: '1f9cf-1f3fe-200d-2640-fe0f', + shortnames: [':deaf_woman_medium_dark_skin_tone:'], + category: 'people', + }, + ':deaf_woman_tone5:': { + uc_base: '1f9cf-1f3ff-2640', + uc_full: '1f9cf-1f3ff-200d-2640-fe0f', + shortnames: [':deaf_woman_dark_skin_tone:'], + category: 'people', + }, + ':health_worker_tone1:': { + uc_base: '1f9d1-1f3fb-2695', + uc_full: '1f9d1-1f3fb-200d-2695-fe0f', + shortnames: [':health_worker_light_skin_tone:'], + category: 'people', + }, + ':health_worker_tone2:': { + uc_base: '1f9d1-1f3fc-2695', + uc_full: '1f9d1-1f3fc-200d-2695-fe0f', + shortnames: [':health_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':health_worker_tone3:': { + uc_base: '1f9d1-1f3fd-2695', + uc_full: '1f9d1-1f3fd-200d-2695-fe0f', + shortnames: [':health_worker_medium_skin_tone:'], + category: 'people', + }, + ':health_worker_tone4:': { + uc_base: '1f9d1-1f3fe-2695', + uc_full: '1f9d1-1f3fe-200d-2695-fe0f', + shortnames: [':health_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':health_worker_tone5:': { + uc_base: '1f9d1-1f3ff-2695', + uc_full: '1f9d1-1f3ff-200d-2695-fe0f', + shortnames: [':health_worker_dark_skin_tone:'], + category: 'people', + }, + ':judge_tone1:': { + uc_base: '1f9d1-1f3fb-2696', + uc_full: '1f9d1-1f3fb-200d-2696-fe0f', + shortnames: [':judge_light_skin_tone:'], + category: 'people', + }, + ':judge_tone2:': { + uc_base: '1f9d1-1f3fc-2696', + uc_full: '1f9d1-1f3fc-200d-2696-fe0f', + shortnames: [':judge_medium_light_skin_tone:'], + category: 'people', + }, + ':judge_tone3:': { + uc_base: '1f9d1-1f3fd-2696', + uc_full: '1f9d1-1f3fd-200d-2696-fe0f', + shortnames: [':judge_medium_skin_tone:'], + category: 'people', + }, + ':judge_tone4:': { + uc_base: '1f9d1-1f3fe-2696', + uc_full: '1f9d1-1f3fe-200d-2696-fe0f', + shortnames: [':judge_medium_dark_skin_tone:'], + category: 'people', + }, + ':judge_tone5:': { + uc_base: '1f9d1-1f3ff-2696', + uc_full: '1f9d1-1f3ff-200d-2696-fe0f', + shortnames: [':judge_dark_skin_tone:'], + category: 'people', + }, + ':man_biking_tone1:': { + uc_base: '1f6b4-1f3fb-2642', + uc_full: '1f6b4-1f3fb-200d-2642-fe0f', + shortnames: [':man_biking_light_skin_tone:'], + category: 'activity', + }, + ':man_biking_tone2:': { + uc_base: '1f6b4-1f3fc-2642', + uc_full: '1f6b4-1f3fc-200d-2642-fe0f', + shortnames: [':man_biking_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_biking_tone3:': { + uc_base: '1f6b4-1f3fd-2642', + uc_full: '1f6b4-1f3fd-200d-2642-fe0f', + shortnames: [':man_biking_medium_skin_tone:'], + category: 'activity', + }, + ':man_biking_tone4:': { + uc_base: '1f6b4-1f3fe-2642', + uc_full: '1f6b4-1f3fe-200d-2642-fe0f', + shortnames: [':man_biking_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_biking_tone5:': { + uc_base: '1f6b4-1f3ff-2642', + uc_full: '1f6b4-1f3ff-200d-2642-fe0f', + shortnames: [':man_biking_dark_skin_tone:'], + category: 'activity', + }, + ':man_bowing_tone1:': { + uc_base: '1f647-1f3fb-2642', + uc_full: '1f647-1f3fb-200d-2642-fe0f', + shortnames: [':man_bowing_light_skin_tone:'], + category: 'people', + }, + ':man_bowing_tone2:': { + uc_base: '1f647-1f3fc-2642', + uc_full: '1f647-1f3fc-200d-2642-fe0f', + shortnames: [':man_bowing_medium_light_skin_tone:'], + category: 'people', + }, + ':man_bowing_tone3:': { + uc_base: '1f647-1f3fd-2642', + uc_full: '1f647-1f3fd-200d-2642-fe0f', + shortnames: [':man_bowing_medium_skin_tone:'], + category: 'people', + }, + ':man_bowing_tone4:': { + uc_base: '1f647-1f3fe-2642', + uc_full: '1f647-1f3fe-200d-2642-fe0f', + shortnames: [':man_bowing_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_bowing_tone5:': { + uc_base: '1f647-1f3ff-2642', + uc_full: '1f647-1f3ff-200d-2642-fe0f', + shortnames: [':man_bowing_dark_skin_tone:'], + category: 'people', + }, + ':man_cartwheeling_tone1:': { + uc_base: '1f938-1f3fb-2642', + uc_full: '1f938-1f3fb-200d-2642-fe0f', + shortnames: [':man_cartwheeling_light_skin_tone:'], + category: 'activity', + }, + ':man_cartwheeling_tone2:': { + uc_base: '1f938-1f3fc-2642', + uc_full: '1f938-1f3fc-200d-2642-fe0f', + shortnames: [':man_cartwheeling_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_cartwheeling_tone3:': { + uc_base: '1f938-1f3fd-2642', + uc_full: '1f938-1f3fd-200d-2642-fe0f', + shortnames: [':man_cartwheeling_medium_skin_tone:'], + category: 'activity', + }, + ':man_cartwheeling_tone4:': { + uc_base: '1f938-1f3fe-2642', + uc_full: '1f938-1f3fe-200d-2642-fe0f', + shortnames: [':man_cartwheeling_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_cartwheeling_tone5:': { + uc_base: '1f938-1f3ff-2642', + uc_full: '1f938-1f3ff-200d-2642-fe0f', + shortnames: [':man_cartwheeling_dark_skin_tone:'], + category: 'activity', + }, + ':man_climbing_tone1:': { + uc_base: '1f9d7-1f3fb-2642', + uc_full: '1f9d7-1f3fb-200d-2642-fe0f', + shortnames: [':man_climbing_light_skin_tone:'], + category: 'activity', + }, + ':man_climbing_tone2:': { + uc_base: '1f9d7-1f3fc-2642', + uc_full: '1f9d7-1f3fc-200d-2642-fe0f', + shortnames: [':man_climbing_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_climbing_tone3:': { + uc_base: '1f9d7-1f3fd-2642', + uc_full: '1f9d7-1f3fd-200d-2642-fe0f', + shortnames: [':man_climbing_medium_skin_tone:'], + category: 'activity', + }, + ':man_climbing_tone4:': { + uc_base: '1f9d7-1f3fe-2642', + uc_full: '1f9d7-1f3fe-200d-2642-fe0f', + shortnames: [':man_climbing_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_climbing_tone5:': { + uc_base: '1f9d7-1f3ff-2642', + uc_full: '1f9d7-1f3ff-200d-2642-fe0f', + shortnames: [':man_climbing_dark_skin_tone:'], + category: 'activity', + }, + ':man_construction_worker_tone1:': { + uc_base: '1f477-1f3fb-2642', + uc_full: '1f477-1f3fb-200d-2642-fe0f', + shortnames: [':man_construction_worker_light_skin_tone:'], + category: 'people', + }, + ':man_construction_worker_tone2:': { + uc_base: '1f477-1f3fc-2642', + uc_full: '1f477-1f3fc-200d-2642-fe0f', + shortnames: [':man_construction_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':man_construction_worker_tone3:': { + uc_base: '1f477-1f3fd-2642', + uc_full: '1f477-1f3fd-200d-2642-fe0f', + shortnames: [':man_construction_worker_medium_skin_tone:'], + category: 'people', + }, + ':man_construction_worker_tone4:': { + uc_base: '1f477-1f3fe-2642', + uc_full: '1f477-1f3fe-200d-2642-fe0f', + shortnames: [':man_construction_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_construction_worker_tone5:': { + uc_base: '1f477-1f3ff-2642', + uc_full: '1f477-1f3ff-200d-2642-fe0f', + shortnames: [':man_construction_worker_dark_skin_tone:'], + category: 'people', + }, + ':man_detective_tone1:': { + uc_base: '1f575-1f3fb-2642', + uc_full: '1f575-1f3fb-200d-2642-fe0f', + shortnames: [':man_detective_light_skin_tone:'], + category: 'people', + }, + ':man_detective_tone2:': { + uc_base: '1f575-1f3fc-2642', + uc_full: '1f575-1f3fc-200d-2642-fe0f', + shortnames: [':man_detective_medium_light_skin_tone:'], + category: 'people', + }, + ':man_detective_tone3:': { + uc_base: '1f575-1f3fd-2642', + uc_full: '1f575-1f3fd-200d-2642-fe0f', + shortnames: [':man_detective_medium_skin_tone:'], + category: 'people', + }, + ':man_detective_tone4:': { + uc_base: '1f575-1f3fe-2642', + uc_full: '1f575-1f3fe-200d-2642-fe0f', + shortnames: [':man_detective_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_detective_tone5:': { + uc_base: '1f575-1f3ff-2642', + uc_full: '1f575-1f3ff-200d-2642-fe0f', + shortnames: [':man_detective_dark_skin_tone:'], + category: 'people', + }, + ':man_elf_tone1:': { + uc_base: '1f9dd-1f3fb-2642', + uc_full: '1f9dd-1f3fb-200d-2642-fe0f', + shortnames: [':man_elf_light_skin_tone:'], + category: 'people', + }, + ':man_elf_tone2:': { + uc_base: '1f9dd-1f3fc-2642', + uc_full: '1f9dd-1f3fc-200d-2642-fe0f', + shortnames: [':man_elf_medium_light_skin_tone:'], + category: 'people', + }, + ':man_elf_tone3:': { + uc_base: '1f9dd-1f3fd-2642', + uc_full: '1f9dd-1f3fd-200d-2642-fe0f', + shortnames: [':man_elf_medium_skin_tone:'], + category: 'people', + }, + ':man_elf_tone4:': { + uc_base: '1f9dd-1f3fe-2642', + uc_full: '1f9dd-1f3fe-200d-2642-fe0f', + shortnames: [':man_elf_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_elf_tone5:': { + uc_base: '1f9dd-1f3ff-2642', + uc_full: '1f9dd-1f3ff-200d-2642-fe0f', + shortnames: [':man_elf_dark_skin_tone:'], + category: 'people', + }, + ':man_facepalming_tone1:': { + uc_base: '1f926-1f3fb-2642', + uc_full: '1f926-1f3fb-200d-2642-fe0f', + shortnames: [':man_facepalming_light_skin_tone:'], + category: 'people', + }, + ':man_facepalming_tone2:': { + uc_base: '1f926-1f3fc-2642', + uc_full: '1f926-1f3fc-200d-2642-fe0f', + shortnames: [':man_facepalming_medium_light_skin_tone:'], + category: 'people', + }, + ':man_facepalming_tone3:': { + uc_base: '1f926-1f3fd-2642', + uc_full: '1f926-1f3fd-200d-2642-fe0f', + shortnames: [':man_facepalming_medium_skin_tone:'], + category: 'people', + }, + ':man_facepalming_tone4:': { + uc_base: '1f926-1f3fe-2642', + uc_full: '1f926-1f3fe-200d-2642-fe0f', + shortnames: [':man_facepalming_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_facepalming_tone5:': { + uc_base: '1f926-1f3ff-2642', + uc_full: '1f926-1f3ff-200d-2642-fe0f', + shortnames: [':man_facepalming_dark_skin_tone:'], + category: 'people', + }, + ':man_fairy_tone1:': { + uc_base: '1f9da-1f3fb-2642', + uc_full: '1f9da-1f3fb-200d-2642-fe0f', + shortnames: [':man_fairy_light_skin_tone:'], + category: 'people', + }, + ':man_fairy_tone2:': { + uc_base: '1f9da-1f3fc-2642', + uc_full: '1f9da-1f3fc-200d-2642-fe0f', + shortnames: [':man_fairy_medium_light_skin_tone:'], + category: 'people', + }, + ':man_fairy_tone3:': { + uc_base: '1f9da-1f3fd-2642', + uc_full: '1f9da-1f3fd-200d-2642-fe0f', + shortnames: [':man_fairy_medium_skin_tone:'], + category: 'people', + }, + ':man_fairy_tone4:': { + uc_base: '1f9da-1f3fe-2642', + uc_full: '1f9da-1f3fe-200d-2642-fe0f', + shortnames: [':man_fairy_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_fairy_tone5:': { + uc_base: '1f9da-1f3ff-2642', + uc_full: '1f9da-1f3ff-200d-2642-fe0f', + shortnames: [':man_fairy_dark_skin_tone:'], + category: 'people', + }, + ':man_frowning_tone1:': { + uc_base: '1f64d-1f3fb-2642', + uc_full: '1f64d-1f3fb-200d-2642-fe0f', + shortnames: [':man_frowning_light_skin_tone:'], + category: 'people', + }, + ':man_frowning_tone2:': { + uc_base: '1f64d-1f3fc-2642', + uc_full: '1f64d-1f3fc-200d-2642-fe0f', + shortnames: [':man_frowning_medium_light_skin_tone:'], + category: 'people', + }, + ':man_frowning_tone3:': { + uc_base: '1f64d-1f3fd-2642', + uc_full: '1f64d-1f3fd-200d-2642-fe0f', + shortnames: [':man_frowning_medium_skin_tone:'], + category: 'people', + }, + ':man_frowning_tone4:': { + uc_base: '1f64d-1f3fe-2642', + uc_full: '1f64d-1f3fe-200d-2642-fe0f', + shortnames: [':man_frowning_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_frowning_tone5:': { + uc_base: '1f64d-1f3ff-2642', + uc_full: '1f64d-1f3ff-200d-2642-fe0f', + shortnames: [':man_frowning_dark_skin_tone:'], + category: 'people', + }, + ':man_gesturing_no_tone1:': { + uc_base: '1f645-1f3fb-2642', + uc_full: '1f645-1f3fb-200d-2642-fe0f', + shortnames: [':man_gesturing_no_light_skin_tone:'], + category: 'people', + }, + ':man_gesturing_no_tone2:': { + uc_base: '1f645-1f3fc-2642', + uc_full: '1f645-1f3fc-200d-2642-fe0f', + shortnames: [':man_gesturing_no_medium_light_skin_tone:'], + category: 'people', + }, + ':man_gesturing_no_tone3:': { + uc_base: '1f645-1f3fd-2642', + uc_full: '1f645-1f3fd-200d-2642-fe0f', + shortnames: [':man_gesturing_no_medium_skin_tone:'], + category: 'people', + }, + ':man_gesturing_no_tone4:': { + uc_base: '1f645-1f3fe-2642', + uc_full: '1f645-1f3fe-200d-2642-fe0f', + shortnames: [':man_gesturing_no_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_gesturing_no_tone5:': { + uc_base: '1f645-1f3ff-2642', + uc_full: '1f645-1f3ff-200d-2642-fe0f', + shortnames: [':man_gesturing_no_dark_skin_tone:'], + category: 'people', + }, + ':man_gesturing_ok_tone1:': { + uc_base: '1f646-1f3fb-2642', + uc_full: '1f646-1f3fb-200d-2642-fe0f', + shortnames: [':man_gesturing_ok_light_skin_tone:'], + category: 'people', + }, + ':man_gesturing_ok_tone2:': { + uc_base: '1f646-1f3fc-2642', + uc_full: '1f646-1f3fc-200d-2642-fe0f', + shortnames: [':man_gesturing_ok_medium_light_skin_tone:'], + category: 'people', + }, + ':man_gesturing_ok_tone3:': { + uc_base: '1f646-1f3fd-2642', + uc_full: '1f646-1f3fd-200d-2642-fe0f', + shortnames: [':man_gesturing_ok_medium_skin_tone:'], + category: 'people', + }, + ':man_gesturing_ok_tone4:': { + uc_base: '1f646-1f3fe-2642', + uc_full: '1f646-1f3fe-200d-2642-fe0f', + shortnames: [':man_gesturing_ok_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_gesturing_ok_tone5:': { + uc_base: '1f646-1f3ff-2642', + uc_full: '1f646-1f3ff-200d-2642-fe0f', + shortnames: [':man_gesturing_ok_dark_skin_tone:'], + category: 'people', + }, + ':man_getting_face_massage_tone1:': { + uc_base: '1f486-1f3fb-2642', + uc_full: '1f486-1f3fb-200d-2642-fe0f', + shortnames: [':man_getting_face_massage_light_skin_tone:'], + category: 'people', + }, + ':man_getting_face_massage_tone2:': { + uc_base: '1f486-1f3fc-2642', + uc_full: '1f486-1f3fc-200d-2642-fe0f', + shortnames: [':man_getting_face_massage_medium_light_skin_tone:'], + category: 'people', + }, + ':man_getting_face_massage_tone3:': { + uc_base: '1f486-1f3fd-2642', + uc_full: '1f486-1f3fd-200d-2642-fe0f', + shortnames: [':man_getting_face_massage_medium_skin_tone:'], + category: 'people', + }, + ':man_getting_face_massage_tone4:': { + uc_base: '1f486-1f3fe-2642', + uc_full: '1f486-1f3fe-200d-2642-fe0f', + shortnames: [':man_getting_face_massage_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_getting_face_massage_tone5:': { + uc_base: '1f486-1f3ff-2642', + uc_full: '1f486-1f3ff-200d-2642-fe0f', + shortnames: [':man_getting_face_massage_dark_skin_tone:'], + category: 'people', + }, + ':man_getting_haircut_tone1:': { + uc_base: '1f487-1f3fb-2642', + uc_full: '1f487-1f3fb-200d-2642-fe0f', + shortnames: [':man_getting_haircut_light_skin_tone:'], + category: 'people', + }, + ':man_getting_haircut_tone2:': { + uc_base: '1f487-1f3fc-2642', + uc_full: '1f487-1f3fc-200d-2642-fe0f', + shortnames: [':man_getting_haircut_medium_light_skin_tone:'], + category: 'people', + }, + ':man_getting_haircut_tone3:': { + uc_base: '1f487-1f3fd-2642', + uc_full: '1f487-1f3fd-200d-2642-fe0f', + shortnames: [':man_getting_haircut_medium_skin_tone:'], + category: 'people', + }, + ':man_getting_haircut_tone4:': { + uc_base: '1f487-1f3fe-2642', + uc_full: '1f487-1f3fe-200d-2642-fe0f', + shortnames: [':man_getting_haircut_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_getting_haircut_tone5:': { + uc_base: '1f487-1f3ff-2642', + uc_full: '1f487-1f3ff-200d-2642-fe0f', + shortnames: [':man_getting_haircut_dark_skin_tone:'], + category: 'people', + }, + ':man_golfing_tone1:': { + uc_base: '1f3cc-1f3fb-2642', + uc_full: '1f3cc-1f3fb-200d-2642-fe0f', + shortnames: [':man_golfing_light_skin_tone:'], + category: 'activity', + }, + ':man_golfing_tone2:': { + uc_base: '1f3cc-1f3fc-2642', + uc_full: '1f3cc-1f3fc-200d-2642-fe0f', + shortnames: [':man_golfing_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_golfing_tone3:': { + uc_base: '1f3cc-1f3fd-2642', + uc_full: '1f3cc-1f3fd-200d-2642-fe0f', + shortnames: [':man_golfing_medium_skin_tone:'], + category: 'activity', + }, + ':man_golfing_tone4:': { + uc_base: '1f3cc-1f3fe-2642', + uc_full: '1f3cc-1f3fe-200d-2642-fe0f', + shortnames: [':man_golfing_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_golfing_tone5:': { + uc_base: '1f3cc-1f3ff-2642', + uc_full: '1f3cc-1f3ff-200d-2642-fe0f', + shortnames: [':man_golfing_dark_skin_tone:'], + category: 'activity', + }, + ':man_guard_tone1:': { + uc_base: '1f482-1f3fb-2642', + uc_full: '1f482-1f3fb-200d-2642-fe0f', + shortnames: [':man_guard_light_skin_tone:'], + category: 'people', + }, + ':man_guard_tone2:': { + uc_base: '1f482-1f3fc-2642', + uc_full: '1f482-1f3fc-200d-2642-fe0f', + shortnames: [':man_guard_medium_light_skin_tone:'], + category: 'people', + }, + ':man_guard_tone3:': { + uc_base: '1f482-1f3fd-2642', + uc_full: '1f482-1f3fd-200d-2642-fe0f', + shortnames: [':man_guard_medium_skin_tone:'], + category: 'people', + }, + ':man_guard_tone4:': { + uc_base: '1f482-1f3fe-2642', + uc_full: '1f482-1f3fe-200d-2642-fe0f', + shortnames: [':man_guard_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_guard_tone5:': { + uc_base: '1f482-1f3ff-2642', + uc_full: '1f482-1f3ff-200d-2642-fe0f', + shortnames: [':man_guard_dark_skin_tone:'], + category: 'people', + }, + ':man_health_worker_tone1:': { + uc_base: '1f468-1f3fb-2695', + uc_full: '1f468-1f3fb-200d-2695-fe0f', + shortnames: [':man_health_worker_light_skin_tone:'], + category: 'people', + }, + ':man_health_worker_tone2:': { + uc_base: '1f468-1f3fc-2695', + uc_full: '1f468-1f3fc-200d-2695-fe0f', + shortnames: [':man_health_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':man_health_worker_tone3:': { + uc_base: '1f468-1f3fd-2695', + uc_full: '1f468-1f3fd-200d-2695-fe0f', + shortnames: [':man_health_worker_medium_skin_tone:'], + category: 'people', + }, + ':man_health_worker_tone4:': { + uc_base: '1f468-1f3fe-2695', + uc_full: '1f468-1f3fe-200d-2695-fe0f', + shortnames: [':man_health_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_health_worker_tone5:': { + uc_base: '1f468-1f3ff-2695', + uc_full: '1f468-1f3ff-200d-2695-fe0f', + shortnames: [':man_health_worker_dark_skin_tone:'], + category: 'people', + }, + ':man_in_lotus_position_tone1:': { + uc_base: '1f9d8-1f3fb-2642', + uc_full: '1f9d8-1f3fb-200d-2642-fe0f', + shortnames: [':man_in_lotus_position_light_skin_tone:'], + category: 'activity', + }, + ':man_in_lotus_position_tone2:': { + uc_base: '1f9d8-1f3fc-2642', + uc_full: '1f9d8-1f3fc-200d-2642-fe0f', + shortnames: [':man_in_lotus_position_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_in_lotus_position_tone3:': { + uc_base: '1f9d8-1f3fd-2642', + uc_full: '1f9d8-1f3fd-200d-2642-fe0f', + shortnames: [':man_in_lotus_position_medium_skin_tone:'], + category: 'activity', + }, + ':man_in_lotus_position_tone4:': { + uc_base: '1f9d8-1f3fe-2642', + uc_full: '1f9d8-1f3fe-200d-2642-fe0f', + shortnames: [':man_in_lotus_position_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_in_lotus_position_tone5:': { + uc_base: '1f9d8-1f3ff-2642', + uc_full: '1f9d8-1f3ff-200d-2642-fe0f', + shortnames: [':man_in_lotus_position_dark_skin_tone:'], + category: 'activity', + }, + ':man_in_steamy_room_tone1:': { + uc_base: '1f9d6-1f3fb-2642', + uc_full: '1f9d6-1f3fb-200d-2642-fe0f', + shortnames: [':man_in_steamy_room_light_skin_tone:'], + category: 'people', + }, + ':man_in_steamy_room_tone2:': { + uc_base: '1f9d6-1f3fc-2642', + uc_full: '1f9d6-1f3fc-200d-2642-fe0f', + shortnames: [':man_in_steamy_room_medium_light_skin_tone:'], + category: 'people', + }, + ':man_in_steamy_room_tone3:': { + uc_base: '1f9d6-1f3fd-2642', + uc_full: '1f9d6-1f3fd-200d-2642-fe0f', + shortnames: [':man_in_steamy_room_medium_skin_tone:'], + category: 'people', + }, + ':man_in_steamy_room_tone4:': { + uc_base: '1f9d6-1f3fe-2642', + uc_full: '1f9d6-1f3fe-200d-2642-fe0f', + shortnames: [':man_in_steamy_room_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_in_steamy_room_tone5:': { + uc_base: '1f9d6-1f3ff-2642', + uc_full: '1f9d6-1f3ff-200d-2642-fe0f', + shortnames: [':man_in_steamy_room_dark_skin_tone:'], + category: 'people', + }, + ':man_in_tuxedo_tone1:': { + uc_base: '1f935-1f3fb-2642', + uc_full: '1f935-1f3fb-200d-2642-fe0f', + shortnames: [':man_in_tuxedo_light_skin_tone:'], + category: 'people', + }, + ':man_in_tuxedo_tone2:': { + uc_base: '1f935-1f3fc-2642', + uc_full: '1f935-1f3fc-200d-2642-fe0f', + shortnames: [':man_in_tuxedo_medium_light_skin_tone:'], + category: 'people', + }, + ':man_in_tuxedo_tone3:': { + uc_base: '1f935-1f3fd-2642', + uc_full: '1f935-1f3fd-200d-2642-fe0f', + shortnames: [':man_in_tuxedo_medium_skin_tone:'], + category: 'people', + }, + ':man_in_tuxedo_tone4:': { + uc_base: '1f935-1f3fe-2642', + uc_full: '1f935-1f3fe-200d-2642-fe0f', + shortnames: [':man_in_tuxedo_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_in_tuxedo_tone5:': { + uc_base: '1f935-1f3ff-2642', + uc_full: '1f935-1f3ff-200d-2642-fe0f', + shortnames: [':man_in_tuxedo_dark_skin_tone:'], + category: 'people', + }, + ':man_judge_tone1:': { + uc_base: '1f468-1f3fb-2696', + uc_full: '1f468-1f3fb-200d-2696-fe0f', + shortnames: [':man_judge_light_skin_tone:'], + category: 'people', + }, + ':man_judge_tone2:': { + uc_base: '1f468-1f3fc-2696', + uc_full: '1f468-1f3fc-200d-2696-fe0f', + shortnames: [':man_judge_medium_light_skin_tone:'], + category: 'people', + }, + ':man_judge_tone3:': { + uc_base: '1f468-1f3fd-2696', + uc_full: '1f468-1f3fd-200d-2696-fe0f', + shortnames: [':man_judge_medium_skin_tone:'], + category: 'people', + }, + ':man_judge_tone4:': { + uc_base: '1f468-1f3fe-2696', + uc_full: '1f468-1f3fe-200d-2696-fe0f', + shortnames: [':man_judge_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_judge_tone5:': { + uc_base: '1f468-1f3ff-2696', + uc_full: '1f468-1f3ff-200d-2696-fe0f', + shortnames: [':man_judge_dark_skin_tone:'], + category: 'people', + }, + ':man_juggling_tone1:': { + uc_base: '1f939-1f3fb-2642', + uc_full: '1f939-1f3fb-200d-2642-fe0f', + shortnames: [':man_juggling_light_skin_tone:'], + category: 'activity', + }, + ':man_juggling_tone2:': { + uc_base: '1f939-1f3fc-2642', + uc_full: '1f939-1f3fc-200d-2642-fe0f', + shortnames: [':man_juggling_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_juggling_tone3:': { + uc_base: '1f939-1f3fd-2642', + uc_full: '1f939-1f3fd-200d-2642-fe0f', + shortnames: [':man_juggling_medium_skin_tone:'], + category: 'activity', + }, + ':man_juggling_tone4:': { + uc_base: '1f939-1f3fe-2642', + uc_full: '1f939-1f3fe-200d-2642-fe0f', + shortnames: [':man_juggling_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_juggling_tone5:': { + uc_base: '1f939-1f3ff-2642', + uc_full: '1f939-1f3ff-200d-2642-fe0f', + shortnames: [':man_juggling_dark_skin_tone:'], + category: 'activity', + }, + ':man_kneeling_tone1:': { + uc_base: '1f9ce-1f3fb-2642', + uc_full: '1f9ce-1f3fb-200d-2642-fe0f', + shortnames: [':man_kneeling_light_skin_tone:'], + category: 'people', + }, + ':man_kneeling_tone2:': { + uc_base: '1f9ce-1f3fc-2642', + uc_full: '1f9ce-1f3fc-200d-2642-fe0f', + shortnames: [':man_kneeling_medium_light_skin_tone:'], + category: 'people', + }, + ':man_kneeling_tone3:': { + uc_base: '1f9ce-1f3fd-2642', + uc_full: '1f9ce-1f3fd-200d-2642-fe0f', + shortnames: [':man_kneeling_medium_skin_tone:'], + category: 'people', + }, + ':man_kneeling_tone4:': { + uc_base: '1f9ce-1f3fe-2642', + uc_full: '1f9ce-1f3fe-200d-2642-fe0f', + shortnames: [':man_kneeling_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_kneeling_tone5:': { + uc_base: '1f9ce-1f3ff-2642', + uc_full: '1f9ce-1f3ff-200d-2642-fe0f', + shortnames: [':man_kneeling_dark_skin_tone:'], + category: 'people', + }, + ':man_lifting_weights_tone1:': { + uc_base: '1f3cb-1f3fb-2642', + uc_full: '1f3cb-1f3fb-200d-2642-fe0f', + shortnames: [':man_lifting_weights_light_skin_tone:'], + category: 'activity', + }, + ':man_lifting_weights_tone2:': { + uc_base: '1f3cb-1f3fc-2642', + uc_full: '1f3cb-1f3fc-200d-2642-fe0f', + shortnames: [':man_lifting_weights_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_lifting_weights_tone3:': { + uc_base: '1f3cb-1f3fd-2642', + uc_full: '1f3cb-1f3fd-200d-2642-fe0f', + shortnames: [':man_lifting_weights_medium_skin_tone:'], + category: 'activity', + }, + ':man_lifting_weights_tone4:': { + uc_base: '1f3cb-1f3fe-2642', + uc_full: '1f3cb-1f3fe-200d-2642-fe0f', + shortnames: [':man_lifting_weights_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_lifting_weights_tone5:': { + uc_base: '1f3cb-1f3ff-2642', + uc_full: '1f3cb-1f3ff-200d-2642-fe0f', + shortnames: [':man_lifting_weights_dark_skin_tone:'], + category: 'activity', + }, + ':man_mage_tone1:': { + uc_base: '1f9d9-1f3fb-2642', + uc_full: '1f9d9-1f3fb-200d-2642-fe0f', + shortnames: [':man_mage_light_skin_tone:'], + category: 'people', + }, + ':man_mage_tone2:': { + uc_base: '1f9d9-1f3fc-2642', + uc_full: '1f9d9-1f3fc-200d-2642-fe0f', + shortnames: [':man_mage_medium_light_skin_tone:'], + category: 'people', + }, + ':man_mage_tone3:': { + uc_base: '1f9d9-1f3fd-2642', + uc_full: '1f9d9-1f3fd-200d-2642-fe0f', + shortnames: [':man_mage_medium_skin_tone:'], + category: 'people', + }, + ':man_mage_tone4:': { + uc_base: '1f9d9-1f3fe-2642', + uc_full: '1f9d9-1f3fe-200d-2642-fe0f', + shortnames: [':man_mage_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_mage_tone5:': { + uc_base: '1f9d9-1f3ff-2642', + uc_full: '1f9d9-1f3ff-200d-2642-fe0f', + shortnames: [':man_mage_dark_skin_tone:'], + category: 'people', + }, + ':man_mountain_biking_tone1:': { + uc_base: '1f6b5-1f3fb-2642', + uc_full: '1f6b5-1f3fb-200d-2642-fe0f', + shortnames: [':man_mountain_biking_light_skin_tone:'], + category: 'activity', + }, + ':man_mountain_biking_tone2:': { + uc_base: '1f6b5-1f3fc-2642', + uc_full: '1f6b5-1f3fc-200d-2642-fe0f', + shortnames: [':man_mountain_biking_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_mountain_biking_tone3:': { + uc_base: '1f6b5-1f3fd-2642', + uc_full: '1f6b5-1f3fd-200d-2642-fe0f', + shortnames: [':man_mountain_biking_medium_skin_tone:'], + category: 'activity', + }, + ':man_mountain_biking_tone4:': { + uc_base: '1f6b5-1f3fe-2642', + uc_full: '1f6b5-1f3fe-200d-2642-fe0f', + shortnames: [':man_mountain_biking_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_mountain_biking_tone5:': { + uc_base: '1f6b5-1f3ff-2642', + uc_full: '1f6b5-1f3ff-200d-2642-fe0f', + shortnames: [':man_mountain_biking_dark_skin_tone:'], + category: 'activity', + }, + ':man_pilot_tone1:': { + uc_base: '1f468-1f3fb-2708', + uc_full: '1f468-1f3fb-200d-2708-fe0f', + shortnames: [':man_pilot_light_skin_tone:'], + category: 'people', + }, + ':man_pilot_tone2:': { + uc_base: '1f468-1f3fc-2708', + uc_full: '1f468-1f3fc-200d-2708-fe0f', + shortnames: [':man_pilot_medium_light_skin_tone:'], + category: 'people', + }, + ':man_pilot_tone3:': { + uc_base: '1f468-1f3fd-2708', + uc_full: '1f468-1f3fd-200d-2708-fe0f', + shortnames: [':man_pilot_medium_skin_tone:'], + category: 'people', + }, + ':man_pilot_tone4:': { + uc_base: '1f468-1f3fe-2708', + uc_full: '1f468-1f3fe-200d-2708-fe0f', + shortnames: [':man_pilot_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_pilot_tone5:': { + uc_base: '1f468-1f3ff-2708', + uc_full: '1f468-1f3ff-200d-2708-fe0f', + shortnames: [':man_pilot_dark_skin_tone:'], + category: 'people', + }, + ':man_playing_handball_tone1:': { + uc_base: '1f93e-1f3fb-2642', + uc_full: '1f93e-1f3fb-200d-2642-fe0f', + shortnames: [':man_playing_handball_light_skin_tone:'], + category: 'activity', + }, + ':man_playing_handball_tone2:': { + uc_base: '1f93e-1f3fc-2642', + uc_full: '1f93e-1f3fc-200d-2642-fe0f', + shortnames: [':man_playing_handball_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_playing_handball_tone3:': { + uc_base: '1f93e-1f3fd-2642', + uc_full: '1f93e-1f3fd-200d-2642-fe0f', + shortnames: [':man_playing_handball_medium_skin_tone:'], + category: 'activity', + }, + ':man_playing_handball_tone4:': { + uc_base: '1f93e-1f3fe-2642', + uc_full: '1f93e-1f3fe-200d-2642-fe0f', + shortnames: [':man_playing_handball_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_playing_handball_tone5:': { + uc_base: '1f93e-1f3ff-2642', + uc_full: '1f93e-1f3ff-200d-2642-fe0f', + shortnames: [':man_playing_handball_dark_skin_tone:'], + category: 'activity', + }, + ':man_playing_water_polo_tone1:': { + uc_base: '1f93d-1f3fb-2642', + uc_full: '1f93d-1f3fb-200d-2642-fe0f', + shortnames: [':man_playing_water_polo_light_skin_tone:'], + category: 'activity', + }, + ':man_playing_water_polo_tone2:': { + uc_base: '1f93d-1f3fc-2642', + uc_full: '1f93d-1f3fc-200d-2642-fe0f', + shortnames: [':man_playing_water_polo_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_playing_water_polo_tone3:': { + uc_base: '1f93d-1f3fd-2642', + uc_full: '1f93d-1f3fd-200d-2642-fe0f', + shortnames: [':man_playing_water_polo_medium_skin_tone:'], + category: 'activity', + }, + ':man_playing_water_polo_tone4:': { + uc_base: '1f93d-1f3fe-2642', + uc_full: '1f93d-1f3fe-200d-2642-fe0f', + shortnames: [':man_playing_water_polo_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_playing_water_polo_tone5:': { + uc_base: '1f93d-1f3ff-2642', + uc_full: '1f93d-1f3ff-200d-2642-fe0f', + shortnames: [':man_playing_water_polo_dark_skin_tone:'], + category: 'activity', + }, + ':man_police_officer_tone1:': { + uc_base: '1f46e-1f3fb-2642', + uc_full: '1f46e-1f3fb-200d-2642-fe0f', + shortnames: [':man_police_officer_light_skin_tone:'], + category: 'people', + }, + ':man_police_officer_tone2:': { + uc_base: '1f46e-1f3fc-2642', + uc_full: '1f46e-1f3fc-200d-2642-fe0f', + shortnames: [':man_police_officer_medium_light_skin_tone:'], + category: 'people', + }, + ':man_police_officer_tone3:': { + uc_base: '1f46e-1f3fd-2642', + uc_full: '1f46e-1f3fd-200d-2642-fe0f', + shortnames: [':man_police_officer_medium_skin_tone:'], + category: 'people', + }, + ':man_police_officer_tone4:': { + uc_base: '1f46e-1f3fe-2642', + uc_full: '1f46e-1f3fe-200d-2642-fe0f', + shortnames: [':man_police_officer_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_police_officer_tone5:': { + uc_base: '1f46e-1f3ff-2642', + uc_full: '1f46e-1f3ff-200d-2642-fe0f', + shortnames: [':man_police_officer_dark_skin_tone:'], + category: 'people', + }, + ':man_pouting_tone1:': { + uc_base: '1f64e-1f3fb-2642', + uc_full: '1f64e-1f3fb-200d-2642-fe0f', + shortnames: [':man_pouting_light_skin_tone:'], + category: 'people', + }, + ':man_pouting_tone2:': { + uc_base: '1f64e-1f3fc-2642', + uc_full: '1f64e-1f3fc-200d-2642-fe0f', + shortnames: [':man_pouting_medium_light_skin_tone:'], + category: 'people', + }, + ':man_pouting_tone3:': { + uc_base: '1f64e-1f3fd-2642', + uc_full: '1f64e-1f3fd-200d-2642-fe0f', + shortnames: [':man_pouting_medium_skin_tone:'], + category: 'people', + }, + ':man_pouting_tone4:': { + uc_base: '1f64e-1f3fe-2642', + uc_full: '1f64e-1f3fe-200d-2642-fe0f', + shortnames: [':man_pouting_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_pouting_tone5:': { + uc_base: '1f64e-1f3ff-2642', + uc_full: '1f64e-1f3ff-200d-2642-fe0f', + shortnames: [':man_pouting_dark_skin_tone:'], + category: 'people', + }, + ':man_raising_hand_tone1:': { + uc_base: '1f64b-1f3fb-2642', + uc_full: '1f64b-1f3fb-200d-2642-fe0f', + shortnames: [':man_raising_hand_light_skin_tone:'], + category: 'people', + }, + ':man_raising_hand_tone2:': { + uc_base: '1f64b-1f3fc-2642', + uc_full: '1f64b-1f3fc-200d-2642-fe0f', + shortnames: [':man_raising_hand_medium_light_skin_tone:'], + category: 'people', + }, + ':man_raising_hand_tone3:': { + uc_base: '1f64b-1f3fd-2642', + uc_full: '1f64b-1f3fd-200d-2642-fe0f', + shortnames: [':man_raising_hand_medium_skin_tone:'], + category: 'people', + }, + ':man_raising_hand_tone4:': { + uc_base: '1f64b-1f3fe-2642', + uc_full: '1f64b-1f3fe-200d-2642-fe0f', + shortnames: [':man_raising_hand_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_raising_hand_tone5:': { + uc_base: '1f64b-1f3ff-2642', + uc_full: '1f64b-1f3ff-200d-2642-fe0f', + shortnames: [':man_raising_hand_dark_skin_tone:'], + category: 'people', + }, + ':man_rowing_boat_tone1:': { + uc_base: '1f6a3-1f3fb-2642', + uc_full: '1f6a3-1f3fb-200d-2642-fe0f', + shortnames: [':man_rowing_boat_light_skin_tone:'], + category: 'activity', + }, + ':man_rowing_boat_tone2:': { + uc_base: '1f6a3-1f3fc-2642', + uc_full: '1f6a3-1f3fc-200d-2642-fe0f', + shortnames: [':man_rowing_boat_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_rowing_boat_tone3:': { + uc_base: '1f6a3-1f3fd-2642', + uc_full: '1f6a3-1f3fd-200d-2642-fe0f', + shortnames: [':man_rowing_boat_medium_skin_tone:'], + category: 'activity', + }, + ':man_rowing_boat_tone4:': { + uc_base: '1f6a3-1f3fe-2642', + uc_full: '1f6a3-1f3fe-200d-2642-fe0f', + shortnames: [':man_rowing_boat_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_rowing_boat_tone5:': { + uc_base: '1f6a3-1f3ff-2642', + uc_full: '1f6a3-1f3ff-200d-2642-fe0f', + shortnames: [':man_rowing_boat_dark_skin_tone:'], + category: 'activity', + }, + ':man_running_tone1:': { + uc_base: '1f3c3-1f3fb-2642', + uc_full: '1f3c3-1f3fb-200d-2642-fe0f', + shortnames: [':man_running_light_skin_tone:'], + category: 'people', + }, + ':man_running_tone2:': { + uc_base: '1f3c3-1f3fc-2642', + uc_full: '1f3c3-1f3fc-200d-2642-fe0f', + shortnames: [':man_running_medium_light_skin_tone:'], + category: 'people', + }, + ':man_running_tone3:': { + uc_base: '1f3c3-1f3fd-2642', + uc_full: '1f3c3-1f3fd-200d-2642-fe0f', + shortnames: [':man_running_medium_skin_tone:'], + category: 'people', + }, + ':man_running_tone4:': { + uc_base: '1f3c3-1f3fe-2642', + uc_full: '1f3c3-1f3fe-200d-2642-fe0f', + shortnames: [':man_running_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_running_tone5:': { + uc_base: '1f3c3-1f3ff-2642', + uc_full: '1f3c3-1f3ff-200d-2642-fe0f', + shortnames: [':man_running_dark_skin_tone:'], + category: 'people', + }, + ':man_shrugging_tone1:': { + uc_base: '1f937-1f3fb-2642', + uc_full: '1f937-1f3fb-200d-2642-fe0f', + shortnames: [':man_shrugging_light_skin_tone:'], + category: 'people', + }, + ':man_shrugging_tone2:': { + uc_base: '1f937-1f3fc-2642', + uc_full: '1f937-1f3fc-200d-2642-fe0f', + shortnames: [':man_shrugging_medium_light_skin_tone:'], + category: 'people', + }, + ':man_shrugging_tone3:': { + uc_base: '1f937-1f3fd-2642', + uc_full: '1f937-1f3fd-200d-2642-fe0f', + shortnames: [':man_shrugging_medium_skin_tone:'], + category: 'people', + }, + ':man_shrugging_tone4:': { + uc_base: '1f937-1f3fe-2642', + uc_full: '1f937-1f3fe-200d-2642-fe0f', + shortnames: [':man_shrugging_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_shrugging_tone5:': { + uc_base: '1f937-1f3ff-2642', + uc_full: '1f937-1f3ff-200d-2642-fe0f', + shortnames: [':man_shrugging_dark_skin_tone:'], + category: 'people', + }, + ':man_standing_tone1:': { + uc_base: '1f9cd-1f3fb-2642', + uc_full: '1f9cd-1f3fb-200d-2642-fe0f', + shortnames: [':man_standing_light_skin_tone:'], + category: 'people', + }, + ':man_standing_tone2:': { + uc_base: '1f9cd-1f3fc-2642', + uc_full: '1f9cd-1f3fc-200d-2642-fe0f', + shortnames: [':man_standing_medium_light_skin_tone:'], + category: 'people', + }, + ':man_standing_tone3:': { + uc_base: '1f9cd-1f3fd-2642', + uc_full: '1f9cd-1f3fd-200d-2642-fe0f', + shortnames: [':man_standing_medium_skin_tone:'], + category: 'people', + }, + ':man_standing_tone4:': { + uc_base: '1f9cd-1f3fe-2642', + uc_full: '1f9cd-1f3fe-200d-2642-fe0f', + shortnames: [':man_standing_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_standing_tone5:': { + uc_base: '1f9cd-1f3ff-2642', + uc_full: '1f9cd-1f3ff-200d-2642-fe0f', + shortnames: [':man_standing_dark_skin_tone:'], + category: 'people', + }, + ':man_superhero_tone1:': { + uc_base: '1f9b8-1f3fb-2642', + uc_full: '1f9b8-1f3fb-200d-2642-fe0f', + shortnames: [':man_superhero_light_skin_tone:'], + category: 'people', + }, + ':man_superhero_tone2:': { + uc_base: '1f9b8-1f3fc-2642', + uc_full: '1f9b8-1f3fc-200d-2642-fe0f', + shortnames: [':man_superhero_medium_light_skin_tone:'], + category: 'people', + }, + ':man_superhero_tone3:': { + uc_base: '1f9b8-1f3fd-2642', + uc_full: '1f9b8-1f3fd-200d-2642-fe0f', + shortnames: [':man_superhero_medium_skin_tone:'], + category: 'people', + }, + ':man_superhero_tone4:': { + uc_base: '1f9b8-1f3fe-2642', + uc_full: '1f9b8-1f3fe-200d-2642-fe0f', + shortnames: [':man_superhero_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_superhero_tone5:': { + uc_base: '1f9b8-1f3ff-2642', + uc_full: '1f9b8-1f3ff-200d-2642-fe0f', + shortnames: [':man_superhero_dark_skin_tone:'], + category: 'people', + }, + ':man_supervillain_tone1:': { + uc_base: '1f9b9-1f3fb-2642', + uc_full: '1f9b9-1f3fb-200d-2642-fe0f', + shortnames: [':man_supervillain_light_skin_tone:'], + category: 'people', + }, + ':man_supervillain_tone2:': { + uc_base: '1f9b9-1f3fc-2642', + uc_full: '1f9b9-1f3fc-200d-2642-fe0f', + shortnames: [':man_supervillain_medium_light_skin_tone:'], + category: 'people', + }, + ':man_supervillain_tone3:': { + uc_base: '1f9b9-1f3fd-2642', + uc_full: '1f9b9-1f3fd-200d-2642-fe0f', + shortnames: [':man_supervillain_medium_skin_tone:'], + category: 'people', + }, + ':man_supervillain_tone4:': { + uc_base: '1f9b9-1f3fe-2642', + uc_full: '1f9b9-1f3fe-200d-2642-fe0f', + shortnames: [':man_supervillain_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_supervillain_tone5:': { + uc_base: '1f9b9-1f3ff-2642', + uc_full: '1f9b9-1f3ff-200d-2642-fe0f', + shortnames: [':man_supervillain_dark_skin_tone:'], + category: 'people', + }, + ':man_surfing_tone1:': { + uc_base: '1f3c4-1f3fb-2642', + uc_full: '1f3c4-1f3fb-200d-2642-fe0f', + shortnames: [':man_surfing_light_skin_tone:'], + category: 'activity', + }, + ':man_surfing_tone2:': { + uc_base: '1f3c4-1f3fc-2642', + uc_full: '1f3c4-1f3fc-200d-2642-fe0f', + shortnames: [':man_surfing_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_surfing_tone3:': { + uc_base: '1f3c4-1f3fd-2642', + uc_full: '1f3c4-1f3fd-200d-2642-fe0f', + shortnames: [':man_surfing_medium_skin_tone:'], + category: 'activity', + }, + ':man_surfing_tone4:': { + uc_base: '1f3c4-1f3fe-2642', + uc_full: '1f3c4-1f3fe-200d-2642-fe0f', + shortnames: [':man_surfing_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_surfing_tone5:': { + uc_base: '1f3c4-1f3ff-2642', + uc_full: '1f3c4-1f3ff-200d-2642-fe0f', + shortnames: [':man_surfing_dark_skin_tone:'], + category: 'activity', + }, + ':man_swimming_tone1:': { + uc_base: '1f3ca-1f3fb-2642', + uc_full: '1f3ca-1f3fb-200d-2642-fe0f', + shortnames: [':man_swimming_light_skin_tone:'], + category: 'activity', + }, + ':man_swimming_tone2:': { + uc_base: '1f3ca-1f3fc-2642', + uc_full: '1f3ca-1f3fc-200d-2642-fe0f', + shortnames: [':man_swimming_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_swimming_tone3:': { + uc_base: '1f3ca-1f3fd-2642', + uc_full: '1f3ca-1f3fd-200d-2642-fe0f', + shortnames: [':man_swimming_medium_skin_tone:'], + category: 'activity', + }, + ':man_swimming_tone4:': { + uc_base: '1f3ca-1f3fe-2642', + uc_full: '1f3ca-1f3fe-200d-2642-fe0f', + shortnames: [':man_swimming_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_swimming_tone5:': { + uc_base: '1f3ca-1f3ff-2642', + uc_full: '1f3ca-1f3ff-200d-2642-fe0f', + shortnames: [':man_swimming_dark_skin_tone:'], + category: 'activity', + }, + ':man_tipping_hand_tone1:': { + uc_base: '1f481-1f3fb-2642', + uc_full: '1f481-1f3fb-200d-2642-fe0f', + shortnames: [':man_tipping_hand_light_skin_tone:'], + category: 'people', + }, + ':man_tipping_hand_tone2:': { + uc_base: '1f481-1f3fc-2642', + uc_full: '1f481-1f3fc-200d-2642-fe0f', + shortnames: [':man_tipping_hand_medium_light_skin_tone:'], + category: 'people', + }, + ':man_tipping_hand_tone3:': { + uc_base: '1f481-1f3fd-2642', + uc_full: '1f481-1f3fd-200d-2642-fe0f', + shortnames: [':man_tipping_hand_medium_skin_tone:'], + category: 'people', + }, + ':man_tipping_hand_tone4:': { + uc_base: '1f481-1f3fe-2642', + uc_full: '1f481-1f3fe-200d-2642-fe0f', + shortnames: [':man_tipping_hand_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_tipping_hand_tone5:': { + uc_base: '1f481-1f3ff-2642', + uc_full: '1f481-1f3ff-200d-2642-fe0f', + shortnames: [':man_tipping_hand_dark_skin_tone:'], + category: 'people', + }, + ':man_tone1_beard:': { + uc_base: '1f9d4-1f3fb-2642', + uc_full: '1f9d4-1f3fb-200d-2642-fe0f', + shortnames: [':man_light_skin_tone_beard:'], + category: 'people', + }, + ':man_tone2_beard:': { + uc_base: '1f9d4-1f3fc-2642', + uc_full: '1f9d4-1f3fc-200d-2642-fe0f', + shortnames: [':man_medium_light_skin_tone_beard:'], + category: 'people', + }, + ':man_tone3_beard:': { + uc_base: '1f9d4-1f3fd-2642', + uc_full: '1f9d4-1f3fd-200d-2642-fe0f', + shortnames: [':man_medium_skin_tone_beard:'], + category: 'people', + }, + ':man_tone4_beard:': { + uc_base: '1f9d4-1f3fe-2642', + uc_full: '1f9d4-1f3fe-200d-2642-fe0f', + shortnames: [':man_medium_dark_skin_tone_beard:'], + category: 'people', + }, + ':man_tone5_beard:': { + uc_base: '1f9d4-1f3ff-2642', + uc_full: '1f9d4-1f3ff-200d-2642-fe0f', + shortnames: [':man_dark_skin_tone_beard:'], + category: 'people', + }, + ':man_vampire_tone1:': { + uc_base: '1f9db-1f3fb-2642', + uc_full: '1f9db-1f3fb-200d-2642-fe0f', + shortnames: [':man_vampire_light_skin_tone:'], + category: 'people', + }, + ':man_vampire_tone2:': { + uc_base: '1f9db-1f3fc-2642', + uc_full: '1f9db-1f3fc-200d-2642-fe0f', + shortnames: [':man_vampire_medium_light_skin_tone:'], + category: 'people', + }, + ':man_vampire_tone3:': { + uc_base: '1f9db-1f3fd-2642', + uc_full: '1f9db-1f3fd-200d-2642-fe0f', + shortnames: [':man_vampire_medium_skin_tone:'], + category: 'people', + }, + ':man_vampire_tone4:': { + uc_base: '1f9db-1f3fe-2642', + uc_full: '1f9db-1f3fe-200d-2642-fe0f', + shortnames: [':man_vampire_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_vampire_tone5:': { + uc_base: '1f9db-1f3ff-2642', + uc_full: '1f9db-1f3ff-200d-2642-fe0f', + shortnames: [':man_vampire_dark_skin_tone:'], + category: 'people', + }, + ':man_walking_tone1:': { + uc_base: '1f6b6-1f3fb-2642', + uc_full: '1f6b6-1f3fb-200d-2642-fe0f', + shortnames: [':man_walking_light_skin_tone:'], + category: 'people', + }, + ':man_walking_tone2:': { + uc_base: '1f6b6-1f3fc-2642', + uc_full: '1f6b6-1f3fc-200d-2642-fe0f', + shortnames: [':man_walking_medium_light_skin_tone:'], + category: 'people', + }, + ':man_walking_tone3:': { + uc_base: '1f6b6-1f3fd-2642', + uc_full: '1f6b6-1f3fd-200d-2642-fe0f', + shortnames: [':man_walking_medium_skin_tone:'], + category: 'people', + }, + ':man_walking_tone4:': { + uc_base: '1f6b6-1f3fe-2642', + uc_full: '1f6b6-1f3fe-200d-2642-fe0f', + shortnames: [':man_walking_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_walking_tone5:': { + uc_base: '1f6b6-1f3ff-2642', + uc_full: '1f6b6-1f3ff-200d-2642-fe0f', + shortnames: [':man_walking_dark_skin_tone:'], + category: 'people', + }, + ':man_wearing_turban_tone1:': { + uc_base: '1f473-1f3fb-2642', + uc_full: '1f473-1f3fb-200d-2642-fe0f', + shortnames: [':man_wearing_turban_light_skin_tone:'], + category: 'people', + }, + ':man_wearing_turban_tone2:': { + uc_base: '1f473-1f3fc-2642', + uc_full: '1f473-1f3fc-200d-2642-fe0f', + shortnames: [':man_wearing_turban_medium_light_skin_tone:'], + category: 'people', + }, + ':man_wearing_turban_tone3:': { + uc_base: '1f473-1f3fd-2642', + uc_full: '1f473-1f3fd-200d-2642-fe0f', + shortnames: [':man_wearing_turban_medium_skin_tone:'], + category: 'people', + }, + ':man_wearing_turban_tone4:': { + uc_base: '1f473-1f3fe-2642', + uc_full: '1f473-1f3fe-200d-2642-fe0f', + shortnames: [':man_wearing_turban_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_wearing_turban_tone5:': { + uc_base: '1f473-1f3ff-2642', + uc_full: '1f473-1f3ff-200d-2642-fe0f', + shortnames: [':man_wearing_turban_dark_skin_tone:'], + category: 'people', + }, + ':man_with_veil_tone1:': { + uc_base: '1f470-1f3fb-2642', + uc_full: '1f470-1f3fb-200d-2642-fe0f', + shortnames: [':man_with_veil_light_skin_tone:'], + category: 'people', + }, + ':man_with_veil_tone2:': { + uc_base: '1f470-1f3fc-2642', + uc_full: '1f470-1f3fc-200d-2642-fe0f', + shortnames: [':man_with_veil_medium_light_skin_tone:'], + category: 'people', + }, + ':man_with_veil_tone3:': { + uc_base: '1f470-1f3fd-2642', + uc_full: '1f470-1f3fd-200d-2642-fe0f', + shortnames: [':man_with_veil_medium_skin_tone:'], + category: 'people', + }, + ':man_with_veil_tone4:': { + uc_base: '1f470-1f3fe-2642', + uc_full: '1f470-1f3fe-200d-2642-fe0f', + shortnames: [':man_with_veil_medium_dark_skin_tone:'], + category: 'people', + }, + ':man_with_veil_tone5:': { + uc_base: '1f470-1f3ff-2642', + uc_full: '1f470-1f3ff-200d-2642-fe0f', + shortnames: [':man_with_veil_dark_skin_tone:'], + category: 'people', + }, + ':mermaid_tone1:': { + uc_base: '1f9dc-1f3fb-2640', + uc_full: '1f9dc-1f3fb-200d-2640-fe0f', + shortnames: [':mermaid_light_skin_tone:'], + category: 'people', + }, + ':mermaid_tone2:': { + uc_base: '1f9dc-1f3fc-2640', + uc_full: '1f9dc-1f3fc-200d-2640-fe0f', + shortnames: [':mermaid_medium_light_skin_tone:'], + category: 'people', + }, + ':mermaid_tone3:': { + uc_base: '1f9dc-1f3fd-2640', + uc_full: '1f9dc-1f3fd-200d-2640-fe0f', + shortnames: [':mermaid_medium_skin_tone:'], + category: 'people', + }, + ':mermaid_tone4:': { + uc_base: '1f9dc-1f3fe-2640', + uc_full: '1f9dc-1f3fe-200d-2640-fe0f', + shortnames: [':mermaid_medium_dark_skin_tone:'], + category: 'people', + }, + ':mermaid_tone5:': { + uc_base: '1f9dc-1f3ff-2640', + uc_full: '1f9dc-1f3ff-200d-2640-fe0f', + shortnames: [':mermaid_dark_skin_tone:'], + category: 'people', + }, + ':merman_tone1:': { + uc_base: '1f9dc-1f3fb-2642', + uc_full: '1f9dc-1f3fb-200d-2642-fe0f', + shortnames: [':merman_light_skin_tone:'], + category: 'people', + }, + ':merman_tone2:': { + uc_base: '1f9dc-1f3fc-2642', + uc_full: '1f9dc-1f3fc-200d-2642-fe0f', + shortnames: [':merman_medium_light_skin_tone:'], + category: 'people', + }, + ':merman_tone3:': { + uc_base: '1f9dc-1f3fd-2642', + uc_full: '1f9dc-1f3fd-200d-2642-fe0f', + shortnames: [':merman_medium_skin_tone:'], + category: 'people', + }, + ':merman_tone4:': { + uc_base: '1f9dc-1f3fe-2642', + uc_full: '1f9dc-1f3fe-200d-2642-fe0f', + shortnames: [':merman_medium_dark_skin_tone:'], + category: 'people', + }, + ':merman_tone5:': { + uc_base: '1f9dc-1f3ff-2642', + uc_full: '1f9dc-1f3ff-200d-2642-fe0f', + shortnames: [':merman_dark_skin_tone:'], + category: 'people', + }, + ':pilot_tone1:': { + uc_base: '1f9d1-1f3fb-2708', + uc_full: '1f9d1-1f3fb-200d-2708-fe0f', + shortnames: [':pilot_light_skin_tone:'], + category: 'people', + }, + ':pilot_tone2:': { + uc_base: '1f9d1-1f3fc-2708', + uc_full: '1f9d1-1f3fc-200d-2708-fe0f', + shortnames: [':pilot_medium_light_skin_tone:'], + category: 'people', + }, + ':pilot_tone3:': { + uc_base: '1f9d1-1f3fd-2708', + uc_full: '1f9d1-1f3fd-200d-2708-fe0f', + shortnames: [':pilot_medium_skin_tone:'], + category: 'people', + }, + ':pilot_tone4:': { + uc_base: '1f9d1-1f3fe-2708', + uc_full: '1f9d1-1f3fe-200d-2708-fe0f', + shortnames: [':pilot_medium_dark_skin_tone:'], + category: 'people', + }, + ':pilot_tone5:': { + uc_base: '1f9d1-1f3ff-2708', + uc_full: '1f9d1-1f3ff-200d-2708-fe0f', + shortnames: [':pilot_dark_skin_tone:'], + category: 'people', + }, + ':woman_biking_tone1:': { + uc_base: '1f6b4-1f3fb-2640', + uc_full: '1f6b4-1f3fb-200d-2640-fe0f', + shortnames: [':woman_biking_light_skin_tone:'], + category: 'activity', + }, + ':woman_biking_tone2:': { + uc_base: '1f6b4-1f3fc-2640', + uc_full: '1f6b4-1f3fc-200d-2640-fe0f', + shortnames: [':woman_biking_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_biking_tone3:': { + uc_base: '1f6b4-1f3fd-2640', + uc_full: '1f6b4-1f3fd-200d-2640-fe0f', + shortnames: [':woman_biking_medium_skin_tone:'], + category: 'activity', + }, + ':woman_biking_tone4:': { + uc_base: '1f6b4-1f3fe-2640', + uc_full: '1f6b4-1f3fe-200d-2640-fe0f', + shortnames: [':woman_biking_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_biking_tone5:': { + uc_base: '1f6b4-1f3ff-2640', + uc_full: '1f6b4-1f3ff-200d-2640-fe0f', + shortnames: [':woman_biking_dark_skin_tone:'], + category: 'activity', + }, + ':woman_bowing_tone1:': { + uc_base: '1f647-1f3fb-2640', + uc_full: '1f647-1f3fb-200d-2640-fe0f', + shortnames: [':woman_bowing_light_skin_tone:'], + category: 'people', + }, + ':woman_bowing_tone2:': { + uc_base: '1f647-1f3fc-2640', + uc_full: '1f647-1f3fc-200d-2640-fe0f', + shortnames: [':woman_bowing_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_bowing_tone3:': { + uc_base: '1f647-1f3fd-2640', + uc_full: '1f647-1f3fd-200d-2640-fe0f', + shortnames: [':woman_bowing_medium_skin_tone:'], + category: 'people', + }, + ':woman_bowing_tone4:': { + uc_base: '1f647-1f3fe-2640', + uc_full: '1f647-1f3fe-200d-2640-fe0f', + shortnames: [':woman_bowing_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_bowing_tone5:': { + uc_base: '1f647-1f3ff-2640', + uc_full: '1f647-1f3ff-200d-2640-fe0f', + shortnames: [':woman_bowing_dark_skin_tone:'], + category: 'people', + }, + ':woman_cartwheeling_tone1:': { + uc_base: '1f938-1f3fb-2640', + uc_full: '1f938-1f3fb-200d-2640-fe0f', + shortnames: [':woman_cartwheeling_light_skin_tone:'], + category: 'activity', + }, + ':woman_cartwheeling_tone2:': { + uc_base: '1f938-1f3fc-2640', + uc_full: '1f938-1f3fc-200d-2640-fe0f', + shortnames: [':woman_cartwheeling_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_cartwheeling_tone3:': { + uc_base: '1f938-1f3fd-2640', + uc_full: '1f938-1f3fd-200d-2640-fe0f', + shortnames: [':woman_cartwheeling_medium_skin_tone:'], + category: 'activity', + }, + ':woman_cartwheeling_tone4:': { + uc_base: '1f938-1f3fe-2640', + uc_full: '1f938-1f3fe-200d-2640-fe0f', + shortnames: [':woman_cartwheeling_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_cartwheeling_tone5:': { + uc_base: '1f938-1f3ff-2640', + uc_full: '1f938-1f3ff-200d-2640-fe0f', + shortnames: [':woman_cartwheeling_dark_skin_tone:'], + category: 'activity', + }, + ':woman_climbing_tone1:': { + uc_base: '1f9d7-1f3fb-2640', + uc_full: '1f9d7-1f3fb-200d-2640-fe0f', + shortnames: [':woman_climbing_light_skin_tone:'], + category: 'activity', + }, + ':woman_climbing_tone2:': { + uc_base: '1f9d7-1f3fc-2640', + uc_full: '1f9d7-1f3fc-200d-2640-fe0f', + shortnames: [':woman_climbing_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_climbing_tone3:': { + uc_base: '1f9d7-1f3fd-2640', + uc_full: '1f9d7-1f3fd-200d-2640-fe0f', + shortnames: [':woman_climbing_medium_skin_tone:'], + category: 'activity', + }, + ':woman_climbing_tone4:': { + uc_base: '1f9d7-1f3fe-2640', + uc_full: '1f9d7-1f3fe-200d-2640-fe0f', + shortnames: [':woman_climbing_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_climbing_tone5:': { + uc_base: '1f9d7-1f3ff-2640', + uc_full: '1f9d7-1f3ff-200d-2640-fe0f', + shortnames: [':woman_climbing_dark_skin_tone:'], + category: 'activity', + }, + ':woman_construction_worker_tone1:': { + uc_base: '1f477-1f3fb-2640', + uc_full: '1f477-1f3fb-200d-2640-fe0f', + shortnames: [':woman_construction_worker_light_skin_tone:'], + category: 'people', + }, + ':woman_construction_worker_tone2:': { + uc_base: '1f477-1f3fc-2640', + uc_full: '1f477-1f3fc-200d-2640-fe0f', + shortnames: [':woman_construction_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_construction_worker_tone3:': { + uc_base: '1f477-1f3fd-2640', + uc_full: '1f477-1f3fd-200d-2640-fe0f', + shortnames: [':woman_construction_worker_medium_skin_tone:'], + category: 'people', + }, + ':woman_construction_worker_tone4:': { + uc_base: '1f477-1f3fe-2640', + uc_full: '1f477-1f3fe-200d-2640-fe0f', + shortnames: [':woman_construction_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_construction_worker_tone5:': { + uc_base: '1f477-1f3ff-2640', + uc_full: '1f477-1f3ff-200d-2640-fe0f', + shortnames: [':woman_construction_worker_dark_skin_tone:'], + category: 'people', + }, + ':woman_detective_tone1:': { + uc_base: '1f575-1f3fb-2640', + uc_full: '1f575-1f3fb-200d-2640-fe0f', + shortnames: [':woman_detective_light_skin_tone:'], + category: 'people', + }, + ':woman_detective_tone2:': { + uc_base: '1f575-1f3fc-2640', + uc_full: '1f575-1f3fc-200d-2640-fe0f', + shortnames: [':woman_detective_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_detective_tone3:': { + uc_base: '1f575-1f3fd-2640', + uc_full: '1f575-1f3fd-200d-2640-fe0f', + shortnames: [':woman_detective_medium_skin_tone:'], + category: 'people', + }, + ':woman_detective_tone4:': { + uc_base: '1f575-1f3fe-2640', + uc_full: '1f575-1f3fe-200d-2640-fe0f', + shortnames: [':woman_detective_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_detective_tone5:': { + uc_base: '1f575-1f3ff-2640', + uc_full: '1f575-1f3ff-200d-2640-fe0f', + shortnames: [':woman_detective_dark_skin_tone:'], + category: 'people', + }, + ':woman_elf_tone1:': { + uc_base: '1f9dd-1f3fb-2640', + uc_full: '1f9dd-1f3fb-200d-2640-fe0f', + shortnames: [':woman_elf_light_skin_tone:'], + category: 'people', + }, + ':woman_elf_tone2:': { + uc_base: '1f9dd-1f3fc-2640', + uc_full: '1f9dd-1f3fc-200d-2640-fe0f', + shortnames: [':woman_elf_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_elf_tone3:': { + uc_base: '1f9dd-1f3fd-2640', + uc_full: '1f9dd-1f3fd-200d-2640-fe0f', + shortnames: [':woman_elf_medium_skin_tone:'], + category: 'people', + }, + ':woman_elf_tone4:': { + uc_base: '1f9dd-1f3fe-2640', + uc_full: '1f9dd-1f3fe-200d-2640-fe0f', + shortnames: [':woman_elf_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_elf_tone5:': { + uc_base: '1f9dd-1f3ff-2640', + uc_full: '1f9dd-1f3ff-200d-2640-fe0f', + shortnames: [':woman_elf_dark_skin_tone:'], + category: 'people', + }, + ':woman_facepalming_tone1:': { + uc_base: '1f926-1f3fb-2640', + uc_full: '1f926-1f3fb-200d-2640-fe0f', + shortnames: [':woman_facepalming_light_skin_tone:'], + category: 'people', + }, + ':woman_facepalming_tone2:': { + uc_base: '1f926-1f3fc-2640', + uc_full: '1f926-1f3fc-200d-2640-fe0f', + shortnames: [':woman_facepalming_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_facepalming_tone3:': { + uc_base: '1f926-1f3fd-2640', + uc_full: '1f926-1f3fd-200d-2640-fe0f', + shortnames: [':woman_facepalming_medium_skin_tone:'], + category: 'people', + }, + ':woman_facepalming_tone4:': { + uc_base: '1f926-1f3fe-2640', + uc_full: '1f926-1f3fe-200d-2640-fe0f', + shortnames: [':woman_facepalming_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_facepalming_tone5:': { + uc_base: '1f926-1f3ff-2640', + uc_full: '1f926-1f3ff-200d-2640-fe0f', + shortnames: [':woman_facepalming_dark_skin_tone:'], + category: 'people', + }, + ':woman_fairy_tone1:': { + uc_base: '1f9da-1f3fb-2640', + uc_full: '1f9da-1f3fb-200d-2640-fe0f', + shortnames: [':woman_fairy_light_skin_tone:'], + category: 'people', + }, + ':woman_fairy_tone2:': { + uc_base: '1f9da-1f3fc-2640', + uc_full: '1f9da-1f3fc-200d-2640-fe0f', + shortnames: [':woman_fairy_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_fairy_tone3:': { + uc_base: '1f9da-1f3fd-2640', + uc_full: '1f9da-1f3fd-200d-2640-fe0f', + shortnames: [':woman_fairy_medium_skin_tone:'], + category: 'people', + }, + ':woman_fairy_tone4:': { + uc_base: '1f9da-1f3fe-2640', + uc_full: '1f9da-1f3fe-200d-2640-fe0f', + shortnames: [':woman_fairy_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_fairy_tone5:': { + uc_base: '1f9da-1f3ff-2640', + uc_full: '1f9da-1f3ff-200d-2640-fe0f', + shortnames: [':woman_fairy_dark_skin_tone:'], + category: 'people', + }, + ':woman_frowning_tone1:': { + uc_base: '1f64d-1f3fb-2640', + uc_full: '1f64d-1f3fb-200d-2640-fe0f', + shortnames: [':woman_frowning_light_skin_tone:'], + category: 'people', + }, + ':woman_frowning_tone2:': { + uc_base: '1f64d-1f3fc-2640', + uc_full: '1f64d-1f3fc-200d-2640-fe0f', + shortnames: [':woman_frowning_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_frowning_tone3:': { + uc_base: '1f64d-1f3fd-2640', + uc_full: '1f64d-1f3fd-200d-2640-fe0f', + shortnames: [':woman_frowning_medium_skin_tone:'], + category: 'people', + }, + ':woman_frowning_tone4:': { + uc_base: '1f64d-1f3fe-2640', + uc_full: '1f64d-1f3fe-200d-2640-fe0f', + shortnames: [':woman_frowning_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_frowning_tone5:': { + uc_base: '1f64d-1f3ff-2640', + uc_full: '1f64d-1f3ff-200d-2640-fe0f', + shortnames: [':woman_frowning_dark_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_no_tone1:': { + uc_base: '1f645-1f3fb-2640', + uc_full: '1f645-1f3fb-200d-2640-fe0f', + shortnames: [':woman_gesturing_no_light_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_no_tone2:': { + uc_base: '1f645-1f3fc-2640', + uc_full: '1f645-1f3fc-200d-2640-fe0f', + shortnames: [':woman_gesturing_no_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_no_tone3:': { + uc_base: '1f645-1f3fd-2640', + uc_full: '1f645-1f3fd-200d-2640-fe0f', + shortnames: [':woman_gesturing_no_medium_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_no_tone4:': { + uc_base: '1f645-1f3fe-2640', + uc_full: '1f645-1f3fe-200d-2640-fe0f', + shortnames: [':woman_gesturing_no_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_no_tone5:': { + uc_base: '1f645-1f3ff-2640', + uc_full: '1f645-1f3ff-200d-2640-fe0f', + shortnames: [':woman_gesturing_no_dark_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_ok_tone1:': { + uc_base: '1f646-1f3fb-2640', + uc_full: '1f646-1f3fb-200d-2640-fe0f', + shortnames: [':woman_gesturing_ok_light_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_ok_tone2:': { + uc_base: '1f646-1f3fc-2640', + uc_full: '1f646-1f3fc-200d-2640-fe0f', + shortnames: [':woman_gesturing_ok_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_ok_tone3:': { + uc_base: '1f646-1f3fd-2640', + uc_full: '1f646-1f3fd-200d-2640-fe0f', + shortnames: [':woman_gesturing_ok_medium_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_ok_tone4:': { + uc_base: '1f646-1f3fe-2640', + uc_full: '1f646-1f3fe-200d-2640-fe0f', + shortnames: [':woman_gesturing_ok_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_gesturing_ok_tone5:': { + uc_base: '1f646-1f3ff-2640', + uc_full: '1f646-1f3ff-200d-2640-fe0f', + shortnames: [':woman_gesturing_ok_dark_skin_tone:'], + category: 'people', + }, + ':woman_getting_face_massage_tone1:': { + uc_base: '1f486-1f3fb-2640', + uc_full: '1f486-1f3fb-200d-2640-fe0f', + shortnames: [':woman_getting_face_massage_light_skin_tone:'], + category: 'people', + }, + ':woman_getting_face_massage_tone2:': { + uc_base: '1f486-1f3fc-2640', + uc_full: '1f486-1f3fc-200d-2640-fe0f', + shortnames: [':woman_getting_face_massage_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_getting_face_massage_tone3:': { + uc_base: '1f486-1f3fd-2640', + uc_full: '1f486-1f3fd-200d-2640-fe0f', + shortnames: [':woman_getting_face_massage_medium_skin_tone:'], + category: 'people', + }, + ':woman_getting_face_massage_tone4:': { + uc_base: '1f486-1f3fe-2640', + uc_full: '1f486-1f3fe-200d-2640-fe0f', + shortnames: [':woman_getting_face_massage_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_getting_face_massage_tone5:': { + uc_base: '1f486-1f3ff-2640', + uc_full: '1f486-1f3ff-200d-2640-fe0f', + shortnames: [':woman_getting_face_massage_dark_skin_tone:'], + category: 'people', + }, + ':woman_getting_haircut_tone1:': { + uc_base: '1f487-1f3fb-2640', + uc_full: '1f487-1f3fb-200d-2640-fe0f', + shortnames: [':woman_getting_haircut_light_skin_tone:'], + category: 'people', + }, + ':woman_getting_haircut_tone2:': { + uc_base: '1f487-1f3fc-2640', + uc_full: '1f487-1f3fc-200d-2640-fe0f', + shortnames: [':woman_getting_haircut_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_getting_haircut_tone3:': { + uc_base: '1f487-1f3fd-2640', + uc_full: '1f487-1f3fd-200d-2640-fe0f', + shortnames: [':woman_getting_haircut_medium_skin_tone:'], + category: 'people', + }, + ':woman_getting_haircut_tone4:': { + uc_base: '1f487-1f3fe-2640', + uc_full: '1f487-1f3fe-200d-2640-fe0f', + shortnames: [':woman_getting_haircut_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_getting_haircut_tone5:': { + uc_base: '1f487-1f3ff-2640', + uc_full: '1f487-1f3ff-200d-2640-fe0f', + shortnames: [':woman_getting_haircut_dark_skin_tone:'], + category: 'people', + }, + ':woman_golfing_tone1:': { + uc_base: '1f3cc-1f3fb-2640', + uc_full: '1f3cc-1f3fb-200d-2640-fe0f', + shortnames: [':woman_golfing_light_skin_tone:'], + category: 'activity', + }, + ':woman_golfing_tone2:': { + uc_base: '1f3cc-1f3fc-2640', + uc_full: '1f3cc-1f3fc-200d-2640-fe0f', + shortnames: [':woman_golfing_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_golfing_tone3:': { + uc_base: '1f3cc-1f3fd-2640', + uc_full: '1f3cc-1f3fd-200d-2640-fe0f', + shortnames: [':woman_golfing_medium_skin_tone:'], + category: 'activity', + }, + ':woman_golfing_tone4:': { + uc_base: '1f3cc-1f3fe-2640', + uc_full: '1f3cc-1f3fe-200d-2640-fe0f', + shortnames: [':woman_golfing_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_golfing_tone5:': { + uc_base: '1f3cc-1f3ff-2640', + uc_full: '1f3cc-1f3ff-200d-2640-fe0f', + shortnames: [':woman_golfing_dark_skin_tone:'], + category: 'activity', + }, + ':woman_guard_tone1:': { + uc_base: '1f482-1f3fb-2640', + uc_full: '1f482-1f3fb-200d-2640-fe0f', + shortnames: [':woman_guard_light_skin_tone:'], + category: 'people', + }, + ':woman_guard_tone2:': { + uc_base: '1f482-1f3fc-2640', + uc_full: '1f482-1f3fc-200d-2640-fe0f', + shortnames: [':woman_guard_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_guard_tone3:': { + uc_base: '1f482-1f3fd-2640', + uc_full: '1f482-1f3fd-200d-2640-fe0f', + shortnames: [':woman_guard_medium_skin_tone:'], + category: 'people', + }, + ':woman_guard_tone4:': { + uc_base: '1f482-1f3fe-2640', + uc_full: '1f482-1f3fe-200d-2640-fe0f', + shortnames: [':woman_guard_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_guard_tone5:': { + uc_base: '1f482-1f3ff-2640', + uc_full: '1f482-1f3ff-200d-2640-fe0f', + shortnames: [':woman_guard_dark_skin_tone:'], + category: 'people', + }, + ':woman_health_worker_tone1:': { + uc_base: '1f469-1f3fb-2695', + uc_full: '1f469-1f3fb-200d-2695-fe0f', + shortnames: [':woman_health_worker_light_skin_tone:'], + category: 'people', + }, + ':woman_health_worker_tone2:': { + uc_base: '1f469-1f3fc-2695', + uc_full: '1f469-1f3fc-200d-2695-fe0f', + shortnames: [':woman_health_worker_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_health_worker_tone3:': { + uc_base: '1f469-1f3fd-2695', + uc_full: '1f469-1f3fd-200d-2695-fe0f', + shortnames: [':woman_health_worker_medium_skin_tone:'], + category: 'people', + }, + ':woman_health_worker_tone4:': { + uc_base: '1f469-1f3fe-2695', + uc_full: '1f469-1f3fe-200d-2695-fe0f', + shortnames: [':woman_health_worker_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_health_worker_tone5:': { + uc_base: '1f469-1f3ff-2695', + uc_full: '1f469-1f3ff-200d-2695-fe0f', + shortnames: [':woman_health_worker_dark_skin_tone:'], + category: 'people', + }, + ':woman_in_lotus_position_tone1:': { + uc_base: '1f9d8-1f3fb-2640', + uc_full: '1f9d8-1f3fb-200d-2640-fe0f', + shortnames: [':woman_in_lotus_position_light_skin_tone:'], + category: 'activity', + }, + ':woman_in_lotus_position_tone2:': { + uc_base: '1f9d8-1f3fc-2640', + uc_full: '1f9d8-1f3fc-200d-2640-fe0f', + shortnames: [':woman_in_lotus_position_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_in_lotus_position_tone3:': { + uc_base: '1f9d8-1f3fd-2640', + uc_full: '1f9d8-1f3fd-200d-2640-fe0f', + shortnames: [':woman_in_lotus_position_medium_skin_tone:'], + category: 'activity', + }, + ':woman_in_lotus_position_tone4:': { + uc_base: '1f9d8-1f3fe-2640', + uc_full: '1f9d8-1f3fe-200d-2640-fe0f', + shortnames: [':woman_in_lotus_position_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_in_lotus_position_tone5:': { + uc_base: '1f9d8-1f3ff-2640', + uc_full: '1f9d8-1f3ff-200d-2640-fe0f', + shortnames: [':woman_in_lotus_position_dark_skin_tone:'], + category: 'activity', + }, + ':woman_in_steamy_room_tone1:': { + uc_base: '1f9d6-1f3fb-2640', + uc_full: '1f9d6-1f3fb-200d-2640-fe0f', + shortnames: [':woman_in_steamy_room_light_skin_tone:'], + category: 'people', + }, + ':woman_in_steamy_room_tone2:': { + uc_base: '1f9d6-1f3fc-2640', + uc_full: '1f9d6-1f3fc-200d-2640-fe0f', + shortnames: [':woman_in_steamy_room_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_in_steamy_room_tone3:': { + uc_base: '1f9d6-1f3fd-2640', + uc_full: '1f9d6-1f3fd-200d-2640-fe0f', + shortnames: [':woman_in_steamy_room_medium_skin_tone:'], + category: 'people', + }, + ':woman_in_steamy_room_tone4:': { + uc_base: '1f9d6-1f3fe-2640', + uc_full: '1f9d6-1f3fe-200d-2640-fe0f', + shortnames: [':woman_in_steamy_room_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_in_steamy_room_tone5:': { + uc_base: '1f9d6-1f3ff-2640', + uc_full: '1f9d6-1f3ff-200d-2640-fe0f', + shortnames: [':woman_in_steamy_room_dark_skin_tone:'], + category: 'people', + }, + ':woman_in_tuxedo_tone1:': { + uc_base: '1f935-1f3fb-2640', + uc_full: '1f935-1f3fb-200d-2640-fe0f', + shortnames: [':woman_in_tuxedo_light_skin_tone:'], + category: 'people', + }, + ':woman_in_tuxedo_tone2:': { + uc_base: '1f935-1f3fc-2640', + uc_full: '1f935-1f3fc-200d-2640-fe0f', + shortnames: [':woman_in_tuxedo_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_in_tuxedo_tone3:': { + uc_base: '1f935-1f3fd-2640', + uc_full: '1f935-1f3fd-200d-2640-fe0f', + shortnames: [':woman_in_tuxedo_medium_skin_tone:'], + category: 'people', + }, + ':woman_in_tuxedo_tone4:': { + uc_base: '1f935-1f3fe-2640', + uc_full: '1f935-1f3fe-200d-2640-fe0f', + shortnames: [':woman_in_tuxedo_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_in_tuxedo_tone5:': { + uc_base: '1f935-1f3ff-2640', + uc_full: '1f935-1f3ff-200d-2640-fe0f', + shortnames: [':woman_in_tuxedo_dark_skin_tone:'], + category: 'people', + }, + ':woman_judge_tone1:': { + uc_base: '1f469-1f3fb-2696', + uc_full: '1f469-1f3fb-200d-2696-fe0f', + shortnames: [':woman_judge_light_skin_tone:'], + category: 'people', + }, + ':woman_judge_tone2:': { + uc_base: '1f469-1f3fc-2696', + uc_full: '1f469-1f3fc-200d-2696-fe0f', + shortnames: [':woman_judge_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_judge_tone3:': { + uc_base: '1f469-1f3fd-2696', + uc_full: '1f469-1f3fd-200d-2696-fe0f', + shortnames: [':woman_judge_medium_skin_tone:'], + category: 'people', + }, + ':woman_judge_tone4:': { + uc_base: '1f469-1f3fe-2696', + uc_full: '1f469-1f3fe-200d-2696-fe0f', + shortnames: [':woman_judge_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_judge_tone5:': { + uc_base: '1f469-1f3ff-2696', + uc_full: '1f469-1f3ff-200d-2696-fe0f', + shortnames: [':woman_judge_dark_skin_tone:'], + category: 'people', + }, + ':woman_juggling_tone1:': { + uc_base: '1f939-1f3fb-2640', + uc_full: '1f939-1f3fb-200d-2640-fe0f', + shortnames: [':woman_juggling_light_skin_tone:'], + category: 'activity', + }, + ':woman_juggling_tone2:': { + uc_base: '1f939-1f3fc-2640', + uc_full: '1f939-1f3fc-200d-2640-fe0f', + shortnames: [':woman_juggling_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_juggling_tone3:': { + uc_base: '1f939-1f3fd-2640', + uc_full: '1f939-1f3fd-200d-2640-fe0f', + shortnames: [':woman_juggling_medium_skin_tone:'], + category: 'activity', + }, + ':woman_juggling_tone4:': { + uc_base: '1f939-1f3fe-2640', + uc_full: '1f939-1f3fe-200d-2640-fe0f', + shortnames: [':woman_juggling_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_juggling_tone5:': { + uc_base: '1f939-1f3ff-2640', + uc_full: '1f939-1f3ff-200d-2640-fe0f', + shortnames: [':woman_juggling_dark_skin_tone:'], + category: 'activity', + }, + ':woman_kneeling_tone1:': { + uc_base: '1f9ce-1f3fb-2640', + uc_full: '1f9ce-1f3fb-200d-2640-fe0f', + shortnames: [':woman_kneeling_light_skin_tone:'], + category: 'people', + }, + ':woman_kneeling_tone2:': { + uc_base: '1f9ce-1f3fc-2640', + uc_full: '1f9ce-1f3fc-200d-2640-fe0f', + shortnames: [':woman_kneeling_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_kneeling_tone3:': { + uc_base: '1f9ce-1f3fd-2640', + uc_full: '1f9ce-1f3fd-200d-2640-fe0f', + shortnames: [':woman_kneeling_medium_skin_tone:'], + category: 'people', + }, + ':woman_kneeling_tone4:': { + uc_base: '1f9ce-1f3fe-2640', + uc_full: '1f9ce-1f3fe-200d-2640-fe0f', + shortnames: [':woman_kneeling_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_kneeling_tone5:': { + uc_base: '1f9ce-1f3ff-2640', + uc_full: '1f9ce-1f3ff-200d-2640-fe0f', + shortnames: [':woman_kneeling_dark_skin_tone:'], + category: 'people', + }, + ':woman_lifting_weights_tone1:': { + uc_base: '1f3cb-1f3fb-2640', + uc_full: '1f3cb-1f3fb-200d-2640-fe0f', + shortnames: [':woman_lifting_weights_light_skin_tone:'], + category: 'activity', + }, + ':woman_lifting_weights_tone2:': { + uc_base: '1f3cb-1f3fc-2640', + uc_full: '1f3cb-1f3fc-200d-2640-fe0f', + shortnames: [':woman_lifting_weights_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_lifting_weights_tone3:': { + uc_base: '1f3cb-1f3fd-2640', + uc_full: '1f3cb-1f3fd-200d-2640-fe0f', + shortnames: [':woman_lifting_weights_medium_skin_tone:'], + category: 'activity', + }, + ':woman_lifting_weights_tone4:': { + uc_base: '1f3cb-1f3fe-2640', + uc_full: '1f3cb-1f3fe-200d-2640-fe0f', + shortnames: [':woman_lifting_weights_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_lifting_weights_tone5:': { + uc_base: '1f3cb-1f3ff-2640', + uc_full: '1f3cb-1f3ff-200d-2640-fe0f', + shortnames: [':woman_lifting_weights_dark_skin_tone:'], + category: 'activity', + }, + ':woman_mage_tone1:': { + uc_base: '1f9d9-1f3fb-2640', + uc_full: '1f9d9-1f3fb-200d-2640-fe0f', + shortnames: [':woman_mage_light_skin_tone:'], + category: 'people', + }, + ':woman_mage_tone2:': { + uc_base: '1f9d9-1f3fc-2640', + uc_full: '1f9d9-1f3fc-200d-2640-fe0f', + shortnames: [':woman_mage_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_mage_tone3:': { + uc_base: '1f9d9-1f3fd-2640', + uc_full: '1f9d9-1f3fd-200d-2640-fe0f', + shortnames: [':woman_mage_medium_skin_tone:'], + category: 'people', + }, + ':woman_mage_tone4:': { + uc_base: '1f9d9-1f3fe-2640', + uc_full: '1f9d9-1f3fe-200d-2640-fe0f', + shortnames: [':woman_mage_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_mage_tone5:': { + uc_base: '1f9d9-1f3ff-2640', + uc_full: '1f9d9-1f3ff-200d-2640-fe0f', + shortnames: [':woman_mage_dark_skin_tone:'], + category: 'people', + }, + ':woman_mountain_biking_tone1:': { + uc_base: '1f6b5-1f3fb-2640', + uc_full: '1f6b5-1f3fb-200d-2640-fe0f', + shortnames: [':woman_mountain_biking_light_skin_tone:'], + category: 'activity', + }, + ':woman_mountain_biking_tone2:': { + uc_base: '1f6b5-1f3fc-2640', + uc_full: '1f6b5-1f3fc-200d-2640-fe0f', + shortnames: [':woman_mountain_biking_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_mountain_biking_tone3:': { + uc_base: '1f6b5-1f3fd-2640', + uc_full: '1f6b5-1f3fd-200d-2640-fe0f', + shortnames: [':woman_mountain_biking_medium_skin_tone:'], + category: 'activity', + }, + ':woman_mountain_biking_tone4:': { + uc_base: '1f6b5-1f3fe-2640', + uc_full: '1f6b5-1f3fe-200d-2640-fe0f', + shortnames: [':woman_mountain_biking_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_mountain_biking_tone5:': { + uc_base: '1f6b5-1f3ff-2640', + uc_full: '1f6b5-1f3ff-200d-2640-fe0f', + shortnames: [':woman_mountain_biking_dark_skin_tone:'], + category: 'activity', + }, + ':woman_pilot_tone1:': { + uc_base: '1f469-1f3fb-2708', + uc_full: '1f469-1f3fb-200d-2708-fe0f', + shortnames: [':woman_pilot_light_skin_tone:'], + category: 'people', + }, + ':woman_pilot_tone2:': { + uc_base: '1f469-1f3fc-2708', + uc_full: '1f469-1f3fc-200d-2708-fe0f', + shortnames: [':woman_pilot_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_pilot_tone3:': { + uc_base: '1f469-1f3fd-2708', + uc_full: '1f469-1f3fd-200d-2708-fe0f', + shortnames: [':woman_pilot_medium_skin_tone:'], + category: 'people', + }, + ':woman_pilot_tone4:': { + uc_base: '1f469-1f3fe-2708', + uc_full: '1f469-1f3fe-200d-2708-fe0f', + shortnames: [':woman_pilot_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_pilot_tone5:': { + uc_base: '1f469-1f3ff-2708', + uc_full: '1f469-1f3ff-200d-2708-fe0f', + shortnames: [':woman_pilot_dark_skin_tone:'], + category: 'people', + }, + ':woman_playing_handball_tone1:': { + uc_base: '1f93e-1f3fb-2640', + uc_full: '1f93e-1f3fb-200d-2640-fe0f', + shortnames: [':woman_playing_handball_light_skin_tone:'], + category: 'activity', + }, + ':woman_playing_handball_tone2:': { + uc_base: '1f93e-1f3fc-2640', + uc_full: '1f93e-1f3fc-200d-2640-fe0f', + shortnames: [':woman_playing_handball_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_playing_handball_tone3:': { + uc_base: '1f93e-1f3fd-2640', + uc_full: '1f93e-1f3fd-200d-2640-fe0f', + shortnames: [':woman_playing_handball_medium_skin_tone:'], + category: 'activity', + }, + ':woman_playing_handball_tone4:': { + uc_base: '1f93e-1f3fe-2640', + uc_full: '1f93e-1f3fe-200d-2640-fe0f', + shortnames: [':woman_playing_handball_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_playing_handball_tone5:': { + uc_base: '1f93e-1f3ff-2640', + uc_full: '1f93e-1f3ff-200d-2640-fe0f', + shortnames: [':woman_playing_handball_dark_skin_tone:'], + category: 'activity', + }, + ':woman_playing_water_polo_tone1:': { + uc_base: '1f93d-1f3fb-2640', + uc_full: '1f93d-1f3fb-200d-2640-fe0f', + shortnames: [':woman_playing_water_polo_light_skin_tone:'], + category: 'activity', + }, + ':woman_playing_water_polo_tone2:': { + uc_base: '1f93d-1f3fc-2640', + uc_full: '1f93d-1f3fc-200d-2640-fe0f', + shortnames: [':woman_playing_water_polo_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_playing_water_polo_tone3:': { + uc_base: '1f93d-1f3fd-2640', + uc_full: '1f93d-1f3fd-200d-2640-fe0f', + shortnames: [':woman_playing_water_polo_medium_skin_tone:'], + category: 'activity', + }, + ':woman_playing_water_polo_tone4:': { + uc_base: '1f93d-1f3fe-2640', + uc_full: '1f93d-1f3fe-200d-2640-fe0f', + shortnames: [':woman_playing_water_polo_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_playing_water_polo_tone5:': { + uc_base: '1f93d-1f3ff-2640', + uc_full: '1f93d-1f3ff-200d-2640-fe0f', + shortnames: [':woman_playing_water_polo_dark_skin_tone:'], + category: 'activity', + }, + ':woman_police_officer_tone1:': { + uc_base: '1f46e-1f3fb-2640', + uc_full: '1f46e-1f3fb-200d-2640-fe0f', + shortnames: [':woman_police_officer_light_skin_tone:'], + category: 'people', + }, + ':woman_police_officer_tone2:': { + uc_base: '1f46e-1f3fc-2640', + uc_full: '1f46e-1f3fc-200d-2640-fe0f', + shortnames: [':woman_police_officer_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_police_officer_tone3:': { + uc_base: '1f46e-1f3fd-2640', + uc_full: '1f46e-1f3fd-200d-2640-fe0f', + shortnames: [':woman_police_officer_medium_skin_tone:'], + category: 'people', + }, + ':woman_police_officer_tone4:': { + uc_base: '1f46e-1f3fe-2640', + uc_full: '1f46e-1f3fe-200d-2640-fe0f', + shortnames: [':woman_police_officer_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_police_officer_tone5:': { + uc_base: '1f46e-1f3ff-2640', + uc_full: '1f46e-1f3ff-200d-2640-fe0f', + shortnames: [':woman_police_officer_dark_skin_tone:'], + category: 'people', + }, + ':woman_pouting_tone1:': { + uc_base: '1f64e-1f3fb-2640', + uc_full: '1f64e-1f3fb-200d-2640-fe0f', + shortnames: [':woman_pouting_light_skin_tone:'], + category: 'people', + }, + ':woman_pouting_tone2:': { + uc_base: '1f64e-1f3fc-2640', + uc_full: '1f64e-1f3fc-200d-2640-fe0f', + shortnames: [':woman_pouting_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_pouting_tone3:': { + uc_base: '1f64e-1f3fd-2640', + uc_full: '1f64e-1f3fd-200d-2640-fe0f', + shortnames: [':woman_pouting_medium_skin_tone:'], + category: 'people', + }, + ':woman_pouting_tone4:': { + uc_base: '1f64e-1f3fe-2640', + uc_full: '1f64e-1f3fe-200d-2640-fe0f', + shortnames: [':woman_pouting_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_pouting_tone5:': { + uc_base: '1f64e-1f3ff-2640', + uc_full: '1f64e-1f3ff-200d-2640-fe0f', + shortnames: [':woman_pouting_dark_skin_tone:'], + category: 'people', + }, + ':woman_raising_hand_tone1:': { + uc_base: '1f64b-1f3fb-2640', + uc_full: '1f64b-1f3fb-200d-2640-fe0f', + shortnames: [':woman_raising_hand_light_skin_tone:'], + category: 'people', + }, + ':woman_raising_hand_tone2:': { + uc_base: '1f64b-1f3fc-2640', + uc_full: '1f64b-1f3fc-200d-2640-fe0f', + shortnames: [':woman_raising_hand_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_raising_hand_tone3:': { + uc_base: '1f64b-1f3fd-2640', + uc_full: '1f64b-1f3fd-200d-2640-fe0f', + shortnames: [':woman_raising_hand_medium_skin_tone:'], + category: 'people', + }, + ':woman_raising_hand_tone4:': { + uc_base: '1f64b-1f3fe-2640', + uc_full: '1f64b-1f3fe-200d-2640-fe0f', + shortnames: [':woman_raising_hand_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_raising_hand_tone5:': { + uc_base: '1f64b-1f3ff-2640', + uc_full: '1f64b-1f3ff-200d-2640-fe0f', + shortnames: [':woman_raising_hand_dark_skin_tone:'], + category: 'people', + }, + ':woman_rowing_boat_tone1:': { + uc_base: '1f6a3-1f3fb-2640', + uc_full: '1f6a3-1f3fb-200d-2640-fe0f', + shortnames: [':woman_rowing_boat_light_skin_tone:'], + category: 'activity', + }, + ':woman_rowing_boat_tone2:': { + uc_base: '1f6a3-1f3fc-2640', + uc_full: '1f6a3-1f3fc-200d-2640-fe0f', + shortnames: [':woman_rowing_boat_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_rowing_boat_tone3:': { + uc_base: '1f6a3-1f3fd-2640', + uc_full: '1f6a3-1f3fd-200d-2640-fe0f', + shortnames: [':woman_rowing_boat_medium_skin_tone:'], + category: 'activity', + }, + ':woman_rowing_boat_tone4:': { + uc_base: '1f6a3-1f3fe-2640', + uc_full: '1f6a3-1f3fe-200d-2640-fe0f', + shortnames: [':woman_rowing_boat_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_rowing_boat_tone5:': { + uc_base: '1f6a3-1f3ff-2640', + uc_full: '1f6a3-1f3ff-200d-2640-fe0f', + shortnames: [':woman_rowing_boat_dark_skin_tone:'], + category: 'activity', + }, + ':woman_running_tone1:': { + uc_base: '1f3c3-1f3fb-2640', + uc_full: '1f3c3-1f3fb-200d-2640-fe0f', + shortnames: [':woman_running_light_skin_tone:'], + category: 'people', + }, + ':woman_running_tone2:': { + uc_base: '1f3c3-1f3fc-2640', + uc_full: '1f3c3-1f3fc-200d-2640-fe0f', + shortnames: [':woman_running_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_running_tone3:': { + uc_base: '1f3c3-1f3fd-2640', + uc_full: '1f3c3-1f3fd-200d-2640-fe0f', + shortnames: [':woman_running_medium_skin_tone:'], + category: 'people', + }, + ':woman_running_tone4:': { + uc_base: '1f3c3-1f3fe-2640', + uc_full: '1f3c3-1f3fe-200d-2640-fe0f', + shortnames: [':woman_running_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_running_tone5:': { + uc_base: '1f3c3-1f3ff-2640', + uc_full: '1f3c3-1f3ff-200d-2640-fe0f', + shortnames: [':woman_running_dark_skin_tone:'], + category: 'people', + }, + ':woman_shrugging_tone1:': { + uc_base: '1f937-1f3fb-2640', + uc_full: '1f937-1f3fb-200d-2640-fe0f', + shortnames: [':woman_shrugging_light_skin_tone:'], + category: 'people', + }, + ':woman_shrugging_tone2:': { + uc_base: '1f937-1f3fc-2640', + uc_full: '1f937-1f3fc-200d-2640-fe0f', + shortnames: [':woman_shrugging_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_shrugging_tone3:': { + uc_base: '1f937-1f3fd-2640', + uc_full: '1f937-1f3fd-200d-2640-fe0f', + shortnames: [':woman_shrugging_medium_skin_tone:'], + category: 'people', + }, + ':woman_shrugging_tone4:': { + uc_base: '1f937-1f3fe-2640', + uc_full: '1f937-1f3fe-200d-2640-fe0f', + shortnames: [':woman_shrugging_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_shrugging_tone5:': { + uc_base: '1f937-1f3ff-2640', + uc_full: '1f937-1f3ff-200d-2640-fe0f', + shortnames: [':woman_shrugging_dark_skin_tone:'], + category: 'people', + }, + ':woman_standing_tone1:': { + uc_base: '1f9cd-1f3fb-2640', + uc_full: '1f9cd-1f3fb-200d-2640-fe0f', + shortnames: [':woman_standing_light_skin_tone:'], + category: 'people', + }, + ':woman_standing_tone2:': { + uc_base: '1f9cd-1f3fc-2640', + uc_full: '1f9cd-1f3fc-200d-2640-fe0f', + shortnames: [':woman_standing_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_standing_tone3:': { + uc_base: '1f9cd-1f3fd-2640', + uc_full: '1f9cd-1f3fd-200d-2640-fe0f', + shortnames: [':woman_standing_medium_skin_tone:'], + category: 'people', + }, + ':woman_standing_tone4:': { + uc_base: '1f9cd-1f3fe-2640', + uc_full: '1f9cd-1f3fe-200d-2640-fe0f', + shortnames: [':woman_standing_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_standing_tone5:': { + uc_base: '1f9cd-1f3ff-2640', + uc_full: '1f9cd-1f3ff-200d-2640-fe0f', + shortnames: [':woman_standing_dark_skin_tone:'], + category: 'people', + }, + ':woman_superhero_tone1:': { + uc_base: '1f9b8-1f3fb-2640', + uc_full: '1f9b8-1f3fb-200d-2640-fe0f', + shortnames: [':woman_superhero_light_skin_tone:'], + category: 'people', + }, + ':woman_superhero_tone2:': { + uc_base: '1f9b8-1f3fc-2640', + uc_full: '1f9b8-1f3fc-200d-2640-fe0f', + shortnames: [':woman_superhero_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_superhero_tone3:': { + uc_base: '1f9b8-1f3fd-2640', + uc_full: '1f9b8-1f3fd-200d-2640-fe0f', + shortnames: [':woman_superhero_medium_skin_tone:'], + category: 'people', + }, + ':woman_superhero_tone4:': { + uc_base: '1f9b8-1f3fe-2640', + uc_full: '1f9b8-1f3fe-200d-2640-fe0f', + shortnames: [':woman_superhero_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_superhero_tone5:': { + uc_base: '1f9b8-1f3ff-2640', + uc_full: '1f9b8-1f3ff-200d-2640-fe0f', + shortnames: [':woman_superhero_dark_skin_tone:'], + category: 'people', + }, + ':woman_supervillain_tone1:': { + uc_base: '1f9b9-1f3fb-2640', + uc_full: '1f9b9-1f3fb-200d-2640-fe0f', + shortnames: [':woman_supervillain_light_skin_tone:'], + category: 'people', + }, + ':woman_supervillain_tone2:': { + uc_base: '1f9b9-1f3fc-2640', + uc_full: '1f9b9-1f3fc-200d-2640-fe0f', + shortnames: [':woman_supervillain_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_supervillain_tone3:': { + uc_base: '1f9b9-1f3fd-2640', + uc_full: '1f9b9-1f3fd-200d-2640-fe0f', + shortnames: [':woman_supervillain_medium_skin_tone:'], + category: 'people', + }, + ':woman_supervillain_tone4:': { + uc_base: '1f9b9-1f3fe-2640', + uc_full: '1f9b9-1f3fe-200d-2640-fe0f', + shortnames: [':woman_supervillain_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_supervillain_tone5:': { + uc_base: '1f9b9-1f3ff-2640', + uc_full: '1f9b9-1f3ff-200d-2640-fe0f', + shortnames: [':woman_supervillain_dark_skin_tone:'], + category: 'people', + }, + ':woman_surfing_tone1:': { + uc_base: '1f3c4-1f3fb-2640', + uc_full: '1f3c4-1f3fb-200d-2640-fe0f', + shortnames: [':woman_surfing_light_skin_tone:'], + category: 'activity', + }, + ':woman_surfing_tone2:': { + uc_base: '1f3c4-1f3fc-2640', + uc_full: '1f3c4-1f3fc-200d-2640-fe0f', + shortnames: [':woman_surfing_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_surfing_tone3:': { + uc_base: '1f3c4-1f3fd-2640', + uc_full: '1f3c4-1f3fd-200d-2640-fe0f', + shortnames: [':woman_surfing_medium_skin_tone:'], + category: 'activity', + }, + ':woman_surfing_tone4:': { + uc_base: '1f3c4-1f3fe-2640', + uc_full: '1f3c4-1f3fe-200d-2640-fe0f', + shortnames: [':woman_surfing_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_surfing_tone5:': { + uc_base: '1f3c4-1f3ff-2640', + uc_full: '1f3c4-1f3ff-200d-2640-fe0f', + shortnames: [':woman_surfing_dark_skin_tone:'], + category: 'activity', + }, + ':woman_swimming_tone1:': { + uc_base: '1f3ca-1f3fb-2640', + uc_full: '1f3ca-1f3fb-200d-2640-fe0f', + shortnames: [':woman_swimming_light_skin_tone:'], + category: 'activity', + }, + ':woman_swimming_tone2:': { + uc_base: '1f3ca-1f3fc-2640', + uc_full: '1f3ca-1f3fc-200d-2640-fe0f', + shortnames: [':woman_swimming_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_swimming_tone3:': { + uc_base: '1f3ca-1f3fd-2640', + uc_full: '1f3ca-1f3fd-200d-2640-fe0f', + shortnames: [':woman_swimming_medium_skin_tone:'], + category: 'activity', + }, + ':woman_swimming_tone4:': { + uc_base: '1f3ca-1f3fe-2640', + uc_full: '1f3ca-1f3fe-200d-2640-fe0f', + shortnames: [':woman_swimming_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_swimming_tone5:': { + uc_base: '1f3ca-1f3ff-2640', + uc_full: '1f3ca-1f3ff-200d-2640-fe0f', + shortnames: [':woman_swimming_dark_skin_tone:'], + category: 'activity', + }, + ':woman_tipping_hand_tone1:': { + uc_base: '1f481-1f3fb-2640', + uc_full: '1f481-1f3fb-200d-2640-fe0f', + shortnames: [':woman_tipping_hand_light_skin_tone:'], + category: 'people', + }, + ':woman_tipping_hand_tone2:': { + uc_base: '1f481-1f3fc-2640', + uc_full: '1f481-1f3fc-200d-2640-fe0f', + shortnames: [':woman_tipping_hand_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_tipping_hand_tone3:': { + uc_base: '1f481-1f3fd-2640', + uc_full: '1f481-1f3fd-200d-2640-fe0f', + shortnames: [':woman_tipping_hand_medium_skin_tone:'], + category: 'people', + }, + ':woman_tipping_hand_tone4:': { + uc_base: '1f481-1f3fe-2640', + uc_full: '1f481-1f3fe-200d-2640-fe0f', + shortnames: [':woman_tipping_hand_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_tipping_hand_tone5:': { + uc_base: '1f481-1f3ff-2640', + uc_full: '1f481-1f3ff-200d-2640-fe0f', + shortnames: [':woman_tipping_hand_dark_skin_tone:'], + category: 'people', + }, + ':woman_tone1_beard:': { + uc_base: '1f9d4-1f3fb-2640', + uc_full: '1f9d4-1f3fb-200d-2640-fe0f', + shortnames: [':woman_light_skin_tone_beard:'], + category: 'people', + }, + ':woman_tone2_beard:': { + uc_base: '1f9d4-1f3fc-2640', + uc_full: '1f9d4-1f3fc-200d-2640-fe0f', + shortnames: [':woman_medium_light_skin_tone_beard:'], + category: 'people', + }, + ':woman_tone3_beard:': { + uc_base: '1f9d4-1f3fd-2640', + uc_full: '1f9d4-1f3fd-200d-2640-fe0f', + shortnames: [':woman_medium_skin_tone_beard:'], + category: 'people', + }, + ':woman_tone4_beard:': { + uc_base: '1f9d4-1f3fe-2640', + uc_full: '1f9d4-1f3fe-200d-2640-fe0f', + shortnames: [':woman_medium_dark_skin_tone_beard:'], + category: 'people', + }, + ':woman_tone5_beard:': { + uc_base: '1f9d4-1f3ff-2640', + uc_full: '1f9d4-1f3ff-200d-2640-fe0f', + shortnames: [':woman_dark_skin_tone_beard:'], + category: 'people', + }, + ':woman_vampire_tone1:': { + uc_base: '1f9db-1f3fb-2640', + uc_full: '1f9db-1f3fb-200d-2640-fe0f', + shortnames: [':woman_vampire_light_skin_tone:'], + category: 'people', + }, + ':woman_vampire_tone2:': { + uc_base: '1f9db-1f3fc-2640', + uc_full: '1f9db-1f3fc-200d-2640-fe0f', + shortnames: [':woman_vampire_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_vampire_tone3:': { + uc_base: '1f9db-1f3fd-2640', + uc_full: '1f9db-1f3fd-200d-2640-fe0f', + shortnames: [':woman_vampire_medium_skin_tone:'], + category: 'people', + }, + ':woman_vampire_tone4:': { + uc_base: '1f9db-1f3fe-2640', + uc_full: '1f9db-1f3fe-200d-2640-fe0f', + shortnames: [':woman_vampire_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_vampire_tone5:': { + uc_base: '1f9db-1f3ff-2640', + uc_full: '1f9db-1f3ff-200d-2640-fe0f', + shortnames: [':woman_vampire_dark_skin_tone:'], + category: 'people', + }, + ':woman_walking_tone1:': { + uc_base: '1f6b6-1f3fb-2640', + uc_full: '1f6b6-1f3fb-200d-2640-fe0f', + shortnames: [':woman_walking_light_skin_tone:'], + category: 'people', + }, + ':woman_walking_tone2:': { + uc_base: '1f6b6-1f3fc-2640', + uc_full: '1f6b6-1f3fc-200d-2640-fe0f', + shortnames: [':woman_walking_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_walking_tone3:': { + uc_base: '1f6b6-1f3fd-2640', + uc_full: '1f6b6-1f3fd-200d-2640-fe0f', + shortnames: [':woman_walking_medium_skin_tone:'], + category: 'people', + }, + ':woman_walking_tone4:': { + uc_base: '1f6b6-1f3fe-2640', + uc_full: '1f6b6-1f3fe-200d-2640-fe0f', + shortnames: [':woman_walking_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_walking_tone5:': { + uc_base: '1f6b6-1f3ff-2640', + uc_full: '1f6b6-1f3ff-200d-2640-fe0f', + shortnames: [':woman_walking_dark_skin_tone:'], + category: 'people', + }, + ':woman_wearing_turban_tone1:': { + uc_base: '1f473-1f3fb-2640', + uc_full: '1f473-1f3fb-200d-2640-fe0f', + shortnames: [':woman_wearing_turban_light_skin_tone:'], + category: 'people', + }, + ':woman_wearing_turban_tone2:': { + uc_base: '1f473-1f3fc-2640', + uc_full: '1f473-1f3fc-200d-2640-fe0f', + shortnames: [':woman_wearing_turban_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_wearing_turban_tone3:': { + uc_base: '1f473-1f3fd-2640', + uc_full: '1f473-1f3fd-200d-2640-fe0f', + shortnames: [':woman_wearing_turban_medium_skin_tone:'], + category: 'people', + }, + ':woman_wearing_turban_tone4:': { + uc_base: '1f473-1f3fe-2640', + uc_full: '1f473-1f3fe-200d-2640-fe0f', + shortnames: [':woman_wearing_turban_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_wearing_turban_tone5:': { + uc_base: '1f473-1f3ff-2640', + uc_full: '1f473-1f3ff-200d-2640-fe0f', + shortnames: [':woman_wearing_turban_dark_skin_tone:'], + category: 'people', + }, + ':woman_with_veil_tone1:': { + uc_base: '1f470-1f3fb-2640', + uc_full: '1f470-1f3fb-200d-2640-fe0f', + shortnames: [':woman_with_veil_light_skin_tone:'], + category: 'people', + }, + ':woman_with_veil_tone2:': { + uc_base: '1f470-1f3fc-2640', + uc_full: '1f470-1f3fc-200d-2640-fe0f', + shortnames: [':woman_with_veil_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_with_veil_tone3:': { + uc_base: '1f470-1f3fd-2640', + uc_full: '1f470-1f3fd-200d-2640-fe0f', + shortnames: [':woman_with_veil_medium_skin_tone:'], + category: 'people', + }, + ':woman_with_veil_tone4:': { + uc_base: '1f470-1f3fe-2640', + uc_full: '1f470-1f3fe-200d-2640-fe0f', + shortnames: [':woman_with_veil_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_with_veil_tone5:': { + uc_base: '1f470-1f3ff-2640', + uc_full: '1f470-1f3ff-200d-2640-fe0f', + shortnames: [':woman_with_veil_dark_skin_tone:'], + category: 'people', + }, + ':man_bouncing_ball_tone1:': { + uc_base: '26f9-1f3fb-2642', + uc_full: '26f9-1f3fb-200d-2642-fe0f', + shortnames: [':man_bouncing_ball_light_skin_tone:'], + category: 'activity', + }, + ':man_bouncing_ball_tone2:': { + uc_base: '26f9-1f3fc-2642', + uc_full: '26f9-1f3fc-200d-2642-fe0f', + shortnames: [':man_bouncing_ball_medium_light_skin_tone:'], + category: 'activity', + }, + ':man_bouncing_ball_tone3:': { + uc_base: '26f9-1f3fd-2642', + uc_full: '26f9-1f3fd-200d-2642-fe0f', + shortnames: [':man_bouncing_ball_medium_skin_tone:'], + category: 'activity', + }, + ':man_bouncing_ball_tone4:': { + uc_base: '26f9-1f3fe-2642', + uc_full: '26f9-1f3fe-200d-2642-fe0f', + shortnames: [':man_bouncing_ball_medium_dark_skin_tone:'], + category: 'activity', + }, + ':man_bouncing_ball_tone5:': { + uc_base: '26f9-1f3ff-2642', + uc_full: '26f9-1f3ff-200d-2642-fe0f', + shortnames: [':man_bouncing_ball_dark_skin_tone:'], + category: 'activity', + }, + ':woman_bouncing_ball_tone1:': { + uc_base: '26f9-1f3fb-2640', + uc_full: '26f9-1f3fb-200d-2640-fe0f', + shortnames: [':woman_bouncing_ball_light_skin_tone:'], + category: 'activity', + }, + ':woman_bouncing_ball_tone2:': { + uc_base: '26f9-1f3fc-2640', + uc_full: '26f9-1f3fc-200d-2640-fe0f', + shortnames: [':woman_bouncing_ball_medium_light_skin_tone:'], + category: 'activity', + }, + ':woman_bouncing_ball_tone3:': { + uc_base: '26f9-1f3fd-2640', + uc_full: '26f9-1f3fd-200d-2640-fe0f', + shortnames: [':woman_bouncing_ball_medium_skin_tone:'], + category: 'activity', + }, + ':woman_bouncing_ball_tone4:': { + uc_base: '26f9-1f3fe-2640', + uc_full: '26f9-1f3fe-200d-2640-fe0f', + shortnames: [':woman_bouncing_ball_medium_dark_skin_tone:'], + category: 'activity', + }, + ':woman_bouncing_ball_tone5:': { + uc_base: '26f9-1f3ff-2640', + uc_full: '26f9-1f3ff-200d-2640-fe0f', + shortnames: [':woman_bouncing_ball_dark_skin_tone:'], + category: 'activity', + }, + ':adult_tone1:': { uc_base: '1f9d1-1f3fb', uc_full: '1f9d1-1f3fb', shortnames: [':adult_light_skin_tone:'], category: 'people' }, + ':adult_tone2:': { uc_base: '1f9d1-1f3fc', uc_full: '1f9d1-1f3fc', shortnames: [':adult_medium_light_skin_tone:'], category: 'people' }, + ':adult_tone3:': { uc_base: '1f9d1-1f3fd', uc_full: '1f9d1-1f3fd', shortnames: [':adult_medium_skin_tone:'], category: 'people' }, + ':adult_tone4:': { uc_base: '1f9d1-1f3fe', uc_full: '1f9d1-1f3fe', shortnames: [':adult_medium_dark_skin_tone:'], category: 'people' }, + ':adult_tone5:': { uc_base: '1f9d1-1f3ff', uc_full: '1f9d1-1f3ff', shortnames: [':adult_dark_skin_tone:'], category: 'people' }, + ':angel_tone1:': { uc_base: '1f47c-1f3fb', uc_full: '1f47c-1f3fb', shortnames: [], category: 'people' }, + ':angel_tone2:': { uc_base: '1f47c-1f3fc', uc_full: '1f47c-1f3fc', shortnames: [], category: 'people' }, + ':angel_tone3:': { uc_base: '1f47c-1f3fd', uc_full: '1f47c-1f3fd', shortnames: [], category: 'people' }, + ':angel_tone4:': { uc_base: '1f47c-1f3fe', uc_full: '1f47c-1f3fe', shortnames: [], category: 'people' }, + ':angel_tone5:': { uc_base: '1f47c-1f3ff', uc_full: '1f47c-1f3ff', shortnames: [], category: 'people' }, + ':artist:': { uc_base: '1f9d1-1f3a8', uc_full: '1f9d1-200d-1f3a8', shortnames: [], category: 'people' }, + ':astronaut:': { uc_base: '1f9d1-1f680', uc_full: '1f9d1-200d-1f680', shortnames: [], category: 'people' }, + ':baby_tone1:': { uc_base: '1f476-1f3fb', uc_full: '1f476-1f3fb', shortnames: [], category: 'people' }, + ':baby_tone2:': { uc_base: '1f476-1f3fc', uc_full: '1f476-1f3fc', shortnames: [], category: 'people' }, + ':baby_tone3:': { uc_base: '1f476-1f3fd', uc_full: '1f476-1f3fd', shortnames: [], category: 'people' }, + ':baby_tone4:': { uc_base: '1f476-1f3fe', uc_full: '1f476-1f3fe', shortnames: [], category: 'people' }, + ':baby_tone5:': { uc_base: '1f476-1f3ff', uc_full: '1f476-1f3ff', shortnames: [], category: 'people' }, + ':bath_tone1:': { uc_base: '1f6c0-1f3fb', uc_full: '1f6c0-1f3fb', shortnames: [], category: 'objects' }, + ':bath_tone2:': { uc_base: '1f6c0-1f3fc', uc_full: '1f6c0-1f3fc', shortnames: [], category: 'objects' }, + ':bath_tone3:': { uc_base: '1f6c0-1f3fd', uc_full: '1f6c0-1f3fd', shortnames: [], category: 'objects' }, + ':bath_tone4:': { uc_base: '1f6c0-1f3fe', uc_full: '1f6c0-1f3fe', shortnames: [], category: 'objects' }, + ':bath_tone5:': { uc_base: '1f6c0-1f3ff', uc_full: '1f6c0-1f3ff', shortnames: [], category: 'objects' }, + ':bearded_person_tone1:': { + uc_base: '1f9d4-1f3fb', + uc_full: '1f9d4-1f3fb', + shortnames: [':bearded_person_light_skin_tone:'], + category: 'people', + }, + ':bearded_person_tone2:': { + uc_base: '1f9d4-1f3fc', + uc_full: '1f9d4-1f3fc', + shortnames: [':bearded_person_medium_light_skin_tone:'], + category: 'people', + }, + ':bearded_person_tone3:': { + uc_base: '1f9d4-1f3fd', + uc_full: '1f9d4-1f3fd', + shortnames: [':bearded_person_medium_skin_tone:'], + category: 'people', + }, + ':bearded_person_tone4:': { + uc_base: '1f9d4-1f3fe', + uc_full: '1f9d4-1f3fe', + shortnames: [':bearded_person_medium_dark_skin_tone:'], + category: 'people', + }, + ':bearded_person_tone5:': { + uc_base: '1f9d4-1f3ff', + uc_full: '1f9d4-1f3ff', + shortnames: [':bearded_person_dark_skin_tone:'], + category: 'people', + }, + ':blond_haired_person_tone1:': { + uc_base: '1f471-1f3fb', + uc_full: '1f471-1f3fb', + shortnames: [':person_with_blond_hair_tone1:'], + category: 'people', + }, + ':blond_haired_person_tone2:': { + uc_base: '1f471-1f3fc', + uc_full: '1f471-1f3fc', + shortnames: [':person_with_blond_hair_tone2:'], + category: 'people', + }, + ':blond_haired_person_tone3:': { + uc_base: '1f471-1f3fd', + uc_full: '1f471-1f3fd', + shortnames: [':person_with_blond_hair_tone3:'], + category: 'people', + }, + ':blond_haired_person_tone4:': { + uc_base: '1f471-1f3fe', + uc_full: '1f471-1f3fe', + shortnames: [':person_with_blond_hair_tone4:'], + category: 'people', + }, + ':blond_haired_person_tone5:': { + uc_base: '1f471-1f3ff', + uc_full: '1f471-1f3ff', + shortnames: [':person_with_blond_hair_tone5:'], + category: 'people', + }, + ':boy_tone1:': { uc_base: '1f466-1f3fb', uc_full: '1f466-1f3fb', shortnames: [], category: 'people' }, + ':boy_tone2:': { uc_base: '1f466-1f3fc', uc_full: '1f466-1f3fc', shortnames: [], category: 'people' }, + ':boy_tone3:': { uc_base: '1f466-1f3fd', uc_full: '1f466-1f3fd', shortnames: [], category: 'people' }, + ':boy_tone4:': { uc_base: '1f466-1f3fe', uc_full: '1f466-1f3fe', shortnames: [], category: 'people' }, + ':boy_tone5:': { uc_base: '1f466-1f3ff', uc_full: '1f466-1f3ff', shortnames: [], category: 'people' }, + ':breast_feeding_tone1:': { + uc_base: '1f931-1f3fb', + uc_full: '1f931-1f3fb', + shortnames: [':breast_feeding_light_skin_tone:'], + category: 'people', + }, + ':breast_feeding_tone2:': { + uc_base: '1f931-1f3fc', + uc_full: '1f931-1f3fc', + shortnames: [':breast_feeding_medium_light_skin_tone:'], + category: 'people', + }, + ':breast_feeding_tone3:': { + uc_base: '1f931-1f3fd', + uc_full: '1f931-1f3fd', + shortnames: [':breast_feeding_medium_skin_tone:'], + category: 'people', + }, + ':breast_feeding_tone4:': { + uc_base: '1f931-1f3fe', + uc_full: '1f931-1f3fe', + shortnames: [':breast_feeding_medium_dark_skin_tone:'], + category: 'people', + }, + ':breast_feeding_tone5:': { + uc_base: '1f931-1f3ff', + uc_full: '1f931-1f3ff', + shortnames: [':breast_feeding_dark_skin_tone:'], + category: 'people', + }, + ':call_me_tone1:': { uc_base: '1f919-1f3fb', uc_full: '1f919-1f3fb', shortnames: [':call_me_hand_tone1:'], category: 'people' }, + ':call_me_tone2:': { uc_base: '1f919-1f3fc', uc_full: '1f919-1f3fc', shortnames: [':call_me_hand_tone2:'], category: 'people' }, + ':call_me_tone3:': { uc_base: '1f919-1f3fd', uc_full: '1f919-1f3fd', shortnames: [':call_me_hand_tone3:'], category: 'people' }, + ':call_me_tone4:': { uc_base: '1f919-1f3fe', uc_full: '1f919-1f3fe', shortnames: [':call_me_hand_tone4:'], category: 'people' }, + ':call_me_tone5:': { uc_base: '1f919-1f3ff', uc_full: '1f919-1f3ff', shortnames: [':call_me_hand_tone5:'], category: 'people' }, + ':child_tone1:': { uc_base: '1f9d2-1f3fb', uc_full: '1f9d2-1f3fb', shortnames: [':child_light_skin_tone:'], category: 'people' }, + ':child_tone2:': { uc_base: '1f9d2-1f3fc', uc_full: '1f9d2-1f3fc', shortnames: [':child_medium_light_skin_tone:'], category: 'people' }, + ':child_tone3:': { uc_base: '1f9d2-1f3fd', uc_full: '1f9d2-1f3fd', shortnames: [':child_medium_skin_tone:'], category: 'people' }, + ':child_tone4:': { uc_base: '1f9d2-1f3fe', uc_full: '1f9d2-1f3fe', shortnames: [':child_medium_dark_skin_tone:'], category: 'people' }, + ':child_tone5:': { uc_base: '1f9d2-1f3ff', uc_full: '1f9d2-1f3ff', shortnames: [':child_dark_skin_tone:'], category: 'people' }, + ':clap_tone1:': { uc_base: '1f44f-1f3fb', uc_full: '1f44f-1f3fb', shortnames: [], category: 'people' }, + ':clap_tone2:': { uc_base: '1f44f-1f3fc', uc_full: '1f44f-1f3fc', shortnames: [], category: 'people' }, + ':clap_tone3:': { uc_base: '1f44f-1f3fd', uc_full: '1f44f-1f3fd', shortnames: [], category: 'people' }, + ':clap_tone4:': { uc_base: '1f44f-1f3fe', uc_full: '1f44f-1f3fe', shortnames: [], category: 'people' }, + ':clap_tone5:': { uc_base: '1f44f-1f3ff', uc_full: '1f44f-1f3ff', shortnames: [], category: 'people' }, + ':construction_worker_tone1:': { uc_base: '1f477-1f3fb', uc_full: '1f477-1f3fb', shortnames: [], category: 'people' }, + ':construction_worker_tone2:': { uc_base: '1f477-1f3fc', uc_full: '1f477-1f3fc', shortnames: [], category: 'people' }, + ':construction_worker_tone3:': { uc_base: '1f477-1f3fd', uc_full: '1f477-1f3fd', shortnames: [], category: 'people' }, + ':construction_worker_tone4:': { uc_base: '1f477-1f3fe', uc_full: '1f477-1f3fe', shortnames: [], category: 'people' }, + ':construction_worker_tone5:': { uc_base: '1f477-1f3ff', uc_full: '1f477-1f3ff', shortnames: [], category: 'people' }, + ':cook:': { uc_base: '1f9d1-1f373', uc_full: '1f9d1-200d-1f373', shortnames: [], category: 'people' }, + ':couple_with_heart_tone1:': { + uc_base: '1f491-1f3fb', + uc_full: '1f491-1f3fb', + shortnames: [':couple_with_heart_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_tone2:': { + uc_base: '1f491-1f3fc', + uc_full: '1f491-1f3fc', + shortnames: [':couple_with_heart_medium_light_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_tone3:': { + uc_base: '1f491-1f3fd', + uc_full: '1f491-1f3fd', + shortnames: [':couple_with_heart_medium_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_tone4:': { + uc_base: '1f491-1f3fe', + uc_full: '1f491-1f3fe', + shortnames: [':couple_with_heart_medium_dark_skin_tone:'], + category: 'people', + }, + ':couple_with_heart_tone5:': { + uc_base: '1f491-1f3ff', + uc_full: '1f491-1f3ff', + shortnames: [':couple_with_heart_dark_skin_tone:'], + category: 'people', + }, + ':dancer_tone1:': { uc_base: '1f483-1f3fb', uc_full: '1f483-1f3fb', shortnames: [], category: 'people' }, + ':dancer_tone2:': { uc_base: '1f483-1f3fc', uc_full: '1f483-1f3fc', shortnames: [], category: 'people' }, + ':dancer_tone3:': { uc_base: '1f483-1f3fd', uc_full: '1f483-1f3fd', shortnames: [], category: 'people' }, + ':dancer_tone4:': { uc_base: '1f483-1f3fe', uc_full: '1f483-1f3fe', shortnames: [], category: 'people' }, + ':dancer_tone5:': { uc_base: '1f483-1f3ff', uc_full: '1f483-1f3ff', shortnames: [], category: 'people' }, + ':deaf_person_tone1:': { + uc_base: '1f9cf-1f3fb', + uc_full: '1f9cf-1f3fb', + shortnames: [':deaf_person_light_skin_tone:'], + category: 'people', + }, + ':deaf_person_tone2:': { + uc_base: '1f9cf-1f3fc', + uc_full: '1f9cf-1f3fc', + shortnames: [':deaf_person_medium_light_skin_tone:'], + category: 'people', + }, + ':deaf_person_tone3:': { + uc_base: '1f9cf-1f3fd', + uc_full: '1f9cf-1f3fd', + shortnames: [':deaf_person_medium_skin_tone:'], + category: 'people', + }, + ':deaf_person_tone4:': { + uc_base: '1f9cf-1f3fe', + uc_full: '1f9cf-1f3fe', + shortnames: [':deaf_person_medium_dark_skin_tone:'], + category: 'people', + }, + ':deaf_person_tone5:': { + uc_base: '1f9cf-1f3ff', + uc_full: '1f9cf-1f3ff', + shortnames: [':deaf_person_dark_skin_tone:'], + category: 'people', + }, + ':detective_tone1:': { + uc_base: '1f575-1f3fb', + uc_full: '1f575-1f3fb', + shortnames: [':spy_tone1:', ':sleuth_or_spy_tone1:'], + category: 'people', + }, + ':detective_tone2:': { + uc_base: '1f575-1f3fc', + uc_full: '1f575-1f3fc', + shortnames: [':spy_tone2:', ':sleuth_or_spy_tone2:'], + category: 'people', + }, + ':detective_tone3:': { + uc_base: '1f575-1f3fd', + uc_full: '1f575-1f3fd', + shortnames: [':spy_tone3:', ':sleuth_or_spy_tone3:'], + category: 'people', + }, + ':detective_tone4:': { + uc_base: '1f575-1f3fe', + uc_full: '1f575-1f3fe', + shortnames: [':spy_tone4:', ':sleuth_or_spy_tone4:'], + category: 'people', + }, + ':detective_tone5:': { + uc_base: '1f575-1f3ff', + uc_full: '1f575-1f3ff', + shortnames: [':spy_tone5:', ':sleuth_or_spy_tone5:'], + category: 'people', + }, + ':ear_tone1:': { uc_base: '1f442-1f3fb', uc_full: '1f442-1f3fb', shortnames: [], category: 'people' }, + ':ear_tone2:': { uc_base: '1f442-1f3fc', uc_full: '1f442-1f3fc', shortnames: [], category: 'people' }, + ':ear_tone3:': { uc_base: '1f442-1f3fd', uc_full: '1f442-1f3fd', shortnames: [], category: 'people' }, + ':ear_tone4:': { uc_base: '1f442-1f3fe', uc_full: '1f442-1f3fe', shortnames: [], category: 'people' }, + ':ear_tone5:': { uc_base: '1f442-1f3ff', uc_full: '1f442-1f3ff', shortnames: [], category: 'people' }, + ':ear_with_hearing_aid_tone1:': { + uc_base: '1f9bb-1f3fb', + uc_full: '1f9bb-1f3fb', + shortnames: [':ear_with_hearing_aid_light_skin_tone:'], + category: 'people', + }, + ':ear_with_hearing_aid_tone2:': { + uc_base: '1f9bb-1f3fc', + uc_full: '1f9bb-1f3fc', + shortnames: [':ear_with_hearing_aid_medium_light_skin_tone:'], + category: 'people', + }, + ':ear_with_hearing_aid_tone3:': { + uc_base: '1f9bb-1f3fd', + uc_full: '1f9bb-1f3fd', + shortnames: [':ear_with_hearing_aid_medium_skin_tone:'], + category: 'people', + }, + ':ear_with_hearing_aid_tone4:': { + uc_base: '1f9bb-1f3fe', + uc_full: '1f9bb-1f3fe', + shortnames: [':ear_with_hearing_aid_medium_dark_skin_tone:'], + category: 'people', + }, + ':ear_with_hearing_aid_tone5:': { + uc_base: '1f9bb-1f3ff', + uc_full: '1f9bb-1f3ff', + shortnames: [':ear_with_hearing_aid_dark_skin_tone:'], + category: 'people', + }, + ':elf_tone1:': { uc_base: '1f9dd-1f3fb', uc_full: '1f9dd-1f3fb', shortnames: [':elf_light_skin_tone:'], category: 'people' }, + ':elf_tone2:': { uc_base: '1f9dd-1f3fc', uc_full: '1f9dd-1f3fc', shortnames: [':elf_medium_light_skin_tone:'], category: 'people' }, + ':elf_tone3:': { uc_base: '1f9dd-1f3fd', uc_full: '1f9dd-1f3fd', shortnames: [':elf_medium_skin_tone:'], category: 'people' }, + ':elf_tone4:': { uc_base: '1f9dd-1f3fe', uc_full: '1f9dd-1f3fe', shortnames: [':elf_medium_dark_skin_tone:'], category: 'people' }, + ':elf_tone5:': { uc_base: '1f9dd-1f3ff', uc_full: '1f9dd-1f3ff', shortnames: [':elf_dark_skin_tone:'], category: 'people' }, + ':eye_in_speech_bubble:': { uc_base: '1f441-1f5e8', uc_full: '1f441-fe0f-200d-1f5e8-fe0f', shortnames: [], category: 'symbols' }, + ':face_exhaling:': { uc_base: '1f62e-1f4a8', uc_full: '1f62e-200d-1f4a8', shortnames: [], category: 'people' }, + ':face_in_clouds:': { uc_base: '1f636-1f32b', uc_full: '1f636-200d-1f32b-fe0f', shortnames: [], category: 'people' }, + ':face_with_spiral_eyes:': { uc_base: '1f635-1f4ab', uc_full: '1f635-200d-1f4ab', shortnames: [], category: 'people' }, + ':factory_worker:': { uc_base: '1f9d1-1f3ed', uc_full: '1f9d1-200d-1f3ed', shortnames: [], category: 'people' }, + ':fairy_tone1:': { uc_base: '1f9da-1f3fb', uc_full: '1f9da-1f3fb', shortnames: [':fairy_light_skin_tone:'], category: 'people' }, + ':fairy_tone2:': { uc_base: '1f9da-1f3fc', uc_full: '1f9da-1f3fc', shortnames: [':fairy_medium_light_skin_tone:'], category: 'people' }, + ':fairy_tone3:': { uc_base: '1f9da-1f3fd', uc_full: '1f9da-1f3fd', shortnames: [':fairy_medium_skin_tone:'], category: 'people' }, + ':fairy_tone4:': { uc_base: '1f9da-1f3fe', uc_full: '1f9da-1f3fe', shortnames: [':fairy_medium_dark_skin_tone:'], category: 'people' }, + ':fairy_tone5:': { uc_base: '1f9da-1f3ff', uc_full: '1f9da-1f3ff', shortnames: [':fairy_dark_skin_tone:'], category: 'people' }, + ':family_man_boy:': { uc_base: '1f468-1f466', uc_full: '1f468-200d-1f466', shortnames: [], category: 'people' }, + ':family_man_girl:': { uc_base: '1f468-1f467', uc_full: '1f468-200d-1f467', shortnames: [], category: 'people' }, + ':family_woman_boy:': { uc_base: '1f469-1f466', uc_full: '1f469-200d-1f466', shortnames: [], category: 'people' }, + ':family_woman_girl:': { uc_base: '1f469-1f467', uc_full: '1f469-200d-1f467', shortnames: [], category: 'people' }, + ':farmer:': { uc_base: '1f9d1-1f33e', uc_full: '1f9d1-200d-1f33e', shortnames: [], category: 'people' }, + ':fingers_crossed_tone1:': { + uc_base: '1f91e-1f3fb', + uc_full: '1f91e-1f3fb', + shortnames: [':hand_with_index_and_middle_fingers_crossed_tone1:'], + category: 'people', + }, + ':fingers_crossed_tone2:': { + uc_base: '1f91e-1f3fc', + uc_full: '1f91e-1f3fc', + shortnames: [':hand_with_index_and_middle_fingers_crossed_tone2:'], + category: 'people', + }, + ':fingers_crossed_tone3:': { + uc_base: '1f91e-1f3fd', + uc_full: '1f91e-1f3fd', + shortnames: [':hand_with_index_and_middle_fingers_crossed_tone3:'], + category: 'people', + }, + ':fingers_crossed_tone4:': { + uc_base: '1f91e-1f3fe', + uc_full: '1f91e-1f3fe', + shortnames: [':hand_with_index_and_middle_fingers_crossed_tone4:'], + category: 'people', + }, + ':fingers_crossed_tone5:': { + uc_base: '1f91e-1f3ff', + uc_full: '1f91e-1f3ff', + shortnames: [':hand_with_index_and_middle_fingers_crossed_tone5:'], + category: 'people', + }, + ':firefighter:': { uc_base: '1f9d1-1f692', uc_full: '1f9d1-200d-1f692', shortnames: [], category: 'people' }, + ':flag_ac:': { uc_base: '1f1e6-1f1e8', uc_full: '1f1e6-1f1e8', shortnames: [':ac:'], category: 'flags' }, + ':flag_ad:': { uc_base: '1f1e6-1f1e9', uc_full: '1f1e6-1f1e9', shortnames: [':ad:'], category: 'flags' }, + ':flag_ae:': { uc_base: '1f1e6-1f1ea', uc_full: '1f1e6-1f1ea', shortnames: [':ae:'], category: 'flags' }, + ':flag_af:': { uc_base: '1f1e6-1f1eb', uc_full: '1f1e6-1f1eb', shortnames: [':af:'], category: 'flags' }, + ':flag_ag:': { uc_base: '1f1e6-1f1ec', uc_full: '1f1e6-1f1ec', shortnames: [':ag:'], category: 'flags' }, + ':flag_ai:': { uc_base: '1f1e6-1f1ee', uc_full: '1f1e6-1f1ee', shortnames: [':ai:'], category: 'flags' }, + ':flag_al:': { uc_base: '1f1e6-1f1f1', uc_full: '1f1e6-1f1f1', shortnames: [':al:'], category: 'flags' }, + ':flag_am:': { uc_base: '1f1e6-1f1f2', uc_full: '1f1e6-1f1f2', shortnames: [':am:'], category: 'flags' }, + ':flag_ao:': { uc_base: '1f1e6-1f1f4', uc_full: '1f1e6-1f1f4', shortnames: [':ao:'], category: 'flags' }, + ':flag_aq:': { uc_base: '1f1e6-1f1f6', uc_full: '1f1e6-1f1f6', shortnames: [':aq:'], category: 'flags' }, + ':flag_ar:': { uc_base: '1f1e6-1f1f7', uc_full: '1f1e6-1f1f7', shortnames: [':ar:'], category: 'flags' }, + ':flag_as:': { uc_base: '1f1e6-1f1f8', uc_full: '1f1e6-1f1f8', shortnames: [':as:'], category: 'flags' }, + ':flag_at:': { uc_base: '1f1e6-1f1f9', uc_full: '1f1e6-1f1f9', shortnames: [':at:'], category: 'flags' }, + ':flag_au:': { uc_base: '1f1e6-1f1fa', uc_full: '1f1e6-1f1fa', shortnames: [':au:'], category: 'flags' }, + ':flag_aw:': { uc_base: '1f1e6-1f1fc', uc_full: '1f1e6-1f1fc', shortnames: [':aw:'], category: 'flags' }, + ':flag_ax:': { uc_base: '1f1e6-1f1fd', uc_full: '1f1e6-1f1fd', shortnames: [':ax:'], category: 'flags' }, + ':flag_az:': { uc_base: '1f1e6-1f1ff', uc_full: '1f1e6-1f1ff', shortnames: [':az:'], category: 'flags' }, + ':flag_ba:': { uc_base: '1f1e7-1f1e6', uc_full: '1f1e7-1f1e6', shortnames: [':ba:'], category: 'flags' }, + ':flag_bb:': { uc_base: '1f1e7-1f1e7', uc_full: '1f1e7-1f1e7', shortnames: [':bb:'], category: 'flags' }, + ':flag_bd:': { uc_base: '1f1e7-1f1e9', uc_full: '1f1e7-1f1e9', shortnames: [':bd:'], category: 'flags' }, + ':flag_be:': { uc_base: '1f1e7-1f1ea', uc_full: '1f1e7-1f1ea', shortnames: [':be:'], category: 'flags' }, + ':flag_bf:': { uc_base: '1f1e7-1f1eb', uc_full: '1f1e7-1f1eb', shortnames: [':bf:'], category: 'flags' }, + ':flag_bg:': { uc_base: '1f1e7-1f1ec', uc_full: '1f1e7-1f1ec', shortnames: [':bg:'], category: 'flags' }, + ':flag_bh:': { uc_base: '1f1e7-1f1ed', uc_full: '1f1e7-1f1ed', shortnames: [':bh:'], category: 'flags' }, + ':flag_bi:': { uc_base: '1f1e7-1f1ee', uc_full: '1f1e7-1f1ee', shortnames: [':bi:'], category: 'flags' }, + ':flag_bj:': { uc_base: '1f1e7-1f1ef', uc_full: '1f1e7-1f1ef', shortnames: [':bj:'], category: 'flags' }, + ':flag_bl:': { uc_base: '1f1e7-1f1f1', uc_full: '1f1e7-1f1f1', shortnames: [':bl:'], category: 'flags' }, + ':flag_bm:': { uc_base: '1f1e7-1f1f2', uc_full: '1f1e7-1f1f2', shortnames: [':bm:'], category: 'flags' }, + ':flag_bn:': { uc_base: '1f1e7-1f1f3', uc_full: '1f1e7-1f1f3', shortnames: [':bn:'], category: 'flags' }, + ':flag_bo:': { uc_base: '1f1e7-1f1f4', uc_full: '1f1e7-1f1f4', shortnames: [':bo:'], category: 'flags' }, + ':flag_bq:': { uc_base: '1f1e7-1f1f6', uc_full: '1f1e7-1f1f6', shortnames: [':bq:'], category: 'flags' }, + ':flag_br:': { uc_base: '1f1e7-1f1f7', uc_full: '1f1e7-1f1f7', shortnames: [':br:'], category: 'flags' }, + ':flag_bs:': { uc_base: '1f1e7-1f1f8', uc_full: '1f1e7-1f1f8', shortnames: [':bs:'], category: 'flags' }, + ':flag_bt:': { uc_base: '1f1e7-1f1f9', uc_full: '1f1e7-1f1f9', shortnames: [':bt:'], category: 'flags' }, + ':flag_bv:': { uc_base: '1f1e7-1f1fb', uc_full: '1f1e7-1f1fb', shortnames: [':bv:'], category: 'flags' }, + ':flag_bw:': { uc_base: '1f1e7-1f1fc', uc_full: '1f1e7-1f1fc', shortnames: [':bw:'], category: 'flags' }, + ':flag_by:': { uc_base: '1f1e7-1f1fe', uc_full: '1f1e7-1f1fe', shortnames: [':by:'], category: 'flags' }, + ':flag_bz:': { uc_base: '1f1e7-1f1ff', uc_full: '1f1e7-1f1ff', shortnames: [':bz:'], category: 'flags' }, + ':flag_ca:': { uc_base: '1f1e8-1f1e6', uc_full: '1f1e8-1f1e6', shortnames: [':ca:'], category: 'flags' }, + ':flag_cc:': { uc_base: '1f1e8-1f1e8', uc_full: '1f1e8-1f1e8', shortnames: [':cc:'], category: 'flags' }, + ':flag_cd:': { uc_base: '1f1e8-1f1e9', uc_full: '1f1e8-1f1e9', shortnames: [':congo:'], category: 'flags' }, + ':flag_cf:': { uc_base: '1f1e8-1f1eb', uc_full: '1f1e8-1f1eb', shortnames: [':cf:'], category: 'flags' }, + ':flag_cg:': { uc_base: '1f1e8-1f1ec', uc_full: '1f1e8-1f1ec', shortnames: [':cg:'], category: 'flags' }, + ':flag_ch:': { uc_base: '1f1e8-1f1ed', uc_full: '1f1e8-1f1ed', shortnames: [':ch:'], category: 'flags' }, + ':flag_ci:': { uc_base: '1f1e8-1f1ee', uc_full: '1f1e8-1f1ee', shortnames: [':ci:'], category: 'flags' }, + ':flag_ck:': { uc_base: '1f1e8-1f1f0', uc_full: '1f1e8-1f1f0', shortnames: [':ck:'], category: 'flags' }, + ':flag_cl:': { uc_base: '1f1e8-1f1f1', uc_full: '1f1e8-1f1f1', shortnames: [':chile:'], category: 'flags' }, + ':flag_cm:': { uc_base: '1f1e8-1f1f2', uc_full: '1f1e8-1f1f2', shortnames: [':cm:'], category: 'flags' }, + ':flag_cn:': { uc_base: '1f1e8-1f1f3', uc_full: '1f1e8-1f1f3', shortnames: [':cn:'], category: 'flags' }, + ':flag_co:': { uc_base: '1f1e8-1f1f4', uc_full: '1f1e8-1f1f4', shortnames: [':co:'], category: 'flags' }, + ':flag_cp:': { uc_base: '1f1e8-1f1f5', uc_full: '1f1e8-1f1f5', shortnames: [':cp:'], category: 'flags' }, + ':flag_cr:': { uc_base: '1f1e8-1f1f7', uc_full: '1f1e8-1f1f7', shortnames: [':cr:'], category: 'flags' }, + ':flag_cu:': { uc_base: '1f1e8-1f1fa', uc_full: '1f1e8-1f1fa', shortnames: [':cu:'], category: 'flags' }, + ':flag_cv:': { uc_base: '1f1e8-1f1fb', uc_full: '1f1e8-1f1fb', shortnames: [':cv:'], category: 'flags' }, + ':flag_cw:': { uc_base: '1f1e8-1f1fc', uc_full: '1f1e8-1f1fc', shortnames: [':cw:'], category: 'flags' }, + ':flag_cx:': { uc_base: '1f1e8-1f1fd', uc_full: '1f1e8-1f1fd', shortnames: [':cx:'], category: 'flags' }, + ':flag_cy:': { uc_base: '1f1e8-1f1fe', uc_full: '1f1e8-1f1fe', shortnames: [':cy:'], category: 'flags' }, + ':flag_cz:': { uc_base: '1f1e8-1f1ff', uc_full: '1f1e8-1f1ff', shortnames: [':cz:'], category: 'flags' }, + ':flag_de:': { uc_base: '1f1e9-1f1ea', uc_full: '1f1e9-1f1ea', shortnames: [':de:'], category: 'flags' }, + ':flag_dg:': { uc_base: '1f1e9-1f1ec', uc_full: '1f1e9-1f1ec', shortnames: [':dg:'], category: 'flags' }, + ':flag_dj:': { uc_base: '1f1e9-1f1ef', uc_full: '1f1e9-1f1ef', shortnames: [':dj:'], category: 'flags' }, + ':flag_dk:': { uc_base: '1f1e9-1f1f0', uc_full: '1f1e9-1f1f0', shortnames: [':dk:'], category: 'flags' }, + ':flag_dm:': { uc_base: '1f1e9-1f1f2', uc_full: '1f1e9-1f1f2', shortnames: [':dm:'], category: 'flags' }, + ':flag_do:': { uc_base: '1f1e9-1f1f4', uc_full: '1f1e9-1f1f4', shortnames: [':do:'], category: 'flags' }, + ':flag_dz:': { uc_base: '1f1e9-1f1ff', uc_full: '1f1e9-1f1ff', shortnames: [':dz:'], category: 'flags' }, + ':flag_ea:': { uc_base: '1f1ea-1f1e6', uc_full: '1f1ea-1f1e6', shortnames: [':ea:'], category: 'flags' }, + ':flag_ec:': { uc_base: '1f1ea-1f1e8', uc_full: '1f1ea-1f1e8', shortnames: [':ec:'], category: 'flags' }, + ':flag_ee:': { uc_base: '1f1ea-1f1ea', uc_full: '1f1ea-1f1ea', shortnames: [':ee:'], category: 'flags' }, + ':flag_eg:': { uc_base: '1f1ea-1f1ec', uc_full: '1f1ea-1f1ec', shortnames: [':eg:'], category: 'flags' }, + ':flag_eh:': { uc_base: '1f1ea-1f1ed', uc_full: '1f1ea-1f1ed', shortnames: [':eh:'], category: 'flags' }, + ':flag_er:': { uc_base: '1f1ea-1f1f7', uc_full: '1f1ea-1f1f7', shortnames: [':er:'], category: 'flags' }, + ':flag_es:': { uc_base: '1f1ea-1f1f8', uc_full: '1f1ea-1f1f8', shortnames: [':es:'], category: 'flags' }, + ':flag_et:': { uc_base: '1f1ea-1f1f9', uc_full: '1f1ea-1f1f9', shortnames: [':et:'], category: 'flags' }, + ':flag_eu:': { uc_base: '1f1ea-1f1fa', uc_full: '1f1ea-1f1fa', shortnames: [':eu:'], category: 'flags' }, + ':flag_fi:': { uc_base: '1f1eb-1f1ee', uc_full: '1f1eb-1f1ee', shortnames: [':fi:'], category: 'flags' }, + ':flag_fj:': { uc_base: '1f1eb-1f1ef', uc_full: '1f1eb-1f1ef', shortnames: [':fj:'], category: 'flags' }, + ':flag_fk:': { uc_base: '1f1eb-1f1f0', uc_full: '1f1eb-1f1f0', shortnames: [':fk:'], category: 'flags' }, + ':flag_fm:': { uc_base: '1f1eb-1f1f2', uc_full: '1f1eb-1f1f2', shortnames: [':fm:'], category: 'flags' }, + ':flag_fo:': { uc_base: '1f1eb-1f1f4', uc_full: '1f1eb-1f1f4', shortnames: [':fo:'], category: 'flags' }, + ':flag_fr:': { uc_base: '1f1eb-1f1f7', uc_full: '1f1eb-1f1f7', shortnames: [':fr:'], category: 'flags' }, + ':flag_ga:': { uc_base: '1f1ec-1f1e6', uc_full: '1f1ec-1f1e6', shortnames: [':ga:'], category: 'flags' }, + ':flag_gb:': { uc_base: '1f1ec-1f1e7', uc_full: '1f1ec-1f1e7', shortnames: [':gb:'], category: 'flags' }, + ':flag_gd:': { uc_base: '1f1ec-1f1e9', uc_full: '1f1ec-1f1e9', shortnames: [':gd:'], category: 'flags' }, + ':flag_ge:': { uc_base: '1f1ec-1f1ea', uc_full: '1f1ec-1f1ea', shortnames: [':ge:'], category: 'flags' }, + ':flag_gf:': { uc_base: '1f1ec-1f1eb', uc_full: '1f1ec-1f1eb', shortnames: [':gf:'], category: 'flags' }, + ':flag_gg:': { uc_base: '1f1ec-1f1ec', uc_full: '1f1ec-1f1ec', shortnames: [':gg:'], category: 'flags' }, + ':flag_gh:': { uc_base: '1f1ec-1f1ed', uc_full: '1f1ec-1f1ed', shortnames: [':gh:'], category: 'flags' }, + ':flag_gi:': { uc_base: '1f1ec-1f1ee', uc_full: '1f1ec-1f1ee', shortnames: [':gi:'], category: 'flags' }, + ':flag_gl:': { uc_base: '1f1ec-1f1f1', uc_full: '1f1ec-1f1f1', shortnames: [':gl:'], category: 'flags' }, + ':flag_gm:': { uc_base: '1f1ec-1f1f2', uc_full: '1f1ec-1f1f2', shortnames: [':gm:'], category: 'flags' }, + ':flag_gn:': { uc_base: '1f1ec-1f1f3', uc_full: '1f1ec-1f1f3', shortnames: [':gn:'], category: 'flags' }, + ':flag_gp:': { uc_base: '1f1ec-1f1f5', uc_full: '1f1ec-1f1f5', shortnames: [':gp:'], category: 'flags' }, + ':flag_gq:': { uc_base: '1f1ec-1f1f6', uc_full: '1f1ec-1f1f6', shortnames: [':gq:'], category: 'flags' }, + ':flag_gr:': { uc_base: '1f1ec-1f1f7', uc_full: '1f1ec-1f1f7', shortnames: [':gr:'], category: 'flags' }, + ':flag_gs:': { uc_base: '1f1ec-1f1f8', uc_full: '1f1ec-1f1f8', shortnames: [':gs:'], category: 'flags' }, + ':flag_gt:': { uc_base: '1f1ec-1f1f9', uc_full: '1f1ec-1f1f9', shortnames: [':gt:'], category: 'flags' }, + ':flag_gu:': { uc_base: '1f1ec-1f1fa', uc_full: '1f1ec-1f1fa', shortnames: [':gu:'], category: 'flags' }, + ':flag_gw:': { uc_base: '1f1ec-1f1fc', uc_full: '1f1ec-1f1fc', shortnames: [':gw:'], category: 'flags' }, + ':flag_gy:': { uc_base: '1f1ec-1f1fe', uc_full: '1f1ec-1f1fe', shortnames: [':gy:'], category: 'flags' }, + ':flag_hk:': { uc_base: '1f1ed-1f1f0', uc_full: '1f1ed-1f1f0', shortnames: [':hk:'], category: 'flags' }, + ':flag_hm:': { uc_base: '1f1ed-1f1f2', uc_full: '1f1ed-1f1f2', shortnames: [':hm:'], category: 'flags' }, + ':flag_hn:': { uc_base: '1f1ed-1f1f3', uc_full: '1f1ed-1f1f3', shortnames: [':hn:'], category: 'flags' }, + ':flag_hr:': { uc_base: '1f1ed-1f1f7', uc_full: '1f1ed-1f1f7', shortnames: [':hr:'], category: 'flags' }, + ':flag_ht:': { uc_base: '1f1ed-1f1f9', uc_full: '1f1ed-1f1f9', shortnames: [':ht:'], category: 'flags' }, + ':flag_hu:': { uc_base: '1f1ed-1f1fa', uc_full: '1f1ed-1f1fa', shortnames: [':hu:'], category: 'flags' }, + ':flag_ic:': { uc_base: '1f1ee-1f1e8', uc_full: '1f1ee-1f1e8', shortnames: [':ic:'], category: 'flags' }, + ':flag_id:': { uc_base: '1f1ee-1f1e9', uc_full: '1f1ee-1f1e9', shortnames: [':indonesia:'], category: 'flags' }, + ':flag_ie:': { uc_base: '1f1ee-1f1ea', uc_full: '1f1ee-1f1ea', shortnames: [':ie:'], category: 'flags' }, + ':flag_il:': { uc_base: '1f1ee-1f1f1', uc_full: '1f1ee-1f1f1', shortnames: [':il:'], category: 'flags' }, + ':flag_im:': { uc_base: '1f1ee-1f1f2', uc_full: '1f1ee-1f1f2', shortnames: [':im:'], category: 'flags' }, + ':flag_in:': { uc_base: '1f1ee-1f1f3', uc_full: '1f1ee-1f1f3', shortnames: [':in:'], category: 'flags' }, + ':flag_io:': { uc_base: '1f1ee-1f1f4', uc_full: '1f1ee-1f1f4', shortnames: [':io:'], category: 'flags' }, + ':flag_iq:': { uc_base: '1f1ee-1f1f6', uc_full: '1f1ee-1f1f6', shortnames: [':iq:'], category: 'flags' }, + ':flag_ir:': { uc_base: '1f1ee-1f1f7', uc_full: '1f1ee-1f1f7', shortnames: [':ir:'], category: 'flags' }, + ':flag_is:': { uc_base: '1f1ee-1f1f8', uc_full: '1f1ee-1f1f8', shortnames: [':is:'], category: 'flags' }, + ':flag_it:': { uc_base: '1f1ee-1f1f9', uc_full: '1f1ee-1f1f9', shortnames: [':it:'], category: 'flags' }, + ':flag_je:': { uc_base: '1f1ef-1f1ea', uc_full: '1f1ef-1f1ea', shortnames: [':je:'], category: 'flags' }, + ':flag_jm:': { uc_base: '1f1ef-1f1f2', uc_full: '1f1ef-1f1f2', shortnames: [':jm:'], category: 'flags' }, + ':flag_jo:': { uc_base: '1f1ef-1f1f4', uc_full: '1f1ef-1f1f4', shortnames: [':jo:'], category: 'flags' }, + ':flag_jp:': { uc_base: '1f1ef-1f1f5', uc_full: '1f1ef-1f1f5', shortnames: [':jp:'], category: 'flags' }, + ':flag_ke:': { uc_base: '1f1f0-1f1ea', uc_full: '1f1f0-1f1ea', shortnames: [':ke:'], category: 'flags' }, + ':flag_kg:': { uc_base: '1f1f0-1f1ec', uc_full: '1f1f0-1f1ec', shortnames: [':kg:'], category: 'flags' }, + ':flag_kh:': { uc_base: '1f1f0-1f1ed', uc_full: '1f1f0-1f1ed', shortnames: [':kh:'], category: 'flags' }, + ':flag_ki:': { uc_base: '1f1f0-1f1ee', uc_full: '1f1f0-1f1ee', shortnames: [':ki:'], category: 'flags' }, + ':flag_km:': { uc_base: '1f1f0-1f1f2', uc_full: '1f1f0-1f1f2', shortnames: [':km:'], category: 'flags' }, + ':flag_kn:': { uc_base: '1f1f0-1f1f3', uc_full: '1f1f0-1f1f3', shortnames: [':kn:'], category: 'flags' }, + ':flag_kp:': { uc_base: '1f1f0-1f1f5', uc_full: '1f1f0-1f1f5', shortnames: [':kp:'], category: 'flags' }, + ':flag_kr:': { uc_base: '1f1f0-1f1f7', uc_full: '1f1f0-1f1f7', shortnames: [':kr:'], category: 'flags' }, + ':flag_kw:': { uc_base: '1f1f0-1f1fc', uc_full: '1f1f0-1f1fc', shortnames: [':kw:'], category: 'flags' }, + ':flag_ky:': { uc_base: '1f1f0-1f1fe', uc_full: '1f1f0-1f1fe', shortnames: [':ky:'], category: 'flags' }, + ':flag_kz:': { uc_base: '1f1f0-1f1ff', uc_full: '1f1f0-1f1ff', shortnames: [':kz:'], category: 'flags' }, + ':flag_la:': { uc_base: '1f1f1-1f1e6', uc_full: '1f1f1-1f1e6', shortnames: [':la:'], category: 'flags' }, + ':flag_lb:': { uc_base: '1f1f1-1f1e7', uc_full: '1f1f1-1f1e7', shortnames: [':lb:'], category: 'flags' }, + ':flag_lc:': { uc_base: '1f1f1-1f1e8', uc_full: '1f1f1-1f1e8', shortnames: [':lc:'], category: 'flags' }, + ':flag_li:': { uc_base: '1f1f1-1f1ee', uc_full: '1f1f1-1f1ee', shortnames: [':li:'], category: 'flags' }, + ':flag_lk:': { uc_base: '1f1f1-1f1f0', uc_full: '1f1f1-1f1f0', shortnames: [':lk:'], category: 'flags' }, + ':flag_lr:': { uc_base: '1f1f1-1f1f7', uc_full: '1f1f1-1f1f7', shortnames: [':lr:'], category: 'flags' }, + ':flag_ls:': { uc_base: '1f1f1-1f1f8', uc_full: '1f1f1-1f1f8', shortnames: [':ls:'], category: 'flags' }, + ':flag_lt:': { uc_base: '1f1f1-1f1f9', uc_full: '1f1f1-1f1f9', shortnames: [':lt:'], category: 'flags' }, + ':flag_lu:': { uc_base: '1f1f1-1f1fa', uc_full: '1f1f1-1f1fa', shortnames: [':lu:'], category: 'flags' }, + ':flag_lv:': { uc_base: '1f1f1-1f1fb', uc_full: '1f1f1-1f1fb', shortnames: [':lv:'], category: 'flags' }, + ':flag_ly:': { uc_base: '1f1f1-1f1fe', uc_full: '1f1f1-1f1fe', shortnames: [':ly:'], category: 'flags' }, + ':flag_ma:': { uc_base: '1f1f2-1f1e6', uc_full: '1f1f2-1f1e6', shortnames: [':ma:'], category: 'flags' }, + ':flag_mc:': { uc_base: '1f1f2-1f1e8', uc_full: '1f1f2-1f1e8', shortnames: [':mc:'], category: 'flags' }, + ':flag_md:': { uc_base: '1f1f2-1f1e9', uc_full: '1f1f2-1f1e9', shortnames: [':md:'], category: 'flags' }, + ':flag_me:': { uc_base: '1f1f2-1f1ea', uc_full: '1f1f2-1f1ea', shortnames: [':me:'], category: 'flags' }, + ':flag_mf:': { uc_base: '1f1f2-1f1eb', uc_full: '1f1f2-1f1eb', shortnames: [':mf:'], category: 'flags' }, + ':flag_mg:': { uc_base: '1f1f2-1f1ec', uc_full: '1f1f2-1f1ec', shortnames: [':mg:'], category: 'flags' }, + ':flag_mh:': { uc_base: '1f1f2-1f1ed', uc_full: '1f1f2-1f1ed', shortnames: [':mh:'], category: 'flags' }, + ':flag_mk:': { uc_base: '1f1f2-1f1f0', uc_full: '1f1f2-1f1f0', shortnames: [':mk:'], category: 'flags' }, + ':flag_ml:': { uc_base: '1f1f2-1f1f1', uc_full: '1f1f2-1f1f1', shortnames: [':ml:'], category: 'flags' }, + ':flag_mm:': { uc_base: '1f1f2-1f1f2', uc_full: '1f1f2-1f1f2', shortnames: [':mm:'], category: 'flags' }, + ':flag_mn:': { uc_base: '1f1f2-1f1f3', uc_full: '1f1f2-1f1f3', shortnames: [':mn:'], category: 'flags' }, + ':flag_mo:': { uc_base: '1f1f2-1f1f4', uc_full: '1f1f2-1f1f4', shortnames: [':mo:'], category: 'flags' }, + ':flag_mp:': { uc_base: '1f1f2-1f1f5', uc_full: '1f1f2-1f1f5', shortnames: [':mp:'], category: 'flags' }, + ':flag_mq:': { uc_base: '1f1f2-1f1f6', uc_full: '1f1f2-1f1f6', shortnames: [':mq:'], category: 'flags' }, + ':flag_mr:': { uc_base: '1f1f2-1f1f7', uc_full: '1f1f2-1f1f7', shortnames: [':mr:'], category: 'flags' }, + ':flag_ms:': { uc_base: '1f1f2-1f1f8', uc_full: '1f1f2-1f1f8', shortnames: [':ms:'], category: 'flags' }, + ':flag_mt:': { uc_base: '1f1f2-1f1f9', uc_full: '1f1f2-1f1f9', shortnames: [':mt:'], category: 'flags' }, + ':flag_mu:': { uc_base: '1f1f2-1f1fa', uc_full: '1f1f2-1f1fa', shortnames: [':mu:'], category: 'flags' }, + ':flag_mv:': { uc_base: '1f1f2-1f1fb', uc_full: '1f1f2-1f1fb', shortnames: [':mv:'], category: 'flags' }, + ':flag_mw:': { uc_base: '1f1f2-1f1fc', uc_full: '1f1f2-1f1fc', shortnames: [':mw:'], category: 'flags' }, + ':flag_mx:': { uc_base: '1f1f2-1f1fd', uc_full: '1f1f2-1f1fd', shortnames: [':mx:'], category: 'flags' }, + ':flag_my:': { uc_base: '1f1f2-1f1fe', uc_full: '1f1f2-1f1fe', shortnames: [':my:'], category: 'flags' }, + ':flag_mz:': { uc_base: '1f1f2-1f1ff', uc_full: '1f1f2-1f1ff', shortnames: [':mz:'], category: 'flags' }, + ':flag_na:': { uc_base: '1f1f3-1f1e6', uc_full: '1f1f3-1f1e6', shortnames: [':na:'], category: 'flags' }, + ':flag_nc:': { uc_base: '1f1f3-1f1e8', uc_full: '1f1f3-1f1e8', shortnames: [':nc:'], category: 'flags' }, + ':flag_ne:': { uc_base: '1f1f3-1f1ea', uc_full: '1f1f3-1f1ea', shortnames: [':ne:'], category: 'flags' }, + ':flag_nf:': { uc_base: '1f1f3-1f1eb', uc_full: '1f1f3-1f1eb', shortnames: [':nf:'], category: 'flags' }, + ':flag_ng:': { uc_base: '1f1f3-1f1ec', uc_full: '1f1f3-1f1ec', shortnames: [':nigeria:'], category: 'flags' }, + ':flag_ni:': { uc_base: '1f1f3-1f1ee', uc_full: '1f1f3-1f1ee', shortnames: [':ni:'], category: 'flags' }, + ':flag_nl:': { uc_base: '1f1f3-1f1f1', uc_full: '1f1f3-1f1f1', shortnames: [':nl:'], category: 'flags' }, + ':flag_no:': { uc_base: '1f1f3-1f1f4', uc_full: '1f1f3-1f1f4', shortnames: [':no:'], category: 'flags' }, + ':flag_np:': { uc_base: '1f1f3-1f1f5', uc_full: '1f1f3-1f1f5', shortnames: [':np:'], category: 'flags' }, + ':flag_nr:': { uc_base: '1f1f3-1f1f7', uc_full: '1f1f3-1f1f7', shortnames: [':nr:'], category: 'flags' }, + ':flag_nu:': { uc_base: '1f1f3-1f1fa', uc_full: '1f1f3-1f1fa', shortnames: [':nu:'], category: 'flags' }, + ':flag_nz:': { uc_base: '1f1f3-1f1ff', uc_full: '1f1f3-1f1ff', shortnames: [':nz:'], category: 'flags' }, + ':flag_om:': { uc_base: '1f1f4-1f1f2', uc_full: '1f1f4-1f1f2', shortnames: [':om:'], category: 'flags' }, + ':flag_pa:': { uc_base: '1f1f5-1f1e6', uc_full: '1f1f5-1f1e6', shortnames: [':pa:'], category: 'flags' }, + ':flag_pe:': { uc_base: '1f1f5-1f1ea', uc_full: '1f1f5-1f1ea', shortnames: [':pe:'], category: 'flags' }, + ':flag_pf:': { uc_base: '1f1f5-1f1eb', uc_full: '1f1f5-1f1eb', shortnames: [':pf:'], category: 'flags' }, + ':flag_pg:': { uc_base: '1f1f5-1f1ec', uc_full: '1f1f5-1f1ec', shortnames: [':pg:'], category: 'flags' }, + ':flag_ph:': { uc_base: '1f1f5-1f1ed', uc_full: '1f1f5-1f1ed', shortnames: [':ph:'], category: 'flags' }, + ':flag_pk:': { uc_base: '1f1f5-1f1f0', uc_full: '1f1f5-1f1f0', shortnames: [':pk:'], category: 'flags' }, + ':flag_pl:': { uc_base: '1f1f5-1f1f1', uc_full: '1f1f5-1f1f1', shortnames: [':pl:'], category: 'flags' }, + ':flag_pm:': { uc_base: '1f1f5-1f1f2', uc_full: '1f1f5-1f1f2', shortnames: [':pm:'], category: 'flags' }, + ':flag_pn:': { uc_base: '1f1f5-1f1f3', uc_full: '1f1f5-1f1f3', shortnames: [':pn:'], category: 'flags' }, + ':flag_pr:': { uc_base: '1f1f5-1f1f7', uc_full: '1f1f5-1f1f7', shortnames: [':pr:'], category: 'flags' }, + ':flag_ps:': { uc_base: '1f1f5-1f1f8', uc_full: '1f1f5-1f1f8', shortnames: [':ps:'], category: 'flags' }, + ':flag_pt:': { uc_base: '1f1f5-1f1f9', uc_full: '1f1f5-1f1f9', shortnames: [':pt:'], category: 'flags' }, + ':flag_pw:': { uc_base: '1f1f5-1f1fc', uc_full: '1f1f5-1f1fc', shortnames: [':pw:'], category: 'flags' }, + ':flag_py:': { uc_base: '1f1f5-1f1fe', uc_full: '1f1f5-1f1fe', shortnames: [':py:'], category: 'flags' }, + ':flag_qa:': { uc_base: '1f1f6-1f1e6', uc_full: '1f1f6-1f1e6', shortnames: [':qa:'], category: 'flags' }, + ':flag_re:': { uc_base: '1f1f7-1f1ea', uc_full: '1f1f7-1f1ea', shortnames: [':re:'], category: 'flags' }, + ':flag_ro:': { uc_base: '1f1f7-1f1f4', uc_full: '1f1f7-1f1f4', shortnames: [':ro:'], category: 'flags' }, + ':flag_rs:': { uc_base: '1f1f7-1f1f8', uc_full: '1f1f7-1f1f8', shortnames: [':rs:'], category: 'flags' }, + ':flag_ru:': { uc_base: '1f1f7-1f1fa', uc_full: '1f1f7-1f1fa', shortnames: [':ru:'], category: 'flags' }, + ':flag_rw:': { uc_base: '1f1f7-1f1fc', uc_full: '1f1f7-1f1fc', shortnames: [':rw:'], category: 'flags' }, + ':flag_sa:': { uc_base: '1f1f8-1f1e6', uc_full: '1f1f8-1f1e6', shortnames: [':saudiarabia:', ':saudi:'], category: 'flags' }, + ':flag_sb:': { uc_base: '1f1f8-1f1e7', uc_full: '1f1f8-1f1e7', shortnames: [':sb:'], category: 'flags' }, + ':flag_sc:': { uc_base: '1f1f8-1f1e8', uc_full: '1f1f8-1f1e8', shortnames: [':sc:'], category: 'flags' }, + ':flag_sd:': { uc_base: '1f1f8-1f1e9', uc_full: '1f1f8-1f1e9', shortnames: [':sd:'], category: 'flags' }, + ':flag_se:': { uc_base: '1f1f8-1f1ea', uc_full: '1f1f8-1f1ea', shortnames: [':se:'], category: 'flags' }, + ':flag_sg:': { uc_base: '1f1f8-1f1ec', uc_full: '1f1f8-1f1ec', shortnames: [':sg:'], category: 'flags' }, + ':flag_sh:': { uc_base: '1f1f8-1f1ed', uc_full: '1f1f8-1f1ed', shortnames: [':sh:'], category: 'flags' }, + ':flag_si:': { uc_base: '1f1f8-1f1ee', uc_full: '1f1f8-1f1ee', shortnames: [':si:'], category: 'flags' }, + ':flag_sj:': { uc_base: '1f1f8-1f1ef', uc_full: '1f1f8-1f1ef', shortnames: [':sj:'], category: 'flags' }, + ':flag_sk:': { uc_base: '1f1f8-1f1f0', uc_full: '1f1f8-1f1f0', shortnames: [':sk:'], category: 'flags' }, + ':flag_sl:': { uc_base: '1f1f8-1f1f1', uc_full: '1f1f8-1f1f1', shortnames: [':sl:'], category: 'flags' }, + ':flag_sm:': { uc_base: '1f1f8-1f1f2', uc_full: '1f1f8-1f1f2', shortnames: [':sm:'], category: 'flags' }, + ':flag_sn:': { uc_base: '1f1f8-1f1f3', uc_full: '1f1f8-1f1f3', shortnames: [':sn:'], category: 'flags' }, + ':flag_so:': { uc_base: '1f1f8-1f1f4', uc_full: '1f1f8-1f1f4', shortnames: [':so:'], category: 'flags' }, + ':flag_sr:': { uc_base: '1f1f8-1f1f7', uc_full: '1f1f8-1f1f7', shortnames: [':sr:'], category: 'flags' }, + ':flag_ss:': { uc_base: '1f1f8-1f1f8', uc_full: '1f1f8-1f1f8', shortnames: [':ss:'], category: 'flags' }, + ':flag_st:': { uc_base: '1f1f8-1f1f9', uc_full: '1f1f8-1f1f9', shortnames: [':st:'], category: 'flags' }, + ':flag_sv:': { uc_base: '1f1f8-1f1fb', uc_full: '1f1f8-1f1fb', shortnames: [':sv:'], category: 'flags' }, + ':flag_sx:': { uc_base: '1f1f8-1f1fd', uc_full: '1f1f8-1f1fd', shortnames: [':sx:'], category: 'flags' }, + ':flag_sy:': { uc_base: '1f1f8-1f1fe', uc_full: '1f1f8-1f1fe', shortnames: [':sy:'], category: 'flags' }, + ':flag_sz:': { uc_base: '1f1f8-1f1ff', uc_full: '1f1f8-1f1ff', shortnames: [':sz:'], category: 'flags' }, + ':flag_ta:': { uc_base: '1f1f9-1f1e6', uc_full: '1f1f9-1f1e6', shortnames: [':ta:'], category: 'flags' }, + ':flag_tc:': { uc_base: '1f1f9-1f1e8', uc_full: '1f1f9-1f1e8', shortnames: [':tc:'], category: 'flags' }, + ':flag_td:': { uc_base: '1f1f9-1f1e9', uc_full: '1f1f9-1f1e9', shortnames: [':td:'], category: 'flags' }, + ':flag_tf:': { uc_base: '1f1f9-1f1eb', uc_full: '1f1f9-1f1eb', shortnames: [':tf:'], category: 'flags' }, + ':flag_tg:': { uc_base: '1f1f9-1f1ec', uc_full: '1f1f9-1f1ec', shortnames: [':tg:'], category: 'flags' }, + ':flag_th:': { uc_base: '1f1f9-1f1ed', uc_full: '1f1f9-1f1ed', shortnames: [':th:'], category: 'flags' }, + ':flag_tj:': { uc_base: '1f1f9-1f1ef', uc_full: '1f1f9-1f1ef', shortnames: [':tj:'], category: 'flags' }, + ':flag_tk:': { uc_base: '1f1f9-1f1f0', uc_full: '1f1f9-1f1f0', shortnames: [':tk:'], category: 'flags' }, + ':flag_tl:': { uc_base: '1f1f9-1f1f1', uc_full: '1f1f9-1f1f1', shortnames: [':tl:'], category: 'flags' }, + ':flag_tm:': { uc_base: '1f1f9-1f1f2', uc_full: '1f1f9-1f1f2', shortnames: [':turkmenistan:'], category: 'flags' }, + ':flag_tn:': { uc_base: '1f1f9-1f1f3', uc_full: '1f1f9-1f1f3', shortnames: [':tn:'], category: 'flags' }, + ':flag_to:': { uc_base: '1f1f9-1f1f4', uc_full: '1f1f9-1f1f4', shortnames: [':to:'], category: 'flags' }, + ':flag_tr:': { uc_base: '1f1f9-1f1f7', uc_full: '1f1f9-1f1f7', shortnames: [':tr:'], category: 'flags' }, + ':flag_tt:': { uc_base: '1f1f9-1f1f9', uc_full: '1f1f9-1f1f9', shortnames: [':tt:'], category: 'flags' }, + ':flag_tv:': { uc_base: '1f1f9-1f1fb', uc_full: '1f1f9-1f1fb', shortnames: [':tuvalu:'], category: 'flags' }, + ':flag_tw:': { uc_base: '1f1f9-1f1fc', uc_full: '1f1f9-1f1fc', shortnames: [':tw:'], category: 'flags' }, + ':flag_tz:': { uc_base: '1f1f9-1f1ff', uc_full: '1f1f9-1f1ff', shortnames: [':tz:'], category: 'flags' }, + ':flag_ua:': { uc_base: '1f1fa-1f1e6', uc_full: '1f1fa-1f1e6', shortnames: [':ua:'], category: 'flags' }, + ':flag_ug:': { uc_base: '1f1fa-1f1ec', uc_full: '1f1fa-1f1ec', shortnames: [':ug:'], category: 'flags' }, + ':flag_um:': { uc_base: '1f1fa-1f1f2', uc_full: '1f1fa-1f1f2', shortnames: [':um:'], category: 'flags' }, + ':flag_us:': { uc_base: '1f1fa-1f1f8', uc_full: '1f1fa-1f1f8', shortnames: [':us:'], category: 'flags' }, + ':flag_uy:': { uc_base: '1f1fa-1f1fe', uc_full: '1f1fa-1f1fe', shortnames: [':uy:'], category: 'flags' }, + ':flag_uz:': { uc_base: '1f1fa-1f1ff', uc_full: '1f1fa-1f1ff', shortnames: [':uz:'], category: 'flags' }, + ':flag_va:': { uc_base: '1f1fb-1f1e6', uc_full: '1f1fb-1f1e6', shortnames: [':va:'], category: 'flags' }, + ':flag_vc:': { uc_base: '1f1fb-1f1e8', uc_full: '1f1fb-1f1e8', shortnames: [':vc:'], category: 'flags' }, + ':flag_ve:': { uc_base: '1f1fb-1f1ea', uc_full: '1f1fb-1f1ea', shortnames: [':ve:'], category: 'flags' }, + ':flag_vg:': { uc_base: '1f1fb-1f1ec', uc_full: '1f1fb-1f1ec', shortnames: [':vg:'], category: 'flags' }, + ':flag_vi:': { uc_base: '1f1fb-1f1ee', uc_full: '1f1fb-1f1ee', shortnames: [':vi:'], category: 'flags' }, + ':flag_vn:': { uc_base: '1f1fb-1f1f3', uc_full: '1f1fb-1f1f3', shortnames: [':vn:'], category: 'flags' }, + ':flag_vu:': { uc_base: '1f1fb-1f1fa', uc_full: '1f1fb-1f1fa', shortnames: [':vu:'], category: 'flags' }, + ':flag_wf:': { uc_base: '1f1fc-1f1eb', uc_full: '1f1fc-1f1eb', shortnames: [':wf:'], category: 'flags' }, + ':flag_ws:': { uc_base: '1f1fc-1f1f8', uc_full: '1f1fc-1f1f8', shortnames: [':ws:'], category: 'flags' }, + ':flag_xk:': { uc_base: '1f1fd-1f1f0', uc_full: '1f1fd-1f1f0', shortnames: [':xk:'], category: 'flags' }, + ':flag_ye:': { uc_base: '1f1fe-1f1ea', uc_full: '1f1fe-1f1ea', shortnames: [':ye:'], category: 'flags' }, + ':flag_yt:': { uc_base: '1f1fe-1f1f9', uc_full: '1f1fe-1f1f9', shortnames: [':yt:'], category: 'flags' }, + ':flag_za:': { uc_base: '1f1ff-1f1e6', uc_full: '1f1ff-1f1e6', shortnames: [':za:'], category: 'flags' }, + ':flag_zm:': { uc_base: '1f1ff-1f1f2', uc_full: '1f1ff-1f1f2', shortnames: [':zm:'], category: 'flags' }, + ':flag_zw:': { uc_base: '1f1ff-1f1fc', uc_full: '1f1ff-1f1fc', shortnames: [':zw:'], category: 'flags' }, + ':foot_tone1:': { uc_base: '1f9b6-1f3fb', uc_full: '1f9b6-1f3fb', shortnames: [':foot_light_skin_tone:'], category: 'people' }, + ':foot_tone2:': { uc_base: '1f9b6-1f3fc', uc_full: '1f9b6-1f3fc', shortnames: [':foot_medium_light_skin_tone:'], category: 'people' }, + ':foot_tone3:': { uc_base: '1f9b6-1f3fd', uc_full: '1f9b6-1f3fd', shortnames: [':foot_medium_skin_tone:'], category: 'people' }, + ':foot_tone4:': { uc_base: '1f9b6-1f3fe', uc_full: '1f9b6-1f3fe', shortnames: [':foot_medium_dark_skin_tone:'], category: 'people' }, + ':foot_tone5:': { uc_base: '1f9b6-1f3ff', uc_full: '1f9b6-1f3ff', shortnames: [':foot_dark_skin_tone:'], category: 'people' }, + ':girl_tone1:': { uc_base: '1f467-1f3fb', uc_full: '1f467-1f3fb', shortnames: [], category: 'people' }, + ':girl_tone2:': { uc_base: '1f467-1f3fc', uc_full: '1f467-1f3fc', shortnames: [], category: 'people' }, + ':girl_tone3:': { uc_base: '1f467-1f3fd', uc_full: '1f467-1f3fd', shortnames: [], category: 'people' }, + ':girl_tone4:': { uc_base: '1f467-1f3fe', uc_full: '1f467-1f3fe', shortnames: [], category: 'people' }, + ':girl_tone5:': { uc_base: '1f467-1f3ff', uc_full: '1f467-1f3ff', shortnames: [], category: 'people' }, + ':guard_tone1:': { uc_base: '1f482-1f3fb', uc_full: '1f482-1f3fb', shortnames: [':guardsman_tone1:'], category: 'people' }, + ':guard_tone2:': { uc_base: '1f482-1f3fc', uc_full: '1f482-1f3fc', shortnames: [':guardsman_tone2:'], category: 'people' }, + ':guard_tone3:': { uc_base: '1f482-1f3fd', uc_full: '1f482-1f3fd', shortnames: [':guardsman_tone3:'], category: 'people' }, + ':guard_tone4:': { uc_base: '1f482-1f3fe', uc_full: '1f482-1f3fe', shortnames: [':guardsman_tone4:'], category: 'people' }, + ':guard_tone5:': { uc_base: '1f482-1f3ff', uc_full: '1f482-1f3ff', shortnames: [':guardsman_tone5:'], category: 'people' }, + ':hand_splayed_tone1:': { + uc_base: '1f590-1f3fb', + uc_full: '1f590-1f3fb', + shortnames: [':raised_hand_with_fingers_splayed_tone1:'], + category: 'people', + }, + ':hand_splayed_tone2:': { + uc_base: '1f590-1f3fc', + uc_full: '1f590-1f3fc', + shortnames: [':raised_hand_with_fingers_splayed_tone2:'], + category: 'people', + }, + ':hand_splayed_tone3:': { + uc_base: '1f590-1f3fd', + uc_full: '1f590-1f3fd', + shortnames: [':raised_hand_with_fingers_splayed_tone3:'], + category: 'people', + }, + ':hand_splayed_tone4:': { + uc_base: '1f590-1f3fe', + uc_full: '1f590-1f3fe', + shortnames: [':raised_hand_with_fingers_splayed_tone4:'], + category: 'people', + }, + ':hand_splayed_tone5:': { + uc_base: '1f590-1f3ff', + uc_full: '1f590-1f3ff', + shortnames: [':raised_hand_with_fingers_splayed_tone5:'], + category: 'people', + }, + ':horse_racing_tone1:': { uc_base: '1f3c7-1f3fb', uc_full: '1f3c7-1f3fb', shortnames: [], category: 'activity' }, + ':horse_racing_tone2:': { uc_base: '1f3c7-1f3fc', uc_full: '1f3c7-1f3fc', shortnames: [], category: 'activity' }, + ':horse_racing_tone3:': { uc_base: '1f3c7-1f3fd', uc_full: '1f3c7-1f3fd', shortnames: [], category: 'activity' }, + ':horse_racing_tone4:': { uc_base: '1f3c7-1f3fe', uc_full: '1f3c7-1f3fe', shortnames: [], category: 'activity' }, + ':horse_racing_tone5:': { uc_base: '1f3c7-1f3ff', uc_full: '1f3c7-1f3ff', shortnames: [], category: 'activity' }, + ':kiss_tone1:': { uc_base: '1f48f-1f3fb', uc_full: '1f48f-1f3fb', shortnames: [':kiss_light_skin_tone:'], category: 'people' }, + ':kiss_tone2:': { uc_base: '1f48f-1f3fc', uc_full: '1f48f-1f3fc', shortnames: [':kiss_medium_light_skin_tone:'], category: 'people' }, + ':kiss_tone3:': { uc_base: '1f48f-1f3fd', uc_full: '1f48f-1f3fd', shortnames: [':kiss_medium_skin_tone:'], category: 'people' }, + ':kiss_tone4:': { uc_base: '1f48f-1f3fe', uc_full: '1f48f-1f3fe', shortnames: [':kiss_medium_dark_skin_tone:'], category: 'people' }, + ':kiss_tone5:': { uc_base: '1f48f-1f3ff', uc_full: '1f48f-1f3ff', shortnames: [':kiss_dark_skin_tone:'], category: 'people' }, + ':left_facing_fist_tone1:': { uc_base: '1f91b-1f3fb', uc_full: '1f91b-1f3fb', shortnames: [':left_fist_tone1:'], category: 'people' }, + ':left_facing_fist_tone2:': { uc_base: '1f91b-1f3fc', uc_full: '1f91b-1f3fc', shortnames: [':left_fist_tone2:'], category: 'people' }, + ':left_facing_fist_tone3:': { uc_base: '1f91b-1f3fd', uc_full: '1f91b-1f3fd', shortnames: [':left_fist_tone3:'], category: 'people' }, + ':left_facing_fist_tone4:': { uc_base: '1f91b-1f3fe', uc_full: '1f91b-1f3fe', shortnames: [':left_fist_tone4:'], category: 'people' }, + ':left_facing_fist_tone5:': { uc_base: '1f91b-1f3ff', uc_full: '1f91b-1f3ff', shortnames: [':left_fist_tone5:'], category: 'people' }, + ':leg_tone1:': { uc_base: '1f9b5-1f3fb', uc_full: '1f9b5-1f3fb', shortnames: [':leg_light_skin_tone:'], category: 'people' }, + ':leg_tone2:': { uc_base: '1f9b5-1f3fc', uc_full: '1f9b5-1f3fc', shortnames: [':leg_medium_light_skin_tone:'], category: 'people' }, + ':leg_tone3:': { uc_base: '1f9b5-1f3fd', uc_full: '1f9b5-1f3fd', shortnames: [':leg_medium_skin_tone:'], category: 'people' }, + ':leg_tone4:': { uc_base: '1f9b5-1f3fe', uc_full: '1f9b5-1f3fe', shortnames: [':leg_medium_dark_skin_tone:'], category: 'people' }, + ':leg_tone5:': { uc_base: '1f9b5-1f3ff', uc_full: '1f9b5-1f3ff', shortnames: [':leg_dark_skin_tone:'], category: 'people' }, + ':levitate_tone1:': { + uc_base: '1f574-1f3fb', + uc_full: '1f574-1f3fb', + shortnames: [':man_in_business_suit_levitating_tone1:', ':man_in_business_suit_levitating_light_skin_tone:'], + category: 'people', + }, + ':levitate_tone2:': { + uc_base: '1f574-1f3fc', + uc_full: '1f574-1f3fc', + shortnames: [':man_in_business_suit_levitating_tone2:', ':man_in_business_suit_levitating_medium_light_skin_tone:'], + category: 'people', + }, + ':levitate_tone3:': { + uc_base: '1f574-1f3fd', + uc_full: '1f574-1f3fd', + shortnames: [':man_in_business_suit_levitating_tone3:', ':man_in_business_suit_levitating_medium_skin_tone:'], + category: 'people', + }, + ':levitate_tone4:': { + uc_base: '1f574-1f3fe', + uc_full: '1f574-1f3fe', + shortnames: [':man_in_business_suit_levitating_tone4:', ':man_in_business_suit_levitating_medium_dark_skin_tone:'], + category: 'people', + }, + ':levitate_tone5:': { + uc_base: '1f574-1f3ff', + uc_full: '1f574-1f3ff', + shortnames: [':man_in_business_suit_levitating_tone5:', ':man_in_business_suit_levitating_dark_skin_tone:'], + category: 'people', + }, + ':love_you_gesture_tone1:': { + uc_base: '1f91f-1f3fb', + uc_full: '1f91f-1f3fb', + shortnames: [':love_you_gesture_light_skin_tone:'], + category: 'people', + }, + ':love_you_gesture_tone2:': { + uc_base: '1f91f-1f3fc', + uc_full: '1f91f-1f3fc', + shortnames: [':love_you_gesture_medium_light_skin_tone:'], + category: 'people', + }, + ':love_you_gesture_tone3:': { + uc_base: '1f91f-1f3fd', + uc_full: '1f91f-1f3fd', + shortnames: [':love_you_gesture_medium_skin_tone:'], + category: 'people', + }, + ':love_you_gesture_tone4:': { + uc_base: '1f91f-1f3fe', + uc_full: '1f91f-1f3fe', + shortnames: [':love_you_gesture_medium_dark_skin_tone:'], + category: 'people', + }, + ':love_you_gesture_tone5:': { + uc_base: '1f91f-1f3ff', + uc_full: '1f91f-1f3ff', + shortnames: [':love_you_gesture_dark_skin_tone:'], + category: 'people', + }, + ':mage_tone1:': { uc_base: '1f9d9-1f3fb', uc_full: '1f9d9-1f3fb', shortnames: [':mage_light_skin_tone:'], category: 'people' }, + ':mage_tone2:': { uc_base: '1f9d9-1f3fc', uc_full: '1f9d9-1f3fc', shortnames: [':mage_medium_light_skin_tone:'], category: 'people' }, + ':mage_tone3:': { uc_base: '1f9d9-1f3fd', uc_full: '1f9d9-1f3fd', shortnames: [':mage_medium_skin_tone:'], category: 'people' }, + ':mage_tone4:': { uc_base: '1f9d9-1f3fe', uc_full: '1f9d9-1f3fe', shortnames: [':mage_medium_dark_skin_tone:'], category: 'people' }, + ':mage_tone5:': { uc_base: '1f9d9-1f3ff', uc_full: '1f9d9-1f3ff', shortnames: [':mage_dark_skin_tone:'], category: 'people' }, + ':man_artist:': { uc_base: '1f468-1f3a8', uc_full: '1f468-200d-1f3a8', shortnames: [], category: 'people' }, + ':man_astronaut:': { uc_base: '1f468-1f680', uc_full: '1f468-200d-1f680', shortnames: [], category: 'people' }, + ':man_bald:': { uc_base: '1f468-1f9b2', uc_full: '1f468-200d-1f9b2', shortnames: [], category: 'people' }, + ':man_cook:': { uc_base: '1f468-1f373', uc_full: '1f468-200d-1f373', shortnames: [], category: 'people' }, + ':man_curly_haired:': { uc_base: '1f468-1f9b1', uc_full: '1f468-200d-1f9b1', shortnames: [], category: 'people' }, + ':man_dancing_tone1:': { uc_base: '1f57a-1f3fb', uc_full: '1f57a-1f3fb', shortnames: [':male_dancer_tone1:'], category: 'people' }, + ':man_dancing_tone2:': { uc_base: '1f57a-1f3fc', uc_full: '1f57a-1f3fc', shortnames: [':male_dancer_tone2:'], category: 'people' }, + ':man_dancing_tone3:': { uc_base: '1f57a-1f3fd', uc_full: '1f57a-1f3fd', shortnames: [':male_dancer_tone3:'], category: 'people' }, + ':man_dancing_tone4:': { uc_base: '1f57a-1f3fe', uc_full: '1f57a-1f3fe', shortnames: [':male_dancer_tone4:'], category: 'people' }, + ':man_dancing_tone5:': { uc_base: '1f57a-1f3ff', uc_full: '1f57a-1f3ff', shortnames: [':male_dancer_tone5:'], category: 'people' }, + ':man_factory_worker:': { uc_base: '1f468-1f3ed', uc_full: '1f468-200d-1f3ed', shortnames: [], category: 'people' }, + ':man_farmer:': { uc_base: '1f468-1f33e', uc_full: '1f468-200d-1f33e', shortnames: [], category: 'people' }, + ':man_feeding_baby:': { uc_base: '1f468-1f37c', uc_full: '1f468-200d-1f37c', shortnames: [], category: 'people' }, + ':man_firefighter:': { uc_base: '1f468-1f692', uc_full: '1f468-200d-1f692', shortnames: [], category: 'people' }, + ':man_in_manual_wheelchair:': { uc_base: '1f468-1f9bd', uc_full: '1f468-200d-1f9bd', shortnames: [], category: 'people' }, + ':man_in_motorized_wheelchair:': { uc_base: '1f468-1f9bc', uc_full: '1f468-200d-1f9bc', shortnames: [], category: 'people' }, + ':man_mechanic:': { uc_base: '1f468-1f527', uc_full: '1f468-200d-1f527', shortnames: [], category: 'people' }, + ':man_office_worker:': { uc_base: '1f468-1f4bc', uc_full: '1f468-200d-1f4bc', shortnames: [], category: 'people' }, + ':man_red_haired:': { uc_base: '1f468-1f9b0', uc_full: '1f468-200d-1f9b0', shortnames: [], category: 'people' }, + ':man_scientist:': { uc_base: '1f468-1f52c', uc_full: '1f468-200d-1f52c', shortnames: [], category: 'people' }, + ':man_singer:': { uc_base: '1f468-1f3a4', uc_full: '1f468-200d-1f3a4', shortnames: [], category: 'people' }, + ':man_student:': { uc_base: '1f468-1f393', uc_full: '1f468-200d-1f393', shortnames: [], category: 'people' }, + ':man_teacher:': { uc_base: '1f468-1f3eb', uc_full: '1f468-200d-1f3eb', shortnames: [], category: 'people' }, + ':man_technologist:': { uc_base: '1f468-1f4bb', uc_full: '1f468-200d-1f4bb', shortnames: [], category: 'people' }, + ':man_tone1:': { uc_base: '1f468-1f3fb', uc_full: '1f468-1f3fb', shortnames: [], category: 'people' }, + ':man_tone2:': { uc_base: '1f468-1f3fc', uc_full: '1f468-1f3fc', shortnames: [], category: 'people' }, + ':man_tone3:': { uc_base: '1f468-1f3fd', uc_full: '1f468-1f3fd', shortnames: [], category: 'people' }, + ':man_tone4:': { uc_base: '1f468-1f3fe', uc_full: '1f468-1f3fe', shortnames: [], category: 'people' }, + ':man_tone5:': { uc_base: '1f468-1f3ff', uc_full: '1f468-1f3ff', shortnames: [], category: 'people' }, + ':man_white_haired:': { uc_base: '1f468-1f9b3', uc_full: '1f468-200d-1f9b3', shortnames: [], category: 'people' }, + ':man_with_chinese_cap_tone1:': { + uc_base: '1f472-1f3fb', + uc_full: '1f472-1f3fb', + shortnames: [':man_with_gua_pi_mao_tone1:'], + category: 'people', + }, + ':man_with_chinese_cap_tone2:': { + uc_base: '1f472-1f3fc', + uc_full: '1f472-1f3fc', + shortnames: [':man_with_gua_pi_mao_tone2:'], + category: 'people', + }, + ':man_with_chinese_cap_tone3:': { + uc_base: '1f472-1f3fd', + uc_full: '1f472-1f3fd', + shortnames: [':man_with_gua_pi_mao_tone3:'], + category: 'people', + }, + ':man_with_chinese_cap_tone4:': { + uc_base: '1f472-1f3fe', + uc_full: '1f472-1f3fe', + shortnames: [':man_with_gua_pi_mao_tone4:'], + category: 'people', + }, + ':man_with_chinese_cap_tone5:': { + uc_base: '1f472-1f3ff', + uc_full: '1f472-1f3ff', + shortnames: [':man_with_gua_pi_mao_tone5:'], + category: 'people', + }, + ':man_with_probing_cane:': { uc_base: '1f468-1f9af', uc_full: '1f468-200d-1f9af', shortnames: [], category: 'people' }, + ':mechanic:': { uc_base: '1f9d1-1f527', uc_full: '1f9d1-200d-1f527', shortnames: [], category: 'people' }, + ':men_holding_hands_tone1:': { + uc_base: '1f46c-1f3fb', + uc_full: '1f46c-1f3fb', + shortnames: [':men_holding_hands_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone2:': { + uc_base: '1f46c-1f3fc', + uc_full: '1f46c-1f3fc', + shortnames: [':men_holding_hands_medium_light_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone3:': { + uc_base: '1f46c-1f3fd', + uc_full: '1f46c-1f3fd', + shortnames: [':men_holding_hands_medium_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone4:': { + uc_base: '1f46c-1f3fe', + uc_full: '1f46c-1f3fe', + shortnames: [':men_holding_hands_medium_dark_skin_tone:'], + category: 'people', + }, + ':men_holding_hands_tone5:': { + uc_base: '1f46c-1f3ff', + uc_full: '1f46c-1f3ff', + shortnames: [':men_holding_hands_dark_skin_tone:'], + category: 'people', + }, + ':merperson_tone1:': { + uc_base: '1f9dc-1f3fb', + uc_full: '1f9dc-1f3fb', + shortnames: [':merperson_light_skin_tone:'], + category: 'people', + }, + ':merperson_tone2:': { + uc_base: '1f9dc-1f3fc', + uc_full: '1f9dc-1f3fc', + shortnames: [':merperson_medium_light_skin_tone:'], + category: 'people', + }, + ':merperson_tone3:': { + uc_base: '1f9dc-1f3fd', + uc_full: '1f9dc-1f3fd', + shortnames: [':merperson_medium_skin_tone:'], + category: 'people', + }, + ':merperson_tone4:': { + uc_base: '1f9dc-1f3fe', + uc_full: '1f9dc-1f3fe', + shortnames: [':merperson_medium_dark_skin_tone:'], + category: 'people', + }, + ':merperson_tone5:': { uc_base: '1f9dc-1f3ff', uc_full: '1f9dc-1f3ff', shortnames: [':merperson_dark_skin_tone:'], category: 'people' }, + ':metal_tone1:': { uc_base: '1f918-1f3fb', uc_full: '1f918-1f3fb', shortnames: [':sign_of_the_horns_tone1:'], category: 'people' }, + ':metal_tone2:': { uc_base: '1f918-1f3fc', uc_full: '1f918-1f3fc', shortnames: [':sign_of_the_horns_tone2:'], category: 'people' }, + ':metal_tone3:': { uc_base: '1f918-1f3fd', uc_full: '1f918-1f3fd', shortnames: [':sign_of_the_horns_tone3:'], category: 'people' }, + ':metal_tone4:': { uc_base: '1f918-1f3fe', uc_full: '1f918-1f3fe', shortnames: [':sign_of_the_horns_tone4:'], category: 'people' }, + ':metal_tone5:': { uc_base: '1f918-1f3ff', uc_full: '1f918-1f3ff', shortnames: [':sign_of_the_horns_tone5:'], category: 'people' }, + ':middle_finger_tone1:': { + uc_base: '1f595-1f3fb', + uc_full: '1f595-1f3fb', + shortnames: [':reversed_hand_with_middle_finger_extended_tone1:'], + category: 'people', + }, + ':middle_finger_tone2:': { + uc_base: '1f595-1f3fc', + uc_full: '1f595-1f3fc', + shortnames: [':reversed_hand_with_middle_finger_extended_tone2:'], + category: 'people', + }, + ':middle_finger_tone3:': { + uc_base: '1f595-1f3fd', + uc_full: '1f595-1f3fd', + shortnames: [':reversed_hand_with_middle_finger_extended_tone3:'], + category: 'people', + }, + ':middle_finger_tone4:': { + uc_base: '1f595-1f3fe', + uc_full: '1f595-1f3fe', + shortnames: [':reversed_hand_with_middle_finger_extended_tone4:'], + category: 'people', + }, + ':middle_finger_tone5:': { + uc_base: '1f595-1f3ff', + uc_full: '1f595-1f3ff', + shortnames: [':reversed_hand_with_middle_finger_extended_tone5:'], + category: 'people', + }, + ':mrs_claus_tone1:': { uc_base: '1f936-1f3fb', uc_full: '1f936-1f3fb', shortnames: [':mother_christmas_tone1:'], category: 'people' }, + ':mrs_claus_tone2:': { uc_base: '1f936-1f3fc', uc_full: '1f936-1f3fc', shortnames: [':mother_christmas_tone2:'], category: 'people' }, + ':mrs_claus_tone3:': { uc_base: '1f936-1f3fd', uc_full: '1f936-1f3fd', shortnames: [':mother_christmas_tone3:'], category: 'people' }, + ':mrs_claus_tone4:': { uc_base: '1f936-1f3fe', uc_full: '1f936-1f3fe', shortnames: [':mother_christmas_tone4:'], category: 'people' }, + ':mrs_claus_tone5:': { uc_base: '1f936-1f3ff', uc_full: '1f936-1f3ff', shortnames: [':mother_christmas_tone5:'], category: 'people' }, + ':muscle_tone1:': { uc_base: '1f4aa-1f3fb', uc_full: '1f4aa-1f3fb', shortnames: [], category: 'people' }, + ':muscle_tone2:': { uc_base: '1f4aa-1f3fc', uc_full: '1f4aa-1f3fc', shortnames: [], category: 'people' }, + ':muscle_tone3:': { uc_base: '1f4aa-1f3fd', uc_full: '1f4aa-1f3fd', shortnames: [], category: 'people' }, + ':muscle_tone4:': { uc_base: '1f4aa-1f3fe', uc_full: '1f4aa-1f3fe', shortnames: [], category: 'people' }, + ':muscle_tone5:': { uc_base: '1f4aa-1f3ff', uc_full: '1f4aa-1f3ff', shortnames: [], category: 'people' }, + ':mx_claus:': { uc_base: '1f9d1-1f384', uc_full: '1f9d1-200d-1f384', shortnames: [], category: 'people' }, + ':nail_care_tone1:': { uc_base: '1f485-1f3fb', uc_full: '1f485-1f3fb', shortnames: [], category: 'people' }, + ':nail_care_tone2:': { uc_base: '1f485-1f3fc', uc_full: '1f485-1f3fc', shortnames: [], category: 'people' }, + ':nail_care_tone3:': { uc_base: '1f485-1f3fd', uc_full: '1f485-1f3fd', shortnames: [], category: 'people' }, + ':nail_care_tone4:': { uc_base: '1f485-1f3fe', uc_full: '1f485-1f3fe', shortnames: [], category: 'people' }, + ':nail_care_tone5:': { uc_base: '1f485-1f3ff', uc_full: '1f485-1f3ff', shortnames: [], category: 'people' }, + ':ninja_tone1:': { uc_base: '1f977-1f3fb', uc_full: '1f977-1f3fb', shortnames: [':ninja_light_skin_tone:'], category: 'people' }, + ':ninja_tone2:': { uc_base: '1f977-1f3fc', uc_full: '1f977-1f3fc', shortnames: [':ninja_medium_light_skin_tone:'], category: 'people' }, + ':ninja_tone3:': { uc_base: '1f977-1f3fd', uc_full: '1f977-1f3fd', shortnames: [':ninja_medium_skin_tone:'], category: 'people' }, + ':ninja_tone4:': { uc_base: '1f977-1f3fe', uc_full: '1f977-1f3fe', shortnames: [':ninja_medium_dark_skin_tone:'], category: 'people' }, + ':ninja_tone5:': { uc_base: '1f977-1f3ff', uc_full: '1f977-1f3ff', shortnames: [':ninja_dark_skin_tone:'], category: 'people' }, + ':nose_tone1:': { uc_base: '1f443-1f3fb', uc_full: '1f443-1f3fb', shortnames: [], category: 'people' }, + ':nose_tone2:': { uc_base: '1f443-1f3fc', uc_full: '1f443-1f3fc', shortnames: [], category: 'people' }, + ':nose_tone3:': { uc_base: '1f443-1f3fd', uc_full: '1f443-1f3fd', shortnames: [], category: 'people' }, + ':nose_tone4:': { uc_base: '1f443-1f3fe', uc_full: '1f443-1f3fe', shortnames: [], category: 'people' }, + ':nose_tone5:': { uc_base: '1f443-1f3ff', uc_full: '1f443-1f3ff', shortnames: [], category: 'people' }, + ':office_worker:': { uc_base: '1f9d1-1f4bc', uc_full: '1f9d1-200d-1f4bc', shortnames: [], category: 'people' }, + ':ok_hand_tone1:': { uc_base: '1f44c-1f3fb', uc_full: '1f44c-1f3fb', shortnames: [], category: 'people' }, + ':ok_hand_tone2:': { uc_base: '1f44c-1f3fc', uc_full: '1f44c-1f3fc', shortnames: [], category: 'people' }, + ':ok_hand_tone3:': { uc_base: '1f44c-1f3fd', uc_full: '1f44c-1f3fd', shortnames: [], category: 'people' }, + ':ok_hand_tone4:': { uc_base: '1f44c-1f3fe', uc_full: '1f44c-1f3fe', shortnames: [], category: 'people' }, + ':ok_hand_tone5:': { + uc_base: '1f44c-1f3ff', + uc_full: '1f44c-1f3ff', + shortnames: [], + category: 'people', + }, + ':older_adult_tone1:': { + uc_base: '1f9d3-1f3fb', + uc_full: '1f9d3-1f3fb', + shortnames: [':older_adult_light_skin_tone:'], + category: 'people', + }, + ':older_adult_tone2:': { + uc_base: '1f9d3-1f3fc', + uc_full: '1f9d3-1f3fc', + shortnames: [':older_adult_medium_light_skin_tone:'], + category: 'people', + }, + ':older_adult_tone3:': { + uc_base: '1f9d3-1f3fd', + uc_full: '1f9d3-1f3fd', + shortnames: [':older_adult_medium_skin_tone:'], + category: 'people', + }, + ':older_adult_tone4:': { + uc_base: '1f9d3-1f3fe', + uc_full: '1f9d3-1f3fe', + shortnames: [':older_adult_medium_dark_skin_tone:'], + category: 'people', + }, + ':older_adult_tone5:': { + uc_base: '1f9d3-1f3ff', + uc_full: '1f9d3-1f3ff', + shortnames: [':older_adult_dark_skin_tone:'], + category: 'people', + }, + ':older_man_tone1:': { uc_base: '1f474-1f3fb', uc_full: '1f474-1f3fb', shortnames: [], category: 'people' }, + ':older_man_tone2:': { uc_base: '1f474-1f3fc', uc_full: '1f474-1f3fc', shortnames: [], category: 'people' }, + ':older_man_tone3:': { uc_base: '1f474-1f3fd', uc_full: '1f474-1f3fd', shortnames: [], category: 'people' }, + ':older_man_tone4:': { uc_base: '1f474-1f3fe', uc_full: '1f474-1f3fe', shortnames: [], category: 'people' }, + ':older_man_tone5:': { uc_base: '1f474-1f3ff', uc_full: '1f474-1f3ff', shortnames: [], category: 'people' }, + ':older_woman_tone1:': { uc_base: '1f475-1f3fb', uc_full: '1f475-1f3fb', shortnames: [':grandma_tone1:'], category: 'people' }, + ':older_woman_tone2:': { uc_base: '1f475-1f3fc', uc_full: '1f475-1f3fc', shortnames: [':grandma_tone2:'], category: 'people' }, + ':older_woman_tone3:': { uc_base: '1f475-1f3fd', uc_full: '1f475-1f3fd', shortnames: [':grandma_tone3:'], category: 'people' }, + ':older_woman_tone4:': { uc_base: '1f475-1f3fe', uc_full: '1f475-1f3fe', shortnames: [':grandma_tone4:'], category: 'people' }, + ':older_woman_tone5:': { uc_base: '1f475-1f3ff', uc_full: '1f475-1f3ff', shortnames: [':grandma_tone5:'], category: 'people' }, + ':open_hands_tone1:': { uc_base: '1f450-1f3fb', uc_full: '1f450-1f3fb', shortnames: [], category: 'people' }, + ':open_hands_tone2:': { uc_base: '1f450-1f3fc', uc_full: '1f450-1f3fc', shortnames: [], category: 'people' }, + ':open_hands_tone3:': { uc_base: '1f450-1f3fd', uc_full: '1f450-1f3fd', shortnames: [], category: 'people' }, + ':open_hands_tone4:': { uc_base: '1f450-1f3fe', uc_full: '1f450-1f3fe', shortnames: [], category: 'people' }, + ':open_hands_tone5:': { uc_base: '1f450-1f3ff', uc_full: '1f450-1f3ff', shortnames: [], category: 'people' }, + ':palms_up_together_tone1:': { + uc_base: '1f932-1f3fb', + uc_full: '1f932-1f3fb', + shortnames: [':palms_up_together_light_skin_tone:'], + category: 'people', + }, + ':palms_up_together_tone2:': { + uc_base: '1f932-1f3fc', + uc_full: '1f932-1f3fc', + shortnames: [':palms_up_together_medium_light_skin_tone:'], + category: 'people', + }, + ':palms_up_together_tone3:': { + uc_base: '1f932-1f3fd', + uc_full: '1f932-1f3fd', + shortnames: [':palms_up_together_medium_skin_tone:'], + category: 'people', + }, + ':palms_up_together_tone4:': { + uc_base: '1f932-1f3fe', + uc_full: '1f932-1f3fe', + shortnames: [':palms_up_together_medium_dark_skin_tone:'], + category: 'people', + }, + ':palms_up_together_tone5:': { + uc_base: '1f932-1f3ff', + uc_full: '1f932-1f3ff', + shortnames: [':palms_up_together_dark_skin_tone:'], + category: 'people', + }, + ':person_bald:': { uc_base: '1f9d1-1f9b2', uc_full: '1f9d1-200d-1f9b2', shortnames: [], category: 'people' }, + ':person_biking_tone1:': { uc_base: '1f6b4-1f3fb', uc_full: '1f6b4-1f3fb', shortnames: [':bicyclist_tone1:'], category: 'activity' }, + ':person_biking_tone2:': { uc_base: '1f6b4-1f3fc', uc_full: '1f6b4-1f3fc', shortnames: [':bicyclist_tone2:'], category: 'activity' }, + ':person_biking_tone3:': { uc_base: '1f6b4-1f3fd', uc_full: '1f6b4-1f3fd', shortnames: [':bicyclist_tone3:'], category: 'activity' }, + ':person_biking_tone4:': { uc_base: '1f6b4-1f3fe', uc_full: '1f6b4-1f3fe', shortnames: [':bicyclist_tone4:'], category: 'activity' }, + ':person_biking_tone5:': { uc_base: '1f6b4-1f3ff', uc_full: '1f6b4-1f3ff', shortnames: [':bicyclist_tone5:'], category: 'activity' }, + ':person_bowing_tone1:': { uc_base: '1f647-1f3fb', uc_full: '1f647-1f3fb', shortnames: [':bow_tone1:'], category: 'people' }, + ':person_bowing_tone2:': { uc_base: '1f647-1f3fc', uc_full: '1f647-1f3fc', shortnames: [':bow_tone2:'], category: 'people' }, + ':person_bowing_tone3:': { uc_base: '1f647-1f3fd', uc_full: '1f647-1f3fd', shortnames: [':bow_tone3:'], category: 'people' }, + ':person_bowing_tone4:': { uc_base: '1f647-1f3fe', uc_full: '1f647-1f3fe', shortnames: [':bow_tone4:'], category: 'people' }, + ':person_bowing_tone5:': { uc_base: '1f647-1f3ff', uc_full: '1f647-1f3ff', shortnames: [':bow_tone5:'], category: 'people' }, + ':person_climbing_tone1:': { + uc_base: '1f9d7-1f3fb', + uc_full: '1f9d7-1f3fb', + shortnames: [':person_climbing_light_skin_tone:'], + category: 'activity', + }, + ':person_climbing_tone2:': { + uc_base: '1f9d7-1f3fc', + uc_full: '1f9d7-1f3fc', + shortnames: [':person_climbing_medium_light_skin_tone:'], + category: 'activity', + }, + ':person_climbing_tone3:': { + uc_base: '1f9d7-1f3fd', + uc_full: '1f9d7-1f3fd', + shortnames: [':person_climbing_medium_skin_tone:'], + category: 'activity', + }, + ':person_climbing_tone4:': { + uc_base: '1f9d7-1f3fe', + uc_full: '1f9d7-1f3fe', + shortnames: [':person_climbing_medium_dark_skin_tone:'], + category: 'activity', + }, + ':person_climbing_tone5:': { + uc_base: '1f9d7-1f3ff', + uc_full: '1f9d7-1f3ff', + shortnames: [':person_climbing_dark_skin_tone:'], + category: 'activity', + }, + ':person_curly_hair:': { uc_base: '1f9d1-1f9b1', uc_full: '1f9d1-200d-1f9b1', shortnames: [], category: 'people' }, + ':person_doing_cartwheel_tone1:': { + uc_base: '1f938-1f3fb', + uc_full: '1f938-1f3fb', + shortnames: [':cartwheel_tone1:'], + category: 'activity', + }, + ':person_doing_cartwheel_tone2:': { + uc_base: '1f938-1f3fc', + uc_full: '1f938-1f3fc', + shortnames: [':cartwheel_tone2:'], + category: 'activity', + }, + ':person_doing_cartwheel_tone3:': { + uc_base: '1f938-1f3fd', + uc_full: '1f938-1f3fd', + shortnames: [':cartwheel_tone3:'], + category: 'activity', + }, + ':person_doing_cartwheel_tone4:': { + uc_base: '1f938-1f3fe', + uc_full: '1f938-1f3fe', + shortnames: [':cartwheel_tone4:'], + category: 'activity', + }, + ':person_doing_cartwheel_tone5:': { + uc_base: '1f938-1f3ff', + uc_full: '1f938-1f3ff', + shortnames: [':cartwheel_tone5:'], + category: 'activity', + }, + ':person_facepalming_tone1:': { + uc_base: '1f926-1f3fb', + uc_full: '1f926-1f3fb', + shortnames: [':face_palm_tone1:', ':facepalm_tone1:'], + category: 'people', + }, + ':person_facepalming_tone2:': { + uc_base: '1f926-1f3fc', + uc_full: '1f926-1f3fc', + shortnames: [':face_palm_tone2:', ':facepalm_tone2:'], + category: 'people', + }, + ':person_facepalming_tone3:': { + uc_base: '1f926-1f3fd', + uc_full: '1f926-1f3fd', + shortnames: [':face_palm_tone3:', ':facepalm_tone3:'], + category: 'people', + }, + ':person_facepalming_tone4:': { + uc_base: '1f926-1f3fe', + uc_full: '1f926-1f3fe', + shortnames: [':face_palm_tone4:', ':facepalm_tone4:'], + category: 'people', + }, + ':person_facepalming_tone5:': { + uc_base: '1f926-1f3ff', + uc_full: '1f926-1f3ff', + shortnames: [':face_palm_tone5:', ':facepalm_tone5:'], + category: 'people', + }, + ':person_feeding_baby:': { uc_base: '1f9d1-1f37c', uc_full: '1f9d1-200d-1f37c', shortnames: [], category: 'people' }, + ':person_frowning_tone1:': { uc_base: '1f64d-1f3fb', uc_full: '1f64d-1f3fb', shortnames: [], category: 'people' }, + ':person_frowning_tone2:': { uc_base: '1f64d-1f3fc', uc_full: '1f64d-1f3fc', shortnames: [], category: 'people' }, + ':person_frowning_tone3:': { uc_base: '1f64d-1f3fd', uc_full: '1f64d-1f3fd', shortnames: [], category: 'people' }, + ':person_frowning_tone4:': { uc_base: '1f64d-1f3fe', uc_full: '1f64d-1f3fe', shortnames: [], category: 'people' }, + ':person_frowning_tone5:': { uc_base: '1f64d-1f3ff', uc_full: '1f64d-1f3ff', shortnames: [], category: 'people' }, + ':person_gesturing_no_tone1:': { uc_base: '1f645-1f3fb', uc_full: '1f645-1f3fb', shortnames: [':no_good_tone1:'], category: 'people' }, + ':person_gesturing_no_tone2:': { uc_base: '1f645-1f3fc', uc_full: '1f645-1f3fc', shortnames: [':no_good_tone2:'], category: 'people' }, + ':person_gesturing_no_tone3:': { uc_base: '1f645-1f3fd', uc_full: '1f645-1f3fd', shortnames: [':no_good_tone3:'], category: 'people' }, + ':person_gesturing_no_tone4:': { uc_base: '1f645-1f3fe', uc_full: '1f645-1f3fe', shortnames: [':no_good_tone4:'], category: 'people' }, + ':person_gesturing_no_tone5:': { uc_base: '1f645-1f3ff', uc_full: '1f645-1f3ff', shortnames: [':no_good_tone5:'], category: 'people' }, + ':person_gesturing_ok_tone1:': { uc_base: '1f646-1f3fb', uc_full: '1f646-1f3fb', shortnames: [':ok_woman_tone1:'], category: 'people' }, + ':person_gesturing_ok_tone2:': { uc_base: '1f646-1f3fc', uc_full: '1f646-1f3fc', shortnames: [':ok_woman_tone2:'], category: 'people' }, + ':person_gesturing_ok_tone3:': { uc_base: '1f646-1f3fd', uc_full: '1f646-1f3fd', shortnames: [':ok_woman_tone3:'], category: 'people' }, + ':person_gesturing_ok_tone4:': { uc_base: '1f646-1f3fe', uc_full: '1f646-1f3fe', shortnames: [':ok_woman_tone4:'], category: 'people' }, + ':person_gesturing_ok_tone5:': { uc_base: '1f646-1f3ff', uc_full: '1f646-1f3ff', shortnames: [':ok_woman_tone5:'], category: 'people' }, + ':person_getting_haircut_tone1:': { + uc_base: '1f487-1f3fb', + uc_full: '1f487-1f3fb', + shortnames: [':haircut_tone1:'], + category: 'people', + }, + ':person_getting_haircut_tone2:': { + uc_base: '1f487-1f3fc', + uc_full: '1f487-1f3fc', + shortnames: [':haircut_tone2:'], + category: 'people', + }, + ':person_getting_haircut_tone3:': { + uc_base: '1f487-1f3fd', + uc_full: '1f487-1f3fd', + shortnames: [':haircut_tone3:'], + category: 'people', + }, + ':person_getting_haircut_tone4:': { + uc_base: '1f487-1f3fe', + uc_full: '1f487-1f3fe', + shortnames: [':haircut_tone4:'], + category: 'people', + }, + ':person_getting_haircut_tone5:': { + uc_base: '1f487-1f3ff', + uc_full: '1f487-1f3ff', + shortnames: [':haircut_tone5:'], + category: 'people', + }, + ':person_getting_massage_tone1:': { + uc_base: '1f486-1f3fb', + uc_full: '1f486-1f3fb', + shortnames: [':massage_tone1:'], + category: 'people', + }, + ':person_getting_massage_tone2:': { + uc_base: '1f486-1f3fc', + uc_full: '1f486-1f3fc', + shortnames: [':massage_tone2:'], + category: 'people', + }, + ':person_getting_massage_tone3:': { + uc_base: '1f486-1f3fd', + uc_full: '1f486-1f3fd', + shortnames: [':massage_tone3:'], + category: 'people', + }, + ':person_getting_massage_tone4:': { + uc_base: '1f486-1f3fe', + uc_full: '1f486-1f3fe', + shortnames: [':massage_tone4:'], + category: 'people', + }, + ':person_getting_massage_tone5:': { + uc_base: '1f486-1f3ff', + uc_full: '1f486-1f3ff', + shortnames: [':massage_tone5:'], + category: 'people', + }, + ':person_golfing_tone1:': { + uc_base: '1f3cc-1f3fb', + uc_full: '1f3cc-1f3fb', + shortnames: [':person_golfing_light_skin_tone:'], + category: 'activity', + }, + ':person_golfing_tone2:': { + uc_base: '1f3cc-1f3fc', + uc_full: '1f3cc-1f3fc', + shortnames: [':person_golfing_medium_light_skin_tone:'], + category: 'activity', + }, + ':person_golfing_tone3:': { + uc_base: '1f3cc-1f3fd', + uc_full: '1f3cc-1f3fd', + shortnames: [':person_golfing_medium_skin_tone:'], + category: 'activity', + }, + ':person_golfing_tone4:': { + uc_base: '1f3cc-1f3fe', + uc_full: '1f3cc-1f3fe', + shortnames: [':person_golfing_medium_dark_skin_tone:'], + category: 'activity', + }, + ':person_golfing_tone5:': { + uc_base: '1f3cc-1f3ff', + uc_full: '1f3cc-1f3ff', + shortnames: [':person_golfing_dark_skin_tone:'], + category: 'activity', + }, + ':person_in_bed_tone1:': { + uc_base: '1f6cc-1f3fb', + uc_full: '1f6cc-1f3fb', + shortnames: [':person_in_bed_light_skin_tone:'], + category: 'objects', + }, + ':person_in_bed_tone2:': { + uc_base: '1f6cc-1f3fc', + uc_full: '1f6cc-1f3fc', + shortnames: [':person_in_bed_medium_light_skin_tone:'], + category: 'objects', + }, + ':person_in_bed_tone3:': { + uc_base: '1f6cc-1f3fd', + uc_full: '1f6cc-1f3fd', + shortnames: [':person_in_bed_medium_skin_tone:'], + category: 'objects', + }, + ':person_in_bed_tone4:': { + uc_base: '1f6cc-1f3fe', + uc_full: '1f6cc-1f3fe', + shortnames: [':person_in_bed_medium_dark_skin_tone:'], + category: 'objects', + }, + ':person_in_bed_tone5:': { + uc_base: '1f6cc-1f3ff', + uc_full: '1f6cc-1f3ff', + shortnames: [':person_in_bed_dark_skin_tone:'], + category: 'objects', + }, + ':person_in_lotus_position_tone1:': { + uc_base: '1f9d8-1f3fb', + uc_full: '1f9d8-1f3fb', + shortnames: [':person_in_lotus_position_light_skin_tone:'], + category: 'activity', + }, + ':person_in_lotus_position_tone2:': { + uc_base: '1f9d8-1f3fc', + uc_full: '1f9d8-1f3fc', + shortnames: [':person_in_lotus_position_medium_light_skin_tone:'], + category: 'activity', + }, + ':person_in_lotus_position_tone3:': { + uc_base: '1f9d8-1f3fd', + uc_full: '1f9d8-1f3fd', + shortnames: [':person_in_lotus_position_medium_skin_tone:'], + category: 'activity', + }, + ':person_in_lotus_position_tone4:': { + uc_base: '1f9d8-1f3fe', + uc_full: '1f9d8-1f3fe', + shortnames: [':person_in_lotus_position_medium_dark_skin_tone:'], + category: 'activity', + }, + ':person_in_lotus_position_tone5:': { + uc_base: '1f9d8-1f3ff', + uc_full: '1f9d8-1f3ff', + shortnames: [':person_in_lotus_position_dark_skin_tone:'], + category: 'activity', + }, + ':person_in_manual_wheelchair:': { uc_base: '1f9d1-1f9bd', uc_full: '1f9d1-200d-1f9bd', shortnames: [], category: 'people' }, + ':person_in_motorized_wheelchair:': { uc_base: '1f9d1-1f9bc', uc_full: '1f9d1-200d-1f9bc', shortnames: [], category: 'people' }, + ':person_in_steamy_room_tone1:': { + uc_base: '1f9d6-1f3fb', + uc_full: '1f9d6-1f3fb', + shortnames: [':person_in_steamy_room_light_skin_tone:'], + category: 'people', + }, + ':person_in_steamy_room_tone2:': { + uc_base: '1f9d6-1f3fc', + uc_full: '1f9d6-1f3fc', + shortnames: [':person_in_steamy_room_medium_light_skin_tone:'], + category: 'people', + }, + ':person_in_steamy_room_tone3:': { + uc_base: '1f9d6-1f3fd', + uc_full: '1f9d6-1f3fd', + shortnames: [':person_in_steamy_room_medium_skin_tone:'], + category: 'people', + }, + ':person_in_steamy_room_tone4:': { + uc_base: '1f9d6-1f3fe', + uc_full: '1f9d6-1f3fe', + shortnames: [':person_in_steamy_room_medium_dark_skin_tone:'], + category: 'people', + }, + ':person_in_steamy_room_tone5:': { + uc_base: '1f9d6-1f3ff', + uc_full: '1f9d6-1f3ff', + shortnames: [':person_in_steamy_room_dark_skin_tone:'], + category: 'people', + }, + ':person_in_tuxedo_tone1:': { uc_base: '1f935-1f3fb', uc_full: '1f935-1f3fb', shortnames: [':tuxedo_tone1:'], category: 'people' }, + ':person_in_tuxedo_tone2:': { uc_base: '1f935-1f3fc', uc_full: '1f935-1f3fc', shortnames: [':tuxedo_tone2:'], category: 'people' }, + ':person_in_tuxedo_tone3:': { uc_base: '1f935-1f3fd', uc_full: '1f935-1f3fd', shortnames: [':tuxedo_tone3:'], category: 'people' }, + ':person_in_tuxedo_tone4:': { uc_base: '1f935-1f3fe', uc_full: '1f935-1f3fe', shortnames: [':tuxedo_tone4:'], category: 'people' }, + ':person_in_tuxedo_tone5:': { uc_base: '1f935-1f3ff', uc_full: '1f935-1f3ff', shortnames: [':tuxedo_tone5:'], category: 'people' }, + ':person_juggling_tone1:': { + uc_base: '1f939-1f3fb', + uc_full: '1f939-1f3fb', + shortnames: [':juggling_tone1:', ':juggler_tone1:'], + category: 'activity', + }, + ':person_juggling_tone2:': { + uc_base: '1f939-1f3fc', + uc_full: '1f939-1f3fc', + shortnames: [':juggling_tone2:', ':juggler_tone2:'], + category: 'activity', + }, + ':person_juggling_tone3:': { + uc_base: '1f939-1f3fd', + uc_full: '1f939-1f3fd', + shortnames: [':juggling_tone3:', ':juggler_tone3:'], + category: 'activity', + }, + ':person_juggling_tone4:': { + uc_base: '1f939-1f3fe', + uc_full: '1f939-1f3fe', + shortnames: [':juggling_tone4:', ':juggler_tone4:'], + category: 'activity', + }, + ':person_juggling_tone5:': { + uc_base: '1f939-1f3ff', + uc_full: '1f939-1f3ff', + shortnames: [':juggling_tone5:', ':juggler_tone5:'], + category: 'activity', + }, + ':person_kneeling_tone1:': { + uc_base: '1f9ce-1f3fb', + uc_full: '1f9ce-1f3fb', + shortnames: [':person_kneeling_light_skin_tone:'], + category: 'people', + }, + ':person_kneeling_tone2:': { + uc_base: '1f9ce-1f3fc', + uc_full: '1f9ce-1f3fc', + shortnames: [':person_kneeling_medium_light_skin_tone:'], + category: 'people', + }, + ':person_kneeling_tone3:': { + uc_base: '1f9ce-1f3fd', + uc_full: '1f9ce-1f3fd', + shortnames: [':person_kneeling_medium_skin_tone:'], + category: 'people', + }, + ':person_kneeling_tone4:': { + uc_base: '1f9ce-1f3fe', + uc_full: '1f9ce-1f3fe', + shortnames: [':person_kneeling_medium_dark_skin_tone:'], + category: 'people', + }, + ':person_kneeling_tone5:': { + uc_base: '1f9ce-1f3ff', + uc_full: '1f9ce-1f3ff', + shortnames: [':person_kneeling_dark_skin_tone:'], + category: 'people', + }, + ':person_lifting_weights_tone1:': { + uc_base: '1f3cb-1f3fb', + uc_full: '1f3cb-1f3fb', + shortnames: [':lifter_tone1:', ':weight_lifter_tone1:'], + category: 'activity', + }, + ':person_lifting_weights_tone2:': { + uc_base: '1f3cb-1f3fc', + uc_full: '1f3cb-1f3fc', + shortnames: [':lifter_tone2:', ':weight_lifter_tone2:'], + category: 'activity', + }, + ':person_lifting_weights_tone3:': { + uc_base: '1f3cb-1f3fd', + uc_full: '1f3cb-1f3fd', + shortnames: [':lifter_tone3:', ':weight_lifter_tone3:'], + category: 'activity', + }, + ':person_lifting_weights_tone4:': { + uc_base: '1f3cb-1f3fe', + uc_full: '1f3cb-1f3fe', + shortnames: [':lifter_tone4:', ':weight_lifter_tone4:'], + category: 'activity', + }, + ':person_lifting_weights_tone5:': { + uc_base: '1f3cb-1f3ff', + uc_full: '1f3cb-1f3ff', + shortnames: [':lifter_tone5:', ':weight_lifter_tone5:'], + category: 'activity', + }, + ':person_mountain_biking_tone1:': { + uc_base: '1f6b5-1f3fb', + uc_full: '1f6b5-1f3fb', + shortnames: [':mountain_bicyclist_tone1:'], + category: 'activity', + }, + ':person_mountain_biking_tone2:': { + uc_base: '1f6b5-1f3fc', + uc_full: '1f6b5-1f3fc', + shortnames: [':mountain_bicyclist_tone2:'], + category: 'activity', + }, + ':person_mountain_biking_tone3:': { + uc_base: '1f6b5-1f3fd', + uc_full: '1f6b5-1f3fd', + shortnames: [':mountain_bicyclist_tone3:'], + category: 'activity', + }, + ':person_mountain_biking_tone4:': { + uc_base: '1f6b5-1f3fe', + uc_full: '1f6b5-1f3fe', + shortnames: [':mountain_bicyclist_tone4:'], + category: 'activity', + }, + ':person_mountain_biking_tone5:': { + uc_base: '1f6b5-1f3ff', + uc_full: '1f6b5-1f3ff', + shortnames: [':mountain_bicyclist_tone5:'], + category: 'activity', + }, + ':person_playing_handball_tone1:': { + uc_base: '1f93e-1f3fb', + uc_full: '1f93e-1f3fb', + shortnames: [':handball_tone1:'], + category: 'activity', + }, + ':person_playing_handball_tone2:': { + uc_base: '1f93e-1f3fc', + uc_full: '1f93e-1f3fc', + shortnames: [':handball_tone2:'], + category: 'activity', + }, + ':person_playing_handball_tone3:': { + uc_base: '1f93e-1f3fd', + uc_full: '1f93e-1f3fd', + shortnames: [':handball_tone3:'], + category: 'activity', + }, + ':person_playing_handball_tone4:': { + uc_base: '1f93e-1f3fe', + uc_full: '1f93e-1f3fe', + shortnames: [':handball_tone4:'], + category: 'activity', + }, + ':person_playing_handball_tone5:': { + uc_base: '1f93e-1f3ff', + uc_full: '1f93e-1f3ff', + shortnames: [':handball_tone5:'], + category: 'activity', + }, + ':person_playing_water_polo_tone1:': { + uc_base: '1f93d-1f3fb', + uc_full: '1f93d-1f3fb', + shortnames: [':water_polo_tone1:'], + category: 'activity', + }, + ':person_playing_water_polo_tone2:': { + uc_base: '1f93d-1f3fc', + uc_full: '1f93d-1f3fc', + shortnames: [':water_polo_tone2:'], + category: 'activity', + }, + ':person_playing_water_polo_tone3:': { + uc_base: '1f93d-1f3fd', + uc_full: '1f93d-1f3fd', + shortnames: [':water_polo_tone3:'], + category: 'activity', + }, + ':person_playing_water_polo_tone4:': { + uc_base: '1f93d-1f3fe', + uc_full: '1f93d-1f3fe', + shortnames: [':water_polo_tone4:'], + category: 'activity', + }, + ':person_playing_water_polo_tone5:': { + uc_base: '1f93d-1f3ff', + uc_full: '1f93d-1f3ff', + shortnames: [':water_polo_tone5:'], + category: 'activity', + }, + ':person_pouting_tone1:': { + uc_base: '1f64e-1f3fb', + uc_full: '1f64e-1f3fb', + shortnames: [':person_with_pouting_face_tone1:'], + category: 'people', + }, + ':person_pouting_tone2:': { + uc_base: '1f64e-1f3fc', + uc_full: '1f64e-1f3fc', + shortnames: [':person_with_pouting_face_tone2:'], + category: 'people', + }, + ':person_pouting_tone3:': { + uc_base: '1f64e-1f3fd', + uc_full: '1f64e-1f3fd', + shortnames: [':person_with_pouting_face_tone3:'], + category: 'people', + }, + ':person_pouting_tone4:': { + uc_base: '1f64e-1f3fe', + uc_full: '1f64e-1f3fe', + shortnames: [':person_with_pouting_face_tone4:'], + category: 'people', + }, + ':person_pouting_tone5:': { + uc_base: '1f64e-1f3ff', + uc_full: '1f64e-1f3ff', + shortnames: [':person_with_pouting_face_tone5:'], + category: 'people', + }, + ':person_raising_hand_tone1:': { + uc_base: '1f64b-1f3fb', + uc_full: '1f64b-1f3fb', + shortnames: [':raising_hand_tone1:'], + category: 'people', + }, + ':person_raising_hand_tone2:': { + uc_base: '1f64b-1f3fc', + uc_full: '1f64b-1f3fc', + shortnames: [':raising_hand_tone2:'], + category: 'people', + }, + ':person_raising_hand_tone3:': { + uc_base: '1f64b-1f3fd', + uc_full: '1f64b-1f3fd', + shortnames: [':raising_hand_tone3:'], + category: 'people', + }, + ':person_raising_hand_tone4:': { + uc_base: '1f64b-1f3fe', + uc_full: '1f64b-1f3fe', + shortnames: [':raising_hand_tone4:'], + category: 'people', + }, + ':person_raising_hand_tone5:': { + uc_base: '1f64b-1f3ff', + uc_full: '1f64b-1f3ff', + shortnames: [':raising_hand_tone5:'], + category: 'people', + }, + ':person_red_hair:': { uc_base: '1f9d1-1f9b0', uc_full: '1f9d1-200d-1f9b0', shortnames: [], category: 'people' }, + ':person_rowing_boat_tone1:': { uc_base: '1f6a3-1f3fb', uc_full: '1f6a3-1f3fb', shortnames: [':rowboat_tone1:'], category: 'activity' }, + ':person_rowing_boat_tone2:': { uc_base: '1f6a3-1f3fc', uc_full: '1f6a3-1f3fc', shortnames: [':rowboat_tone2:'], category: 'activity' }, + ':person_rowing_boat_tone3:': { uc_base: '1f6a3-1f3fd', uc_full: '1f6a3-1f3fd', shortnames: [':rowboat_tone3:'], category: 'activity' }, + ':person_rowing_boat_tone4:': { uc_base: '1f6a3-1f3fe', uc_full: '1f6a3-1f3fe', shortnames: [':rowboat_tone4:'], category: 'activity' }, + ':person_rowing_boat_tone5:': { uc_base: '1f6a3-1f3ff', uc_full: '1f6a3-1f3ff', shortnames: [':rowboat_tone5:'], category: 'activity' }, + ':person_running_tone1:': { uc_base: '1f3c3-1f3fb', uc_full: '1f3c3-1f3fb', shortnames: [':runner_tone1:'], category: 'people' }, + ':person_running_tone2:': { uc_base: '1f3c3-1f3fc', uc_full: '1f3c3-1f3fc', shortnames: [':runner_tone2:'], category: 'people' }, + ':person_running_tone3:': { uc_base: '1f3c3-1f3fd', uc_full: '1f3c3-1f3fd', shortnames: [':runner_tone3:'], category: 'people' }, + ':person_running_tone4:': { uc_base: '1f3c3-1f3fe', uc_full: '1f3c3-1f3fe', shortnames: [':runner_tone4:'], category: 'people' }, + ':person_running_tone5:': { uc_base: '1f3c3-1f3ff', uc_full: '1f3c3-1f3ff', shortnames: [':runner_tone5:'], category: 'people' }, + ':person_shrugging_tone1:': { uc_base: '1f937-1f3fb', uc_full: '1f937-1f3fb', shortnames: [':shrug_tone1:'], category: 'people' }, + ':person_shrugging_tone2:': { uc_base: '1f937-1f3fc', uc_full: '1f937-1f3fc', shortnames: [':shrug_tone2:'], category: 'people' }, + ':person_shrugging_tone3:': { uc_base: '1f937-1f3fd', uc_full: '1f937-1f3fd', shortnames: [':shrug_tone3:'], category: 'people' }, + ':person_shrugging_tone4:': { uc_base: '1f937-1f3fe', uc_full: '1f937-1f3fe', shortnames: [':shrug_tone4:'], category: 'people' }, + ':person_shrugging_tone5:': { uc_base: '1f937-1f3ff', uc_full: '1f937-1f3ff', shortnames: [':shrug_tone5:'], category: 'people' }, + ':person_standing_tone1:': { + uc_base: '1f9cd-1f3fb', + uc_full: '1f9cd-1f3fb', + shortnames: [':person_standing_light_skin_tone:'], + category: 'people', + }, + ':person_standing_tone2:': { + uc_base: '1f9cd-1f3fc', + uc_full: '1f9cd-1f3fc', + shortnames: [':person_standing_medium_light_skin_tone:'], + category: 'people', + }, + ':person_standing_tone3:': { + uc_base: '1f9cd-1f3fd', + uc_full: '1f9cd-1f3fd', + shortnames: [':person_standing_medium_skin_tone:'], + category: 'people', + }, + ':person_standing_tone4:': { + uc_base: '1f9cd-1f3fe', + uc_full: '1f9cd-1f3fe', + shortnames: [':person_standing_medium_dark_skin_tone:'], + category: 'people', + }, + ':person_standing_tone5:': { + uc_base: '1f9cd-1f3ff', + uc_full: '1f9cd-1f3ff', + shortnames: [':person_standing_dark_skin_tone:'], + category: 'people', + }, + ':person_surfing_tone1:': { uc_base: '1f3c4-1f3fb', uc_full: '1f3c4-1f3fb', shortnames: [':surfer_tone1:'], category: 'activity' }, + ':person_surfing_tone2:': { uc_base: '1f3c4-1f3fc', uc_full: '1f3c4-1f3fc', shortnames: [':surfer_tone2:'], category: 'activity' }, + ':person_surfing_tone3:': { uc_base: '1f3c4-1f3fd', uc_full: '1f3c4-1f3fd', shortnames: [':surfer_tone3:'], category: 'activity' }, + ':person_surfing_tone4:': { uc_base: '1f3c4-1f3fe', uc_full: '1f3c4-1f3fe', shortnames: [':surfer_tone4:'], category: 'activity' }, + ':person_surfing_tone5:': { uc_base: '1f3c4-1f3ff', uc_full: '1f3c4-1f3ff', shortnames: [':surfer_tone5:'], category: 'activity' }, + ':person_swimming_tone1:': { uc_base: '1f3ca-1f3fb', uc_full: '1f3ca-1f3fb', shortnames: [':swimmer_tone1:'], category: 'activity' }, + ':person_swimming_tone2:': { uc_base: '1f3ca-1f3fc', uc_full: '1f3ca-1f3fc', shortnames: [':swimmer_tone2:'], category: 'activity' }, + ':person_swimming_tone3:': { uc_base: '1f3ca-1f3fd', uc_full: '1f3ca-1f3fd', shortnames: [':swimmer_tone3:'], category: 'activity' }, + ':person_swimming_tone4:': { uc_base: '1f3ca-1f3fe', uc_full: '1f3ca-1f3fe', shortnames: [':swimmer_tone4:'], category: 'activity' }, + ':person_swimming_tone5:': { uc_base: '1f3ca-1f3ff', uc_full: '1f3ca-1f3ff', shortnames: [':swimmer_tone5:'], category: 'activity' }, + ':person_tipping_hand_tone1:': { + uc_base: '1f481-1f3fb', + uc_full: '1f481-1f3fb', + shortnames: [':information_desk_person_tone1:'], + category: 'people', + }, + ':person_tipping_hand_tone2:': { + uc_base: '1f481-1f3fc', + uc_full: '1f481-1f3fc', + shortnames: [':information_desk_person_tone2:'], + category: 'people', + }, + ':person_tipping_hand_tone3:': { + uc_base: '1f481-1f3fd', + uc_full: '1f481-1f3fd', + shortnames: [':information_desk_person_tone3:'], + category: 'people', + }, + ':person_tipping_hand_tone4:': { + uc_base: '1f481-1f3fe', + uc_full: '1f481-1f3fe', + shortnames: [':information_desk_person_tone4:'], + category: 'people', + }, + ':person_tipping_hand_tone5:': { + uc_base: '1f481-1f3ff', + uc_full: '1f481-1f3ff', + shortnames: [':information_desk_person_tone5:'], + category: 'people', + }, + ':person_walking_tone1:': { uc_base: '1f6b6-1f3fb', uc_full: '1f6b6-1f3fb', shortnames: [':walking_tone1:'], category: 'people' }, + ':person_walking_tone2:': { uc_base: '1f6b6-1f3fc', uc_full: '1f6b6-1f3fc', shortnames: [':walking_tone2:'], category: 'people' }, + ':person_walking_tone3:': { uc_base: '1f6b6-1f3fd', uc_full: '1f6b6-1f3fd', shortnames: [':walking_tone3:'], category: 'people' }, + ':person_walking_tone4:': { uc_base: '1f6b6-1f3fe', uc_full: '1f6b6-1f3fe', shortnames: [':walking_tone4:'], category: 'people' }, + ':person_walking_tone5:': { uc_base: '1f6b6-1f3ff', uc_full: '1f6b6-1f3ff', shortnames: [':walking_tone5:'], category: 'people' }, + ':person_wearing_turban_tone1:': { + uc_base: '1f473-1f3fb', + uc_full: '1f473-1f3fb', + shortnames: [':man_with_turban_tone1:'], + category: 'people', + }, + ':person_wearing_turban_tone2:': { + uc_base: '1f473-1f3fc', + uc_full: '1f473-1f3fc', + shortnames: [':man_with_turban_tone2:'], + category: 'people', + }, + ':person_wearing_turban_tone3:': { + uc_base: '1f473-1f3fd', + uc_full: '1f473-1f3fd', + shortnames: [':man_with_turban_tone3:'], + category: 'people', + }, + ':person_wearing_turban_tone4:': { + uc_base: '1f473-1f3fe', + uc_full: '1f473-1f3fe', + shortnames: [':man_with_turban_tone4:'], + category: 'people', + }, + ':person_wearing_turban_tone5:': { + uc_base: '1f473-1f3ff', + uc_full: '1f473-1f3ff', + shortnames: [':man_with_turban_tone5:'], + category: 'people', + }, + ':person_white_hair:': { uc_base: '1f9d1-1f9b3', uc_full: '1f9d1-200d-1f9b3', shortnames: [], category: 'people' }, + ':person_with_probing_cane:': { uc_base: '1f9d1-1f9af', uc_full: '1f9d1-200d-1f9af', shortnames: [], category: 'people' }, + ':person_with_veil_tone1:': { uc_base: '1f470-1f3fb', uc_full: '1f470-1f3fb', shortnames: [], category: 'people' }, + ':person_with_veil_tone2:': { uc_base: '1f470-1f3fc', uc_full: '1f470-1f3fc', shortnames: [], category: 'people' }, + ':person_with_veil_tone3:': { uc_base: '1f470-1f3fd', uc_full: '1f470-1f3fd', shortnames: [], category: 'people' }, + ':person_with_veil_tone4:': { uc_base: '1f470-1f3fe', uc_full: '1f470-1f3fe', shortnames: [], category: 'people' }, + ':person_with_veil_tone5:': { uc_base: '1f470-1f3ff', uc_full: '1f470-1f3ff', shortnames: [], category: 'people' }, + ':pinched_fingers_tone1:': { + uc_base: '1f90c-1f3fb', + uc_full: '1f90c-1f3fb', + shortnames: [':pinched_fingers_light_skin_tone:'], + category: 'people', + }, + ':pinched_fingers_tone2:': { + uc_base: '1f90c-1f3fc', + uc_full: '1f90c-1f3fc', + shortnames: [':pinched_fingers_medium_light_skin_tone:'], + category: 'people', + }, + ':pinched_fingers_tone3:': { + uc_base: '1f90c-1f3fd', + uc_full: '1f90c-1f3fd', + shortnames: [':pinched_fingers_medium_skin_tone:'], + category: 'people', + }, + ':pinched_fingers_tone4:': { + uc_base: '1f90c-1f3fe', + uc_full: '1f90c-1f3fe', + shortnames: [':pinched_fingers_medium_dark_skin_tone:'], + category: 'people', + }, + ':pinched_fingers_tone5:': { + uc_base: '1f90c-1f3ff', + uc_full: '1f90c-1f3ff', + shortnames: [':pinched_fingers_dark_skin_tone:'], + category: 'people', + }, + ':pinching_hand_tone1:': { + uc_base: '1f90f-1f3fb', + uc_full: '1f90f-1f3fb', + shortnames: [':pinching_hand_light_skin_tone:'], + category: 'people', + }, + ':pinching_hand_tone2:': { + uc_base: '1f90f-1f3fc', + uc_full: '1f90f-1f3fc', + shortnames: [':pinching_hand_medium_light_skin_tone:'], + category: 'people', + }, + ':pinching_hand_tone3:': { + uc_base: '1f90f-1f3fd', + uc_full: '1f90f-1f3fd', + shortnames: [':pinching_hand_medium_skin_tone:'], + category: 'people', + }, + ':pinching_hand_tone4:': { + uc_base: '1f90f-1f3fe', + uc_full: '1f90f-1f3fe', + shortnames: [':pinching_hand_medium_dark_skin_tone:'], + category: 'people', + }, + ':pinching_hand_tone5:': { + uc_base: '1f90f-1f3ff', + uc_full: '1f90f-1f3ff', + shortnames: [':pinching_hand_dark_skin_tone:'], + category: 'people', + }, + ':point_down_tone1:': { uc_base: '1f447-1f3fb', uc_full: '1f447-1f3fb', shortnames: [], category: 'people' }, + ':point_down_tone2:': { uc_base: '1f447-1f3fc', uc_full: '1f447-1f3fc', shortnames: [], category: 'people' }, + ':point_down_tone3:': { uc_base: '1f447-1f3fd', uc_full: '1f447-1f3fd', shortnames: [], category: 'people' }, + ':point_down_tone4:': { uc_base: '1f447-1f3fe', uc_full: '1f447-1f3fe', shortnames: [], category: 'people' }, + ':point_down_tone5:': { uc_base: '1f447-1f3ff', uc_full: '1f447-1f3ff', shortnames: [], category: 'people' }, + ':point_left_tone1:': { uc_base: '1f448-1f3fb', uc_full: '1f448-1f3fb', shortnames: [], category: 'people' }, + ':point_left_tone2:': { uc_base: '1f448-1f3fc', uc_full: '1f448-1f3fc', shortnames: [], category: 'people' }, + ':point_left_tone3:': { uc_base: '1f448-1f3fd', uc_full: '1f448-1f3fd', shortnames: [], category: 'people' }, + ':point_left_tone4:': { uc_base: '1f448-1f3fe', uc_full: '1f448-1f3fe', shortnames: [], category: 'people' }, + ':point_left_tone5:': { uc_base: '1f448-1f3ff', uc_full: '1f448-1f3ff', shortnames: [], category: 'people' }, + ':point_right_tone1:': { uc_base: '1f449-1f3fb', uc_full: '1f449-1f3fb', shortnames: [], category: 'people' }, + ':point_right_tone2:': { uc_base: '1f449-1f3fc', uc_full: '1f449-1f3fc', shortnames: [], category: 'people' }, + ':point_right_tone3:': { uc_base: '1f449-1f3fd', uc_full: '1f449-1f3fd', shortnames: [], category: 'people' }, + ':point_right_tone4:': { uc_base: '1f449-1f3fe', uc_full: '1f449-1f3fe', shortnames: [], category: 'people' }, + ':point_right_tone5:': { uc_base: '1f449-1f3ff', uc_full: '1f449-1f3ff', shortnames: [], category: 'people' }, + ':point_up_2_tone1:': { uc_base: '1f446-1f3fb', uc_full: '1f446-1f3fb', shortnames: [], category: 'people' }, + ':point_up_2_tone2:': { uc_base: '1f446-1f3fc', uc_full: '1f446-1f3fc', shortnames: [], category: 'people' }, + ':point_up_2_tone3:': { uc_base: '1f446-1f3fd', uc_full: '1f446-1f3fd', shortnames: [], category: 'people' }, + ':point_up_2_tone4:': { uc_base: '1f446-1f3fe', uc_full: '1f446-1f3fe', shortnames: [], category: 'people' }, + ':point_up_2_tone5:': { uc_base: '1f446-1f3ff', uc_full: '1f446-1f3ff', shortnames: [], category: 'people' }, + ':police_officer_tone1:': { uc_base: '1f46e-1f3fb', uc_full: '1f46e-1f3fb', shortnames: [':cop_tone1:'], category: 'people' }, + ':police_officer_tone2:': { uc_base: '1f46e-1f3fc', uc_full: '1f46e-1f3fc', shortnames: [':cop_tone2:'], category: 'people' }, + ':police_officer_tone3:': { uc_base: '1f46e-1f3fd', uc_full: '1f46e-1f3fd', shortnames: [':cop_tone3:'], category: 'people' }, + ':police_officer_tone4:': { uc_base: '1f46e-1f3fe', uc_full: '1f46e-1f3fe', shortnames: [':cop_tone4:'], category: 'people' }, + ':police_officer_tone5:': { uc_base: '1f46e-1f3ff', uc_full: '1f46e-1f3ff', shortnames: [':cop_tone5:'], category: 'people' }, + ':pray_tone1:': { uc_base: '1f64f-1f3fb', uc_full: '1f64f-1f3fb', shortnames: [], category: 'people' }, + ':pray_tone2:': { uc_base: '1f64f-1f3fc', uc_full: '1f64f-1f3fc', shortnames: [], category: 'people' }, + ':pray_tone3:': { uc_base: '1f64f-1f3fd', uc_full: '1f64f-1f3fd', shortnames: [], category: 'people' }, + ':pray_tone4:': { uc_base: '1f64f-1f3fe', uc_full: '1f64f-1f3fe', shortnames: [], category: 'people' }, + ':pray_tone5:': { uc_base: '1f64f-1f3ff', uc_full: '1f64f-1f3ff', shortnames: [], category: 'people' }, + ':pregnant_woman_tone1:': { + uc_base: '1f930-1f3fb', + uc_full: '1f930-1f3fb', + shortnames: [':expecting_woman_tone1:'], + category: 'people', + }, + ':pregnant_woman_tone2:': { + uc_base: '1f930-1f3fc', + uc_full: '1f930-1f3fc', + shortnames: [':expecting_woman_tone2:'], + category: 'people', + }, + ':pregnant_woman_tone3:': { + uc_base: '1f930-1f3fd', + uc_full: '1f930-1f3fd', + shortnames: [':expecting_woman_tone3:'], + category: 'people', + }, + ':pregnant_woman_tone4:': { + uc_base: '1f930-1f3fe', + uc_full: '1f930-1f3fe', + shortnames: [':expecting_woman_tone4:'], + category: 'people', + }, + ':pregnant_woman_tone5:': { + uc_base: '1f930-1f3ff', + uc_full: '1f930-1f3ff', + shortnames: [':expecting_woman_tone5:'], + category: 'people', + }, + ':prince_tone1:': { uc_base: '1f934-1f3fb', uc_full: '1f934-1f3fb', shortnames: [], category: 'people' }, + ':prince_tone2:': { uc_base: '1f934-1f3fc', uc_full: '1f934-1f3fc', shortnames: [], category: 'people' }, + ':prince_tone3:': { uc_base: '1f934-1f3fd', uc_full: '1f934-1f3fd', shortnames: [], category: 'people' }, + ':prince_tone4:': { uc_base: '1f934-1f3fe', uc_full: '1f934-1f3fe', shortnames: [], category: 'people' }, + ':prince_tone5:': { uc_base: '1f934-1f3ff', uc_full: '1f934-1f3ff', shortnames: [], category: 'people' }, + ':princess_tone1:': { uc_base: '1f478-1f3fb', uc_full: '1f478-1f3fb', shortnames: [], category: 'people' }, + ':princess_tone2:': { uc_base: '1f478-1f3fc', uc_full: '1f478-1f3fc', shortnames: [], category: 'people' }, + ':princess_tone3:': { uc_base: '1f478-1f3fd', uc_full: '1f478-1f3fd', shortnames: [], category: 'people' }, + ':princess_tone4:': { uc_base: '1f478-1f3fe', uc_full: '1f478-1f3fe', shortnames: [], category: 'people' }, + ':princess_tone5:': { uc_base: '1f478-1f3ff', uc_full: '1f478-1f3ff', shortnames: [], category: 'people' }, + ':punch_tone1:': { uc_base: '1f44a-1f3fb', uc_full: '1f44a-1f3fb', shortnames: [], category: 'people' }, + ':punch_tone2:': { uc_base: '1f44a-1f3fc', uc_full: '1f44a-1f3fc', shortnames: [], category: 'people' }, + ':punch_tone3:': { uc_base: '1f44a-1f3fd', uc_full: '1f44a-1f3fd', shortnames: [], category: 'people' }, + ':punch_tone4:': { uc_base: '1f44a-1f3fe', uc_full: '1f44a-1f3fe', shortnames: [], category: 'people' }, + ':punch_tone5:': { uc_base: '1f44a-1f3ff', uc_full: '1f44a-1f3ff', shortnames: [], category: 'people' }, + ':rainbow_flag:': { uc_base: '1f3f3-1f308', uc_full: '1f3f3-fe0f-200d-1f308', shortnames: [':gay_pride_flag:'], category: 'flags' }, + ':raised_back_of_hand_tone1:': { + uc_base: '1f91a-1f3fb', + uc_full: '1f91a-1f3fb', + shortnames: [':back_of_hand_tone1:'], + category: 'people', + }, + ':raised_back_of_hand_tone2:': { + uc_base: '1f91a-1f3fc', + uc_full: '1f91a-1f3fc', + shortnames: [':back_of_hand_tone2:'], + category: 'people', + }, + ':raised_back_of_hand_tone3:': { + uc_base: '1f91a-1f3fd', + uc_full: '1f91a-1f3fd', + shortnames: [':back_of_hand_tone3:'], + category: 'people', + }, + ':raised_back_of_hand_tone4:': { + uc_base: '1f91a-1f3fe', + uc_full: '1f91a-1f3fe', + shortnames: [':back_of_hand_tone4:'], + category: 'people', + }, + ':raised_back_of_hand_tone5:': { + uc_base: '1f91a-1f3ff', + uc_full: '1f91a-1f3ff', + shortnames: [':back_of_hand_tone5:'], + category: 'people', + }, + ':raised_hands_tone1:': { uc_base: '1f64c-1f3fb', uc_full: '1f64c-1f3fb', shortnames: [], category: 'people' }, + ':raised_hands_tone2:': { uc_base: '1f64c-1f3fc', uc_full: '1f64c-1f3fc', shortnames: [], category: 'people' }, + ':raised_hands_tone3:': { uc_base: '1f64c-1f3fd', uc_full: '1f64c-1f3fd', shortnames: [], category: 'people' }, + ':raised_hands_tone4:': { uc_base: '1f64c-1f3fe', uc_full: '1f64c-1f3fe', shortnames: [], category: 'people' }, + ':raised_hands_tone5:': { uc_base: '1f64c-1f3ff', uc_full: '1f64c-1f3ff', shortnames: [], category: 'people' }, + ':right_facing_fist_tone1:': { uc_base: '1f91c-1f3fb', uc_full: '1f91c-1f3fb', shortnames: [':right_fist_tone1:'], category: 'people' }, + ':right_facing_fist_tone2:': { uc_base: '1f91c-1f3fc', uc_full: '1f91c-1f3fc', shortnames: [':right_fist_tone2:'], category: 'people' }, + ':right_facing_fist_tone3:': { uc_base: '1f91c-1f3fd', uc_full: '1f91c-1f3fd', shortnames: [':right_fist_tone3:'], category: 'people' }, + ':right_facing_fist_tone4:': { uc_base: '1f91c-1f3fe', uc_full: '1f91c-1f3fe', shortnames: [':right_fist_tone4:'], category: 'people' }, + ':right_facing_fist_tone5:': { uc_base: '1f91c-1f3ff', uc_full: '1f91c-1f3ff', shortnames: [':right_fist_tone5:'], category: 'people' }, + ':santa_tone1:': { uc_base: '1f385-1f3fb', uc_full: '1f385-1f3fb', shortnames: [], category: 'people' }, + ':santa_tone2:': { uc_base: '1f385-1f3fc', uc_full: '1f385-1f3fc', shortnames: [], category: 'people' }, + ':santa_tone3:': { uc_base: '1f385-1f3fd', uc_full: '1f385-1f3fd', shortnames: [], category: 'people' }, + ':santa_tone4:': { uc_base: '1f385-1f3fe', uc_full: '1f385-1f3fe', shortnames: [], category: 'people' }, + ':santa_tone5:': { uc_base: '1f385-1f3ff', uc_full: '1f385-1f3ff', shortnames: [], category: 'people' }, + ':scientist:': { uc_base: '1f9d1-1f52c', uc_full: '1f9d1-200d-1f52c', shortnames: [], category: 'people' }, + ':selfie_tone1:': { uc_base: '1f933-1f3fb', uc_full: '1f933-1f3fb', shortnames: [], category: 'people' }, + ':selfie_tone2:': { uc_base: '1f933-1f3fc', uc_full: '1f933-1f3fc', shortnames: [], category: 'people' }, + ':selfie_tone3:': { uc_base: '1f933-1f3fd', uc_full: '1f933-1f3fd', shortnames: [], category: 'people' }, + ':selfie_tone4:': { uc_base: '1f933-1f3fe', uc_full: '1f933-1f3fe', shortnames: [], category: 'people' }, + ':selfie_tone5:': { uc_base: '1f933-1f3ff', uc_full: '1f933-1f3ff', shortnames: [], category: 'people' }, + ':service_dog:': { uc_base: '1f415-1f9ba', uc_full: '1f415-200d-1f9ba', shortnames: [], category: 'nature' }, + ':singer:': { uc_base: '1f9d1-1f3a4', uc_full: '1f9d1-200d-1f3a4', shortnames: [], category: 'people' }, + ':snowboarder_tone1:': { + uc_base: '1f3c2-1f3fb', + uc_full: '1f3c2-1f3fb', + shortnames: [':snowboarder_light_skin_tone:'], + category: 'activity', + }, + ':snowboarder_tone2:': { + uc_base: '1f3c2-1f3fc', + uc_full: '1f3c2-1f3fc', + shortnames: [':snowboarder_medium_light_skin_tone:'], + category: 'activity', + }, + ':snowboarder_tone3:': { + uc_base: '1f3c2-1f3fd', + uc_full: '1f3c2-1f3fd', + shortnames: [':snowboarder_medium_skin_tone:'], + category: 'activity', + }, + ':snowboarder_tone4:': { + uc_base: '1f3c2-1f3fe', + uc_full: '1f3c2-1f3fe', + shortnames: [':snowboarder_medium_dark_skin_tone:'], + category: 'activity', + }, + ':snowboarder_tone5:': { + uc_base: '1f3c2-1f3ff', + uc_full: '1f3c2-1f3ff', + shortnames: [':snowboarder_dark_skin_tone:'], + category: 'activity', + }, + ':student:': { uc_base: '1f9d1-1f393', uc_full: '1f9d1-200d-1f393', shortnames: [], category: 'people' }, + ':superhero_tone1:': { + uc_base: '1f9b8-1f3fb', + uc_full: '1f9b8-1f3fb', + shortnames: [':superhero_light_skin_tone:'], + category: 'people', + }, + ':superhero_tone2:': { + uc_base: '1f9b8-1f3fc', + uc_full: '1f9b8-1f3fc', + shortnames: [':superhero_medium_light_skin_tone:'], + category: 'people', + }, + ':superhero_tone3:': { + uc_base: '1f9b8-1f3fd', + uc_full: '1f9b8-1f3fd', + shortnames: [':superhero_medium_skin_tone:'], + category: 'people', + }, + ':superhero_tone4:': { + uc_base: '1f9b8-1f3fe', + uc_full: '1f9b8-1f3fe', + shortnames: [':superhero_medium_dark_skin_tone:'], + category: 'people', + }, + ':superhero_tone5:': { uc_base: '1f9b8-1f3ff', uc_full: '1f9b8-1f3ff', shortnames: [':superhero_dark_skin_tone:'], category: 'people' }, + ':supervillain_tone1:': { + uc_base: '1f9b9-1f3fb', + uc_full: '1f9b9-1f3fb', + shortnames: [':supervillain_light_skin_tone:'], + category: 'people', + }, + ':supervillain_tone2:': { + uc_base: '1f9b9-1f3fc', + uc_full: '1f9b9-1f3fc', + shortnames: [':supervillain_medium_light_skin_tone:'], + category: 'people', + }, + ':supervillain_tone3:': { + uc_base: '1f9b9-1f3fd', + uc_full: '1f9b9-1f3fd', + shortnames: [':supervillain_medium_skin_tone:'], + category: 'people', + }, + ':supervillain_tone4:': { + uc_base: '1f9b9-1f3fe', + uc_full: '1f9b9-1f3fe', + shortnames: [':supervillain_medium_dark_skin_tone:'], + category: 'people', + }, + ':supervillain_tone5:': { + uc_base: '1f9b9-1f3ff', + uc_full: '1f9b9-1f3ff', + shortnames: [':supervillain_dark_skin_tone:'], + category: 'people', + }, + ':teacher:': { uc_base: '1f9d1-1f3eb', uc_full: '1f9d1-200d-1f3eb', shortnames: [], category: 'people' }, + ':technologist:': { uc_base: '1f9d1-1f4bb', uc_full: '1f9d1-200d-1f4bb', shortnames: [], category: 'people' }, + ':thumbsdown_tone1:': { + uc_base: '1f44e-1f3fb', + uc_full: '1f44e-1f3fb', + shortnames: [':-1_tone1:', ':thumbdown_tone1:'], + category: 'people', + }, + ':thumbsdown_tone2:': { + uc_base: '1f44e-1f3fc', + uc_full: '1f44e-1f3fc', + shortnames: [':-1_tone2:', ':thumbdown_tone2:'], + category: 'people', + }, + ':thumbsdown_tone3:': { + uc_base: '1f44e-1f3fd', + uc_full: '1f44e-1f3fd', + shortnames: [':-1_tone3:', ':thumbdown_tone3:'], + category: 'people', + }, + ':thumbsdown_tone4:': { + uc_base: '1f44e-1f3fe', + uc_full: '1f44e-1f3fe', + shortnames: [':-1_tone4:', ':thumbdown_tone4:'], + category: 'people', + }, + ':thumbsdown_tone5:': { + uc_base: '1f44e-1f3ff', + uc_full: '1f44e-1f3ff', + shortnames: [':-1_tone5:', ':thumbdown_tone5:'], + category: 'people', + }, + ':thumbsup_tone1:': { + uc_base: '1f44d-1f3fb', + uc_full: '1f44d-1f3fb', + shortnames: [':+1_tone1:', ':thumbup_tone1:'], + category: 'people', + }, + ':thumbsup_tone2:': { + uc_base: '1f44d-1f3fc', + uc_full: '1f44d-1f3fc', + shortnames: [':+1_tone2:', ':thumbup_tone2:'], + category: 'people', + }, + ':thumbsup_tone3:': { + uc_base: '1f44d-1f3fd', + uc_full: '1f44d-1f3fd', + shortnames: [':+1_tone3:', ':thumbup_tone3:'], + category: 'people', + }, + ':thumbsup_tone4:': { + uc_base: '1f44d-1f3fe', + uc_full: '1f44d-1f3fe', + shortnames: [':+1_tone4:', ':thumbup_tone4:'], + category: 'people', + }, + ':thumbsup_tone5:': { + uc_base: '1f44d-1f3ff', + uc_full: '1f44d-1f3ff', + shortnames: [':+1_tone5:', ':thumbup_tone5:'], + category: 'people', + }, + ':united_nations:': { uc_base: '1f1fa-1f1f3', uc_full: '1f1fa-1f1f3', shortnames: [], category: 'flags' }, + ':vampire_tone1:': { uc_base: '1f9db-1f3fb', uc_full: '1f9db-1f3fb', shortnames: [':vampire_light_skin_tone:'], category: 'people' }, + ':vampire_tone2:': { + uc_base: '1f9db-1f3fc', + uc_full: '1f9db-1f3fc', + shortnames: [':vampire_medium_light_skin_tone:'], + category: 'people', + }, + ':vampire_tone3:': { uc_base: '1f9db-1f3fd', uc_full: '1f9db-1f3fd', shortnames: [':vampire_medium_skin_tone:'], category: 'people' }, + ':vampire_tone4:': { + uc_base: '1f9db-1f3fe', + uc_full: '1f9db-1f3fe', + shortnames: [':vampire_medium_dark_skin_tone:'], + category: 'people', + }, + ':vampire_tone5:': { uc_base: '1f9db-1f3ff', uc_full: '1f9db-1f3ff', shortnames: [':vampire_dark_skin_tone:'], category: 'people' }, + ':vulcan_tone1:': { + uc_base: '1f596-1f3fb', + uc_full: '1f596-1f3fb', + shortnames: [':raised_hand_with_part_between_middle_and_ring_fingers_tone1:'], + category: 'people', + }, + ':vulcan_tone2:': { + uc_base: '1f596-1f3fc', + uc_full: '1f596-1f3fc', + shortnames: [':raised_hand_with_part_between_middle_and_ring_fingers_tone2:'], + category: 'people', + }, + ':vulcan_tone3:': { + uc_base: '1f596-1f3fd', + uc_full: '1f596-1f3fd', + shortnames: [':raised_hand_with_part_between_middle_and_ring_fingers_tone3:'], + category: 'people', + }, + ':vulcan_tone4:': { + uc_base: '1f596-1f3fe', + uc_full: '1f596-1f3fe', + shortnames: [':raised_hand_with_part_between_middle_and_ring_fingers_tone4:'], + category: 'people', + }, + ':vulcan_tone5:': { + uc_base: '1f596-1f3ff', + uc_full: '1f596-1f3ff', + shortnames: [':raised_hand_with_part_between_middle_and_ring_fingers_tone5:'], + category: 'people', + }, + ':wave_tone1:': { uc_base: '1f44b-1f3fb', uc_full: '1f44b-1f3fb', shortnames: [], category: 'people' }, + ':wave_tone2:': { uc_base: '1f44b-1f3fc', uc_full: '1f44b-1f3fc', shortnames: [], category: 'people' }, + ':wave_tone3:': { uc_base: '1f44b-1f3fd', uc_full: '1f44b-1f3fd', shortnames: [], category: 'people' }, + ':wave_tone4:': { uc_base: '1f44b-1f3fe', uc_full: '1f44b-1f3fe', shortnames: [], category: 'people' }, + ':wave_tone5:': { uc_base: '1f44b-1f3ff', uc_full: '1f44b-1f3ff', shortnames: [], category: 'people' }, + ':woman_and_man_holding_hands_tone1:': { + uc_base: '1f46b-1f3fb', + uc_full: '1f46b-1f3fb', + shortnames: [':woman_and_man_holding_hands_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone2:': { + uc_base: '1f46b-1f3fc', + uc_full: '1f46b-1f3fc', + shortnames: [':woman_and_man_holding_hands_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone3:': { + uc_base: '1f46b-1f3fd', + uc_full: '1f46b-1f3fd', + shortnames: [':woman_and_man_holding_hands_medium_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone4:': { + uc_base: '1f46b-1f3fe', + uc_full: '1f46b-1f3fe', + shortnames: [':woman_and_man_holding_hands_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_and_man_holding_hands_tone5:': { + uc_base: '1f46b-1f3ff', + uc_full: '1f46b-1f3ff', + shortnames: [':woman_and_man_holding_hands_dark_skin_tone:'], + category: 'people', + }, + ':woman_artist:': { uc_base: '1f469-1f3a8', uc_full: '1f469-200d-1f3a8', shortnames: [], category: 'people' }, + ':woman_astronaut:': { uc_base: '1f469-1f680', uc_full: '1f469-200d-1f680', shortnames: [], category: 'people' }, + ':woman_bald:': { uc_base: '1f469-1f9b2', uc_full: '1f469-200d-1f9b2', shortnames: [], category: 'people' }, + ':woman_cook:': { uc_base: '1f469-1f373', uc_full: '1f469-200d-1f373', shortnames: [], category: 'people' }, + ':woman_curly_haired:': { uc_base: '1f469-1f9b1', uc_full: '1f469-200d-1f9b1', shortnames: [], category: 'people' }, + ':woman_factory_worker:': { uc_base: '1f469-1f3ed', uc_full: '1f469-200d-1f3ed', shortnames: [], category: 'people' }, + ':woman_farmer:': { uc_base: '1f469-1f33e', uc_full: '1f469-200d-1f33e', shortnames: [], category: 'people' }, + ':woman_feeding_baby:': { uc_base: '1f469-1f37c', uc_full: '1f469-200d-1f37c', shortnames: [], category: 'people' }, + ':woman_firefighter:': { uc_base: '1f469-1f692', uc_full: '1f469-200d-1f692', shortnames: [], category: 'people' }, + ':woman_in_manual_wheelchair:': { uc_base: '1f469-1f9bd', uc_full: '1f469-200d-1f9bd', shortnames: [], category: 'people' }, + ':woman_in_motorized_wheelchair:': { uc_base: '1f469-1f9bc', uc_full: '1f469-200d-1f9bc', shortnames: [], category: 'people' }, + ':woman_mechanic:': { uc_base: '1f469-1f527', uc_full: '1f469-200d-1f527', shortnames: [], category: 'people' }, + ':woman_office_worker:': { uc_base: '1f469-1f4bc', uc_full: '1f469-200d-1f4bc', shortnames: [], category: 'people' }, + ':woman_red_haired:': { uc_base: '1f469-1f9b0', uc_full: '1f469-200d-1f9b0', shortnames: [], category: 'people' }, + ':woman_scientist:': { uc_base: '1f469-1f52c', uc_full: '1f469-200d-1f52c', shortnames: [], category: 'people' }, + ':woman_singer:': { uc_base: '1f469-1f3a4', uc_full: '1f469-200d-1f3a4', shortnames: [], category: 'people' }, + ':woman_student:': { uc_base: '1f469-1f393', uc_full: '1f469-200d-1f393', shortnames: [], category: 'people' }, + ':woman_teacher:': { uc_base: '1f469-1f3eb', uc_full: '1f469-200d-1f3eb', shortnames: [], category: 'people' }, + ':woman_technologist:': { uc_base: '1f469-1f4bb', uc_full: '1f469-200d-1f4bb', shortnames: [], category: 'people' }, + ':woman_tone1:': { uc_base: '1f469-1f3fb', uc_full: '1f469-1f3fb', shortnames: [], category: 'people' }, + ':woman_tone2:': { uc_base: '1f469-1f3fc', uc_full: '1f469-1f3fc', shortnames: [], category: 'people' }, + ':woman_tone3:': { uc_base: '1f469-1f3fd', uc_full: '1f469-1f3fd', shortnames: [], category: 'people' }, + ':woman_tone4:': { uc_base: '1f469-1f3fe', uc_full: '1f469-1f3fe', shortnames: [], category: 'people' }, + ':woman_tone5:': { uc_base: '1f469-1f3ff', uc_full: '1f469-1f3ff', shortnames: [], category: 'people' }, + ':woman_white_haired:': { uc_base: '1f469-1f9b3', uc_full: '1f469-200d-1f9b3', shortnames: [], category: 'people' }, + ':woman_with_headscarf_tone1:': { + uc_base: '1f9d5-1f3fb', + uc_full: '1f9d5-1f3fb', + shortnames: [':woman_with_headscarf_light_skin_tone:'], + category: 'people', + }, + ':woman_with_headscarf_tone2:': { + uc_base: '1f9d5-1f3fc', + uc_full: '1f9d5-1f3fc', + shortnames: [':woman_with_headscarf_medium_light_skin_tone:'], + category: 'people', + }, + ':woman_with_headscarf_tone3:': { + uc_base: '1f9d5-1f3fd', + uc_full: '1f9d5-1f3fd', + shortnames: [':woman_with_headscarf_medium_skin_tone:'], + category: 'people', + }, + ':woman_with_headscarf_tone4:': { + uc_base: '1f9d5-1f3fe', + uc_full: '1f9d5-1f3fe', + shortnames: [':woman_with_headscarf_medium_dark_skin_tone:'], + category: 'people', + }, + ':woman_with_headscarf_tone5:': { + uc_base: '1f9d5-1f3ff', + uc_full: '1f9d5-1f3ff', + shortnames: [':woman_with_headscarf_dark_skin_tone:'], + category: 'people', + }, + ':woman_with_probing_cane:': { uc_base: '1f469-1f9af', uc_full: '1f469-200d-1f9af', shortnames: [], category: 'people' }, + ':women_holding_hands_tone1:': { + uc_base: '1f46d-1f3fb', + uc_full: '1f46d-1f3fb', + shortnames: [':women_holding_hands_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone2:': { + uc_base: '1f46d-1f3fc', + uc_full: '1f46d-1f3fc', + shortnames: [':women_holding_hands_medium_light_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone3:': { + uc_base: '1f46d-1f3fd', + uc_full: '1f46d-1f3fd', + shortnames: [':women_holding_hands_medium_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone4:': { + uc_base: '1f46d-1f3fe', + uc_full: '1f46d-1f3fe', + shortnames: [':women_holding_hands_medium_dark_skin_tone:'], + category: 'people', + }, + ':women_holding_hands_tone5:': { + uc_base: '1f46d-1f3ff', + uc_full: '1f46d-1f3ff', + shortnames: [':women_holding_hands_dark_skin_tone:'], + category: 'people', + }, + ':black_cat:': { uc_base: '1f408-2b1b', uc_full: '1f408-200d-2b1b', shortnames: [], category: 'nature' }, + ':blond-haired_man:': { uc_base: '1f471-2642', uc_full: '1f471-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':blond-haired_woman:': { uc_base: '1f471-2640', uc_full: '1f471-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':deaf_man:': { uc_base: '1f9cf-2642', uc_full: '1f9cf-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':deaf_woman:': { uc_base: '1f9cf-2640', uc_full: '1f9cf-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':fist_tone1:': { uc_base: '270a-1f3fb', uc_full: '270a-1f3fb', shortnames: [], category: 'people' }, + ':fist_tone2:': { uc_base: '270a-1f3fc', uc_full: '270a-1f3fc', shortnames: [], category: 'people' }, + ':fist_tone3:': { uc_base: '270a-1f3fd', uc_full: '270a-1f3fd', shortnames: [], category: 'people' }, + ':fist_tone4:': { uc_base: '270a-1f3fe', uc_full: '270a-1f3fe', shortnames: [], category: 'people' }, + ':fist_tone5:': { uc_base: '270a-1f3ff', uc_full: '270a-1f3ff', shortnames: [], category: 'people' }, + ':health_worker:': { uc_base: '1f9d1-2695', uc_full: '1f9d1-200d-2695-fe0f', shortnames: [], category: 'people' }, + ':heart_on_fire:': { uc_base: '2764-1f525', uc_full: '2764-fe0f-200d-1f525', shortnames: [], category: 'symbols' }, + ':judge:': { uc_base: '1f9d1-2696', uc_full: '1f9d1-200d-2696-fe0f', shortnames: [], category: 'people' }, + ':man_beard:': { uc_base: '1f9d4-2642', uc_full: '1f9d4-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_biking:': { uc_base: '1f6b4-2642', uc_full: '1f6b4-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_bowing:': { uc_base: '1f647-2642', uc_full: '1f647-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_cartwheeling:': { uc_base: '1f938-2642', uc_full: '1f938-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_climbing:': { uc_base: '1f9d7-2642', uc_full: '1f9d7-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_construction_worker:': { uc_base: '1f477-2642', uc_full: '1f477-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_detective:': { uc_base: '1f575-2642', uc_full: '1f575-fe0f-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_elf:': { uc_base: '1f9dd-2642', uc_full: '1f9dd-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_facepalming:': { uc_base: '1f926-2642', uc_full: '1f926-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_fairy:': { uc_base: '1f9da-2642', uc_full: '1f9da-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_frowning:': { uc_base: '1f64d-2642', uc_full: '1f64d-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_genie:': { uc_base: '1f9de-2642', uc_full: '1f9de-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_gesturing_no:': { uc_base: '1f645-2642', uc_full: '1f645-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_gesturing_ok:': { uc_base: '1f646-2642', uc_full: '1f646-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_getting_face_massage:': { uc_base: '1f486-2642', uc_full: '1f486-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_getting_haircut:': { uc_base: '1f487-2642', uc_full: '1f487-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_golfing:': { uc_base: '1f3cc-2642', uc_full: '1f3cc-fe0f-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_guard:': { uc_base: '1f482-2642', uc_full: '1f482-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_health_worker:': { uc_base: '1f468-2695', uc_full: '1f468-200d-2695-fe0f', shortnames: [], category: 'people' }, + ':man_in_lotus_position:': { uc_base: '1f9d8-2642', uc_full: '1f9d8-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_in_steamy_room:': { uc_base: '1f9d6-2642', uc_full: '1f9d6-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_in_tuxedo:': { uc_base: '1f935-2642', uc_full: '1f935-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_judge:': { uc_base: '1f468-2696', uc_full: '1f468-200d-2696-fe0f', shortnames: [], category: 'people' }, + ':man_juggling:': { uc_base: '1f939-2642', uc_full: '1f939-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_kneeling:': { uc_base: '1f9ce-2642', uc_full: '1f9ce-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_lifting_weights:': { uc_base: '1f3cb-2642', uc_full: '1f3cb-fe0f-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_mage:': { uc_base: '1f9d9-2642', uc_full: '1f9d9-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_mountain_biking:': { uc_base: '1f6b5-2642', uc_full: '1f6b5-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_pilot:': { uc_base: '1f468-2708', uc_full: '1f468-200d-2708-fe0f', shortnames: [], category: 'people' }, + ':man_playing_handball:': { uc_base: '1f93e-2642', uc_full: '1f93e-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_playing_water_polo:': { uc_base: '1f93d-2642', uc_full: '1f93d-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_police_officer:': { uc_base: '1f46e-2642', uc_full: '1f46e-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_pouting:': { uc_base: '1f64e-2642', uc_full: '1f64e-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_raising_hand:': { uc_base: '1f64b-2642', uc_full: '1f64b-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_rowing_boat:': { uc_base: '1f6a3-2642', uc_full: '1f6a3-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_running:': { uc_base: '1f3c3-2642', uc_full: '1f3c3-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_shrugging:': { uc_base: '1f937-2642', uc_full: '1f937-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_standing:': { uc_base: '1f9cd-2642', uc_full: '1f9cd-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_superhero:': { uc_base: '1f9b8-2642', uc_full: '1f9b8-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_supervillain:': { uc_base: '1f9b9-2642', uc_full: '1f9b9-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_surfing:': { uc_base: '1f3c4-2642', uc_full: '1f3c4-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_swimming:': { uc_base: '1f3ca-2642', uc_full: '1f3ca-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':man_tipping_hand:': { uc_base: '1f481-2642', uc_full: '1f481-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_vampire:': { uc_base: '1f9db-2642', uc_full: '1f9db-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_walking:': { uc_base: '1f6b6-2642', uc_full: '1f6b6-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_wearing_turban:': { uc_base: '1f473-2642', uc_full: '1f473-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_with_veil:': { uc_base: '1f470-2642', uc_full: '1f470-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':man_zombie:': { uc_base: '1f9df-2642', uc_full: '1f9df-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':men_with_bunny_ears_partying:': { uc_base: '1f46f-2642', uc_full: '1f46f-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':men_wrestling:': { uc_base: '1f93c-2642', uc_full: '1f93c-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':mending_heart:': { uc_base: '2764-1fa79', uc_full: '2764-fe0f-200d-1fa79', shortnames: [], category: 'symbols' }, + ':mermaid:': { uc_base: '1f9dc-2640', uc_full: '1f9dc-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':merman:': { uc_base: '1f9dc-2642', uc_full: '1f9dc-200d-2642-fe0f', shortnames: [], category: 'people' }, + ':person_bouncing_ball_tone1:': { + uc_base: '26f9-1f3fb', + uc_full: '26f9-1f3fb', + shortnames: [':basketball_player_tone1:', ':person_with_ball_tone1:'], + category: 'activity', + }, + ':person_bouncing_ball_tone2:': { + uc_base: '26f9-1f3fc', + uc_full: '26f9-1f3fc', + shortnames: [':basketball_player_tone2:', ':person_with_ball_tone2:'], + category: 'activity', + }, + ':person_bouncing_ball_tone3:': { + uc_base: '26f9-1f3fd', + uc_full: '26f9-1f3fd', + shortnames: [':basketball_player_tone3:', ':person_with_ball_tone3:'], + category: 'activity', + }, + ':person_bouncing_ball_tone4:': { + uc_base: '26f9-1f3fe', + uc_full: '26f9-1f3fe', + shortnames: [':basketball_player_tone4:', ':person_with_ball_tone4:'], + category: 'activity', + }, + ':person_bouncing_ball_tone5:': { + uc_base: '26f9-1f3ff', + uc_full: '26f9-1f3ff', + shortnames: [':basketball_player_tone5:', ':person_with_ball_tone5:'], + category: 'activity', + }, + ':pilot:': { uc_base: '1f9d1-2708', uc_full: '1f9d1-200d-2708-fe0f', shortnames: [], category: 'people' }, + ':pirate_flag:': { uc_base: '1f3f4-2620', uc_full: '1f3f4-200d-2620-fe0f', shortnames: [], category: 'flags' }, + ':point_up_tone1:': { uc_base: '261d-1f3fb', uc_full: '261d-1f3fb', shortnames: [], category: 'people' }, + ':point_up_tone2:': { uc_base: '261d-1f3fc', uc_full: '261d-1f3fc', shortnames: [], category: 'people' }, + ':point_up_tone3:': { uc_base: '261d-1f3fd', uc_full: '261d-1f3fd', shortnames: [], category: 'people' }, + ':point_up_tone4:': { uc_base: '261d-1f3fe', uc_full: '261d-1f3fe', shortnames: [], category: 'people' }, + ':point_up_tone5:': { uc_base: '261d-1f3ff', uc_full: '261d-1f3ff', shortnames: [], category: 'people' }, + ':polar_bear:': { uc_base: '1f43b-2744', uc_full: '1f43b-200d-2744-fe0f', shortnames: [], category: 'nature' }, + ':raised_hand_tone1:': { uc_base: '270b-1f3fb', uc_full: '270b-1f3fb', shortnames: [], category: 'people' }, + ':raised_hand_tone2:': { uc_base: '270b-1f3fc', uc_full: '270b-1f3fc', shortnames: [], category: 'people' }, + ':raised_hand_tone3:': { uc_base: '270b-1f3fd', uc_full: '270b-1f3fd', shortnames: [], category: 'people' }, + ':raised_hand_tone4:': { uc_base: '270b-1f3fe', uc_full: '270b-1f3fe', shortnames: [], category: 'people' }, + ':raised_hand_tone5:': { uc_base: '270b-1f3ff', uc_full: '270b-1f3ff', shortnames: [], category: 'people' }, + ':transgender_flag:': { uc_base: '1f3f3-26a7', uc_full: '1f3f3-fe0f-200d-26a7-fe0f', shortnames: [], category: 'flags' }, + ':v_tone1:': { uc_base: '270c-1f3fb', uc_full: '270c-1f3fb', shortnames: [], category: 'people' }, + ':v_tone2:': { uc_base: '270c-1f3fc', uc_full: '270c-1f3fc', shortnames: [], category: 'people' }, + ':v_tone3:': { uc_base: '270c-1f3fd', uc_full: '270c-1f3fd', shortnames: [], category: 'people' }, + ':v_tone4:': { uc_base: '270c-1f3fe', uc_full: '270c-1f3fe', shortnames: [], category: 'people' }, + ':v_tone5:': { uc_base: '270c-1f3ff', uc_full: '270c-1f3ff', shortnames: [], category: 'people' }, + ':woman_beard:': { uc_base: '1f9d4-2640', uc_full: '1f9d4-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_biking:': { uc_base: '1f6b4-2640', uc_full: '1f6b4-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_bowing:': { uc_base: '1f647-2640', uc_full: '1f647-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_cartwheeling:': { uc_base: '1f938-2640', uc_full: '1f938-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_climbing:': { uc_base: '1f9d7-2640', uc_full: '1f9d7-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_construction_worker:': { uc_base: '1f477-2640', uc_full: '1f477-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_detective:': { uc_base: '1f575-2640', uc_full: '1f575-fe0f-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_elf:': { uc_base: '1f9dd-2640', uc_full: '1f9dd-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_facepalming:': { uc_base: '1f926-2640', uc_full: '1f926-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_fairy:': { uc_base: '1f9da-2640', uc_full: '1f9da-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_frowning:': { uc_base: '1f64d-2640', uc_full: '1f64d-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_genie:': { uc_base: '1f9de-2640', uc_full: '1f9de-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_gesturing_no:': { uc_base: '1f645-2640', uc_full: '1f645-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_gesturing_ok:': { uc_base: '1f646-2640', uc_full: '1f646-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_getting_face_massage:': { uc_base: '1f486-2640', uc_full: '1f486-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_getting_haircut:': { uc_base: '1f487-2640', uc_full: '1f487-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_golfing:': { uc_base: '1f3cc-2640', uc_full: '1f3cc-fe0f-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_guard:': { uc_base: '1f482-2640', uc_full: '1f482-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_health_worker:': { uc_base: '1f469-2695', uc_full: '1f469-200d-2695-fe0f', shortnames: [], category: 'people' }, + ':woman_in_lotus_position:': { uc_base: '1f9d8-2640', uc_full: '1f9d8-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_in_steamy_room:': { uc_base: '1f9d6-2640', uc_full: '1f9d6-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_in_tuxedo:': { uc_base: '1f935-2640', uc_full: '1f935-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_judge:': { uc_base: '1f469-2696', uc_full: '1f469-200d-2696-fe0f', shortnames: [], category: 'people' }, + ':woman_juggling:': { uc_base: '1f939-2640', uc_full: '1f939-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_kneeling:': { uc_base: '1f9ce-2640', uc_full: '1f9ce-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_lifting_weights:': { uc_base: '1f3cb-2640', uc_full: '1f3cb-fe0f-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_mage:': { uc_base: '1f9d9-2640', uc_full: '1f9d9-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_mountain_biking:': { uc_base: '1f6b5-2640', uc_full: '1f6b5-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_pilot:': { uc_base: '1f469-2708', uc_full: '1f469-200d-2708-fe0f', shortnames: [], category: 'people' }, + ':woman_playing_handball:': { uc_base: '1f93e-2640', uc_full: '1f93e-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_playing_water_polo:': { uc_base: '1f93d-2640', uc_full: '1f93d-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_police_officer:': { uc_base: '1f46e-2640', uc_full: '1f46e-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_pouting:': { uc_base: '1f64e-2640', uc_full: '1f64e-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_raising_hand:': { uc_base: '1f64b-2640', uc_full: '1f64b-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_rowing_boat:': { uc_base: '1f6a3-2640', uc_full: '1f6a3-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_running:': { uc_base: '1f3c3-2640', uc_full: '1f3c3-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_shrugging:': { uc_base: '1f937-2640', uc_full: '1f937-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_standing:': { uc_base: '1f9cd-2640', uc_full: '1f9cd-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_superhero:': { uc_base: '1f9b8-2640', uc_full: '1f9b8-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_supervillain:': { uc_base: '1f9b9-2640', uc_full: '1f9b9-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_surfing:': { uc_base: '1f3c4-2640', uc_full: '1f3c4-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_swimming:': { uc_base: '1f3ca-2640', uc_full: '1f3ca-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':woman_tipping_hand:': { uc_base: '1f481-2640', uc_full: '1f481-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_vampire:': { uc_base: '1f9db-2640', uc_full: '1f9db-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_walking:': { uc_base: '1f6b6-2640', uc_full: '1f6b6-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_wearing_turban:': { uc_base: '1f473-2640', uc_full: '1f473-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_with_veil:': { uc_base: '1f470-2640', uc_full: '1f470-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':woman_zombie:': { uc_base: '1f9df-2640', uc_full: '1f9df-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':women_with_bunny_ears_partying:': { uc_base: '1f46f-2640', uc_full: '1f46f-200d-2640-fe0f', shortnames: [], category: 'people' }, + ':women_wrestling:': { uc_base: '1f93c-2640', uc_full: '1f93c-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':writing_hand_tone1:': { uc_base: '270d-1f3fb', uc_full: '270d-1f3fb', shortnames: [], category: 'people' }, + ':writing_hand_tone2:': { uc_base: '270d-1f3fc', uc_full: '270d-1f3fc', shortnames: [], category: 'people' }, + ':writing_hand_tone3:': { uc_base: '270d-1f3fd', uc_full: '270d-1f3fd', shortnames: [], category: 'people' }, + ':writing_hand_tone4:': { uc_base: '270d-1f3fe', uc_full: '270d-1f3fe', shortnames: [], category: 'people' }, + ':writing_hand_tone5:': { uc_base: '270d-1f3ff', uc_full: '270d-1f3ff', shortnames: [], category: 'people' }, + ':asterisk:': { uc_base: '002a-20e3', uc_full: '002a-fe0f-20e3', shortnames: [':keycap_asterisk:'], category: 'symbols' }, + ':eight:': { uc_base: '0038-20e3', uc_full: '0038-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':five:': { uc_base: '0035-20e3', uc_full: '0035-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':four:': { uc_base: '0034-20e3', uc_full: '0034-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':hash:': { uc_base: '0023-20e3', uc_full: '0023-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':man_bouncing_ball:': { uc_base: '26f9-2642', uc_full: '26f9-fe0f-200d-2642-fe0f', shortnames: [], category: 'activity' }, + ':nine:': { uc_base: '0039-20e3', uc_full: '0039-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':one:': { uc_base: '0031-20e3', uc_full: '0031-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':seven:': { uc_base: '0037-20e3', uc_full: '0037-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':six:': { uc_base: '0036-20e3', uc_full: '0036-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':three:': { uc_base: '0033-20e3', uc_full: '0033-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':two:': { uc_base: '0032-20e3', uc_full: '0032-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':woman_bouncing_ball:': { uc_base: '26f9-2640', uc_full: '26f9-fe0f-200d-2640-fe0f', shortnames: [], category: 'activity' }, + ':zero:': { uc_base: '0030-20e3', uc_full: '0030-fe0f-20e3', shortnames: [], category: 'symbols' }, + ':100:': { uc_base: '1f4af', uc_full: '1f4af', shortnames: [], category: 'symbols' }, + ':1234:': { uc_base: '1f522', uc_full: '1f522', shortnames: [], category: 'symbols' }, + ':8ball:': { uc_base: '1f3b1', uc_full: '1f3b1', shortnames: [], category: 'activity' }, + ':a:': { uc_base: '1f170', uc_full: '1f170-fe0f', shortnames: [], category: 'symbols' }, + ':ab:': { uc_base: '1f18e', uc_full: '1f18e', shortnames: [], category: 'symbols' }, + ':abacus:': { uc_base: '1f9ee', uc_full: '1f9ee', shortnames: [], category: 'objects' }, + ':abc:': { uc_base: '1f524', uc_full: '1f524', shortnames: [], category: 'symbols' }, + ':abcd:': { uc_base: '1f521', uc_full: '1f521', shortnames: [], category: 'symbols' }, + ':accept:': { uc_base: '1f251', uc_full: '1f251', shortnames: [], category: 'symbols' }, + ':accordion:': { uc_base: '1fa97', uc_full: '1fa97', shortnames: [], category: 'activity' }, + ':adhesive_bandage:': { uc_base: '1fa79', uc_full: '1fa79', shortnames: [], category: 'objects' }, + ':adult:': { uc_base: '1f9d1', uc_full: '1f9d1', shortnames: [], category: 'people' }, + ':aerial_tramway:': { uc_base: '1f6a1', uc_full: '1f6a1', shortnames: [], category: 'travel' }, + ':airplane_arriving:': { uc_base: '1f6ec', uc_full: '1f6ec', shortnames: [], category: 'travel' }, + ':airplane_departure:': { uc_base: '1f6eb', uc_full: '1f6eb', shortnames: [], category: 'travel' }, + ':airplane_small:': { uc_base: '1f6e9', uc_full: '1f6e9-fe0f', shortnames: [':small_airplane:'], category: 'travel' }, + ':alien:': { uc_base: '1f47d', uc_full: '1f47d', shortnames: [], category: 'people' }, + ':ambulance:': { uc_base: '1f691', uc_full: '1f691', shortnames: [], category: 'travel' }, + ':amphora:': { uc_base: '1f3fa', uc_full: '1f3fa', shortnames: [], category: 'objects' }, + ':anatomical_heart:': { uc_base: '1fac0', uc_full: '1fac0', shortnames: [], category: 'people' }, + ':angel:': { uc_base: '1f47c', uc_full: '1f47c', shortnames: [], category: 'people' }, + ':anger:': { uc_base: '1f4a2', uc_full: '1f4a2', shortnames: [], category: 'symbols' }, + ':anger_right:': { uc_base: '1f5ef', uc_full: '1f5ef-fe0f', shortnames: [':right_anger_bubble:'], category: 'symbols' }, + ':angry:': { uc_base: '1f620', uc_full: '1f620', shortnames: [], category: 'people' }, + ':anguished:': { uc_base: '1f627', uc_full: '1f627', shortnames: [], category: 'people' }, + ':ant:': { uc_base: '1f41c', uc_full: '1f41c', shortnames: [], category: 'nature' }, + ':apple:': { uc_base: '1f34e', uc_full: '1f34e', shortnames: [], category: 'food' }, + ':arrow_down_small:': { uc_base: '1f53d', uc_full: '1f53d', shortnames: [], category: 'symbols' }, + ':arrow_up_small:': { uc_base: '1f53c', uc_full: '1f53c', shortnames: [], category: 'symbols' }, + ':arrows_clockwise:': { uc_base: '1f503', uc_full: '1f503', shortnames: [], category: 'symbols' }, + ':arrows_counterclockwise:': { uc_base: '1f504', uc_full: '1f504', shortnames: [], category: 'symbols' }, + ':art:': { uc_base: '1f3a8', uc_full: '1f3a8', shortnames: [], category: 'activity' }, + ':articulated_lorry:': { uc_base: '1f69b', uc_full: '1f69b', shortnames: [], category: 'travel' }, + ':astonished:': { uc_base: '1f632', uc_full: '1f632', shortnames: [], category: 'people' }, + ':athletic_shoe:': { uc_base: '1f45f', uc_full: '1f45f', shortnames: [], category: 'people' }, + ':atm:': { uc_base: '1f3e7', uc_full: '1f3e7', shortnames: [], category: 'symbols' }, + ':auto_rickshaw:': { uc_base: '1f6fa', uc_full: '1f6fa', shortnames: [], category: 'travel' }, + ':avocado:': { uc_base: '1f951', uc_full: '1f951', shortnames: [], category: 'food' }, + ':axe:': { uc_base: '1fa93', uc_full: '1fa93', shortnames: [], category: 'objects' }, + ':b:': { uc_base: '1f171', uc_full: '1f171-fe0f', shortnames: [], category: 'symbols' }, + ':baby:': { uc_base: '1f476', uc_full: '1f476', shortnames: [], category: 'people' }, + ':baby_bottle:': { uc_base: '1f37c', uc_full: '1f37c', shortnames: [], category: 'food' }, + ':baby_chick:': { uc_base: '1f424', uc_full: '1f424', shortnames: [], category: 'nature' }, + ':baby_symbol:': { uc_base: '1f6bc', uc_full: '1f6bc', shortnames: [], category: 'symbols' }, + ':back:': { uc_base: '1f519', uc_full: '1f519', shortnames: [], category: 'symbols' }, + ':bacon:': { uc_base: '1f953', uc_full: '1f953', shortnames: [], category: 'food' }, + ':badger:': { uc_base: '1f9a1', uc_full: '1f9a1', shortnames: [], category: 'nature' }, + ':badminton:': { uc_base: '1f3f8', uc_full: '1f3f8', shortnames: [], category: 'activity' }, + ':bagel:': { uc_base: '1f96f', uc_full: '1f96f', shortnames: [], category: 'food' }, + ':baggage_claim:': { uc_base: '1f6c4', uc_full: '1f6c4', shortnames: [], category: 'symbols' }, + ':bald:': { uc_base: '1f9b2', uc_full: '1f9b2', shortnames: [], category: 'people' }, + ':ballet_shoes:': { uc_base: '1fa70', uc_full: '1fa70', shortnames: [], category: 'activity' }, + ':balloon:': { uc_base: '1f388', uc_full: '1f388', shortnames: [], category: 'objects' }, + ':ballot_box:': { uc_base: '1f5f3', uc_full: '1f5f3-fe0f', shortnames: [':ballot_box_with_ballot:'], category: 'objects' }, + ':bamboo:': { uc_base: '1f38d', uc_full: '1f38d', shortnames: [], category: 'nature' }, + ':banana:': { uc_base: '1f34c', uc_full: '1f34c', shortnames: [], category: 'food' }, + ':banjo:': { uc_base: '1fa95', uc_full: '1fa95', shortnames: [], category: 'activity' }, + ':bank:': { uc_base: '1f3e6', uc_full: '1f3e6', shortnames: [], category: 'travel' }, + ':bar_chart:': { uc_base: '1f4ca', uc_full: '1f4ca', shortnames: [], category: 'objects' }, + ':barber:': { uc_base: '1f488', uc_full: '1f488', shortnames: [], category: 'objects' }, + ':basket:': { uc_base: '1f9fa', uc_full: '1f9fa', shortnames: [], category: 'objects' }, + ':basketball:': { uc_base: '1f3c0', uc_full: '1f3c0', shortnames: [], category: 'activity' }, + ':bat:': { uc_base: '1f987', uc_full: '1f987', shortnames: [], category: 'nature' }, + ':bath:': { uc_base: '1f6c0', uc_full: '1f6c0', shortnames: [], category: 'objects' }, + ':bathtub:': { uc_base: '1f6c1', uc_full: '1f6c1', shortnames: [], category: 'objects' }, + ':battery:': { uc_base: '1f50b', uc_full: '1f50b', shortnames: [], category: 'objects' }, + ':beach:': { uc_base: '1f3d6', uc_full: '1f3d6-fe0f', shortnames: [':beach_with_umbrella:'], category: 'travel' }, + ':bear:': { uc_base: '1f43b', uc_full: '1f43b', shortnames: [], category: 'nature' }, + ':bearded_person:': { uc_base: '1f9d4', uc_full: '1f9d4', shortnames: [], category: 'people' }, + ':beaver:': { uc_base: '1f9ab', uc_full: '1f9ab', shortnames: [], category: 'nature' }, + ':bed:': { uc_base: '1f6cf', uc_full: '1f6cf-fe0f', shortnames: [], category: 'objects' }, + ':bee:': { uc_base: '1f41d', uc_full: '1f41d', shortnames: [], category: 'nature' }, + ':beer:': { uc_base: '1f37a', uc_full: '1f37a', shortnames: [], category: 'food' }, + ':beers:': { uc_base: '1f37b', uc_full: '1f37b', shortnames: [], category: 'food' }, + ':beetle:': { uc_base: '1fab2', uc_full: '1fab2', shortnames: [], category: 'nature' }, + ':beginner:': { uc_base: '1f530', uc_full: '1f530', shortnames: [], category: 'symbols' }, + ':bell:': { uc_base: '1f514', uc_full: '1f514', shortnames: [], category: 'symbols' }, + ':bell_pepper:': { uc_base: '1fad1', uc_full: '1fad1', shortnames: [], category: 'food' }, + ':bellhop:': { uc_base: '1f6ce', uc_full: '1f6ce-fe0f', shortnames: [':bellhop_bell:'], category: 'objects' }, + ':bento:': { uc_base: '1f371', uc_full: '1f371', shortnames: [], category: 'food' }, + ':beverage_box:': { uc_base: '1f9c3', uc_full: '1f9c3', shortnames: [], category: 'food' }, + ':bike:': { uc_base: '1f6b2', uc_full: '1f6b2', shortnames: [], category: 'travel' }, + ':bikini:': { uc_base: '1f459', uc_full: '1f459', shortnames: [], category: 'people' }, + ':billed_cap:': { uc_base: '1f9e2', uc_full: '1f9e2', shortnames: [], category: 'people' }, + ':bird:': { uc_base: '1f426', uc_full: '1f426', shortnames: [], category: 'nature' }, + ':birthday:': { uc_base: '1f382', uc_full: '1f382', shortnames: [], category: 'food' }, + ':bison:': { uc_base: '1f9ac', uc_full: '1f9ac', shortnames: [], category: 'nature' }, + ':black_heart:': { uc_base: '1f5a4', uc_full: '1f5a4', shortnames: [], category: 'symbols' }, + ':black_joker:': { uc_base: '1f0cf', uc_full: '1f0cf', shortnames: [], category: 'symbols' }, + ':black_square_button:': { uc_base: '1f532', uc_full: '1f532', shortnames: [], category: 'symbols' }, + ':blond_haired_person:': { uc_base: '1f471', uc_full: '1f471', shortnames: [':person_with_blond_hair:'], category: 'people' }, + ':blossom:': { uc_base: '1f33c', uc_full: '1f33c', shortnames: [], category: 'nature' }, + ':blowfish:': { uc_base: '1f421', uc_full: '1f421', shortnames: [], category: 'nature' }, + ':blue_book:': { uc_base: '1f4d8', uc_full: '1f4d8', shortnames: [], category: 'objects' }, + ':blue_car:': { uc_base: '1f699', uc_full: '1f699', shortnames: [], category: 'travel' }, + ':blue_circle:': { uc_base: '1f535', uc_full: '1f535', shortnames: [], category: 'symbols' }, + ':blue_heart:': { uc_base: '1f499', uc_full: '1f499', shortnames: [], category: 'symbols' }, + ':blue_square:': { uc_base: '1f7e6', uc_full: '1f7e6', shortnames: [], category: 'symbols' }, + ':blueberries:': { uc_base: '1fad0', uc_full: '1fad0', shortnames: [], category: 'food' }, + ':blush:': { uc_base: '1f60a', uc_full: '1f60a', shortnames: [], category: 'people' }, + ':boar:': { uc_base: '1f417', uc_full: '1f417', shortnames: [], category: 'nature' }, + ':bomb:': { uc_base: '1f4a3', uc_full: '1f4a3', shortnames: [], category: 'objects' }, + ':bone:': { uc_base: '1f9b4', uc_full: '1f9b4', shortnames: [], category: 'people' }, + ':book:': { uc_base: '1f4d6', uc_full: '1f4d6', shortnames: [], category: 'objects' }, + ':bookmark:': { uc_base: '1f516', uc_full: '1f516', shortnames: [], category: 'objects' }, + ':bookmark_tabs:': { uc_base: '1f4d1', uc_full: '1f4d1', shortnames: [], category: 'objects' }, + ':books:': { uc_base: '1f4da', uc_full: '1f4da', shortnames: [], category: 'objects' }, + ':boom:': { uc_base: '1f4a5', uc_full: '1f4a5', shortnames: [], category: 'nature' }, + ':boomerang:': { uc_base: '1fa83', uc_full: '1fa83', shortnames: [], category: 'activity' }, + ':boot:': { uc_base: '1f462', uc_full: '1f462', shortnames: [], category: 'people' }, + ':bouquet:': { uc_base: '1f490', uc_full: '1f490', shortnames: [], category: 'nature' }, + ':bow_and_arrow:': { uc_base: '1f3f9', uc_full: '1f3f9', shortnames: [':archery:'], category: 'activity' }, + ':bowl_with_spoon:': { uc_base: '1f963', uc_full: '1f963', shortnames: [], category: 'food' }, + ':bowling:': { uc_base: '1f3b3', uc_full: '1f3b3', shortnames: [], category: 'activity' }, + ':boxing_glove:': { uc_base: '1f94a', uc_full: '1f94a', shortnames: [':boxing_gloves:'], category: 'activity' }, + ':boy:': { uc_base: '1f466', uc_full: '1f466', shortnames: [], category: 'people' }, + ':brain:': { uc_base: '1f9e0', uc_full: '1f9e0', shortnames: [], category: 'people' }, + ':bread:': { uc_base: '1f35e', uc_full: '1f35e', shortnames: [], category: 'food' }, + ':breast_feeding:': { uc_base: '1f931', uc_full: '1f931', shortnames: [], category: 'people' }, + ':bricks:': { uc_base: '1f9f1', uc_full: '1f9f1', shortnames: [], category: 'objects' }, + ':bridge_at_night:': { uc_base: '1f309', uc_full: '1f309', shortnames: [], category: 'travel' }, + ':briefcase:': { uc_base: '1f4bc', uc_full: '1f4bc', shortnames: [], category: 'people' }, + ':briefs:': { uc_base: '1fa72', uc_full: '1fa72', shortnames: [], category: 'people' }, + ':broccoli:': { uc_base: '1f966', uc_full: '1f966', shortnames: [], category: 'food' }, + ':broken_heart:': { uc_base: '1f494', uc_full: '1f494', shortnames: [], category: 'symbols' }, + ':broom:': { uc_base: '1f9f9', uc_full: '1f9f9', shortnames: [], category: 'objects' }, + ':brown_circle:': { uc_base: '1f7e4', uc_full: '1f7e4', shortnames: [], category: 'symbols' }, + ':brown_heart:': { uc_base: '1f90e', uc_full: '1f90e', shortnames: [], category: 'symbols' }, + ':brown_square:': { uc_base: '1f7eb', uc_full: '1f7eb', shortnames: [], category: 'symbols' }, + ':bubble_tea:': { uc_base: '1f9cb', uc_full: '1f9cb', shortnames: [], category: 'food' }, + ':bucket:': { uc_base: '1faa3', uc_full: '1faa3', shortnames: [], category: 'objects' }, + ':bug:': { uc_base: '1f41b', uc_full: '1f41b', shortnames: [], category: 'nature' }, + ':bulb:': { uc_base: '1f4a1', uc_full: '1f4a1', shortnames: [], category: 'objects' }, + ':bullettrain_front:': { uc_base: '1f685', uc_full: '1f685', shortnames: [], category: 'travel' }, + ':bullettrain_side:': { uc_base: '1f684', uc_full: '1f684', shortnames: [], category: 'travel' }, + ':burrito:': { uc_base: '1f32f', uc_full: '1f32f', shortnames: [], category: 'food' }, + ':bus:': { uc_base: '1f68c', uc_full: '1f68c', shortnames: [], category: 'travel' }, + ':busstop:': { uc_base: '1f68f', uc_full: '1f68f', shortnames: [], category: 'travel' }, + ':bust_in_silhouette:': { uc_base: '1f464', uc_full: '1f464', shortnames: [], category: 'people' }, + ':busts_in_silhouette:': { uc_base: '1f465', uc_full: '1f465', shortnames: [], category: 'people' }, + ':butter:': { uc_base: '1f9c8', uc_full: '1f9c8', shortnames: [], category: 'food' }, + ':butterfly:': { uc_base: '1f98b', uc_full: '1f98b', shortnames: [], category: 'nature' }, + ':cactus:': { uc_base: '1f335', uc_full: '1f335', shortnames: [], category: 'nature' }, + ':cake:': { uc_base: '1f370', uc_full: '1f370', shortnames: [], category: 'food' }, + ':calendar:': { uc_base: '1f4c6', uc_full: '1f4c6', shortnames: [], category: 'objects' }, + ':calendar_spiral:': { uc_base: '1f5d3', uc_full: '1f5d3-fe0f', shortnames: [':spiral_calendar_pad:'], category: 'objects' }, + ':call_me:': { uc_base: '1f919', uc_full: '1f919', shortnames: [':call_me_hand:'], category: 'people' }, + ':calling:': { uc_base: '1f4f2', uc_full: '1f4f2', shortnames: [], category: 'objects' }, + ':camel:': { uc_base: '1f42b', uc_full: '1f42b', shortnames: [], category: 'nature' }, + ':camera:': { uc_base: '1f4f7', uc_full: '1f4f7', shortnames: [], category: 'objects' }, + ':camera_with_flash:': { uc_base: '1f4f8', uc_full: '1f4f8', shortnames: [], category: 'objects' }, + ':camping:': { uc_base: '1f3d5', uc_full: '1f3d5-fe0f', shortnames: [], category: 'travel' }, + ':candle:': { uc_base: '1f56f', uc_full: '1f56f-fe0f', shortnames: [], category: 'objects' }, + ':candy:': { uc_base: '1f36c', uc_full: '1f36c', shortnames: [], category: 'food' }, + ':canned_food:': { uc_base: '1f96b', uc_full: '1f96b', shortnames: [], category: 'food' }, + ':canoe:': { uc_base: '1f6f6', uc_full: '1f6f6', shortnames: [':kayak:'], category: 'travel' }, + ':capital_abcd:': { uc_base: '1f520', uc_full: '1f520', shortnames: [], category: 'symbols' }, + ':card_box:': { uc_base: '1f5c3', uc_full: '1f5c3-fe0f', shortnames: [':card_file_box:'], category: 'objects' }, + ':card_index:': { uc_base: '1f4c7', uc_full: '1f4c7', shortnames: [], category: 'objects' }, + ':carousel_horse:': { uc_base: '1f3a0', uc_full: '1f3a0', shortnames: [], category: 'travel' }, + ':carpentry_saw:': { uc_base: '1fa9a', uc_full: '1fa9a', shortnames: [], category: 'objects' }, + ':carrot:': { uc_base: '1f955', uc_full: '1f955', shortnames: [], category: 'food' }, + ':cat2:': { uc_base: '1f408', uc_full: '1f408', shortnames: [], category: 'nature' }, + ':cat:': { uc_base: '1f431', uc_full: '1f431', shortnames: [], category: 'nature' }, + ':cd:': { uc_base: '1f4bf', uc_full: '1f4bf', shortnames: [], category: 'objects' }, + ':chair:': { uc_base: '1fa91', uc_full: '1fa91', shortnames: [], category: 'objects' }, + ':champagne:': { uc_base: '1f37e', uc_full: '1f37e', shortnames: [':bottle_with_popping_cork:'], category: 'food' }, + ':champagne_glass:': { uc_base: '1f942', uc_full: '1f942', shortnames: [':clinking_glass:'], category: 'food' }, + ':chart:': { uc_base: '1f4b9', uc_full: '1f4b9', shortnames: [], category: 'symbols' }, + ':chart_with_downwards_trend:': { uc_base: '1f4c9', uc_full: '1f4c9', shortnames: [], category: 'objects' }, + ':chart_with_upwards_trend:': { uc_base: '1f4c8', uc_full: '1f4c8', shortnames: [], category: 'objects' }, + ':checkered_flag:': { uc_base: '1f3c1', uc_full: '1f3c1', shortnames: [], category: 'flags' }, + ':cheese:': { uc_base: '1f9c0', uc_full: '1f9c0', shortnames: [':cheese_wedge:'], category: 'food' }, + ':cherries:': { uc_base: '1f352', uc_full: '1f352', shortnames: [], category: 'food' }, + ':cherry_blossom:': { uc_base: '1f338', uc_full: '1f338', shortnames: [], category: 'nature' }, + ':chestnut:': { uc_base: '1f330', uc_full: '1f330', shortnames: [], category: 'food' }, + ':chicken:': { uc_base: '1f414', uc_full: '1f414', shortnames: [], category: 'nature' }, + ':child:': { uc_base: '1f9d2', uc_full: '1f9d2', shortnames: [], category: 'people' }, + ':children_crossing:': { uc_base: '1f6b8', uc_full: '1f6b8', shortnames: [], category: 'symbols' }, + ':chipmunk:': { uc_base: '1f43f', uc_full: '1f43f-fe0f', shortnames: [], category: 'nature' }, + ':chocolate_bar:': { uc_base: '1f36b', uc_full: '1f36b', shortnames: [], category: 'food' }, + ':chopsticks:': { uc_base: '1f962', uc_full: '1f962', shortnames: [], category: 'food' }, + ':christmas_tree:': { uc_base: '1f384', uc_full: '1f384', shortnames: [], category: 'nature' }, + ':cinema:': { uc_base: '1f3a6', uc_full: '1f3a6', shortnames: [], category: 'symbols' }, + ':circus_tent:': { uc_base: '1f3aa', uc_full: '1f3aa', shortnames: [], category: 'activity' }, + ':city_dusk:': { uc_base: '1f306', uc_full: '1f306', shortnames: [], category: 'travel' }, + ':city_sunset:': { uc_base: '1f307', uc_full: '1f307', shortnames: [':city_sunrise:'], category: 'travel' }, + ':cityscape:': { uc_base: '1f3d9', uc_full: '1f3d9-fe0f', shortnames: [], category: 'travel' }, + ':cl:': { uc_base: '1f191', uc_full: '1f191', shortnames: [], category: 'symbols' }, + ':clap:': { uc_base: '1f44f', uc_full: '1f44f', shortnames: [], category: 'people' }, + ':clapper:': { uc_base: '1f3ac', uc_full: '1f3ac', shortnames: [], category: 'activity' }, + ':classical_building:': { uc_base: '1f3db', uc_full: '1f3db-fe0f', shortnames: [], category: 'travel' }, + ':clipboard:': { uc_base: '1f4cb', uc_full: '1f4cb', shortnames: [], category: 'objects' }, + ':clock1030:': { uc_base: '1f565', uc_full: '1f565', shortnames: [], category: 'symbols' }, + ':clock10:': { uc_base: '1f559', uc_full: '1f559', shortnames: [], category: 'symbols' }, + ':clock1130:': { uc_base: '1f566', uc_full: '1f566', shortnames: [], category: 'symbols' }, + ':clock11:': { uc_base: '1f55a', uc_full: '1f55a', shortnames: [], category: 'symbols' }, + ':clock1230:': { uc_base: '1f567', uc_full: '1f567', shortnames: [], category: 'symbols' }, + ':clock12:': { uc_base: '1f55b', uc_full: '1f55b', shortnames: [], category: 'symbols' }, + ':clock130:': { uc_base: '1f55c', uc_full: '1f55c', shortnames: [], category: 'symbols' }, + ':clock1:': { uc_base: '1f550', uc_full: '1f550', shortnames: [], category: 'symbols' }, + ':clock230:': { uc_base: '1f55d', uc_full: '1f55d', shortnames: [], category: 'symbols' }, + ':clock2:': { uc_base: '1f551', uc_full: '1f551', shortnames: [], category: 'symbols' }, + ':clock330:': { uc_base: '1f55e', uc_full: '1f55e', shortnames: [], category: 'symbols' }, + ':clock3:': { uc_base: '1f552', uc_full: '1f552', shortnames: [], category: 'symbols' }, + ':clock430:': { uc_base: '1f55f', uc_full: '1f55f', shortnames: [], category: 'symbols' }, + ':clock4:': { uc_base: '1f553', uc_full: '1f553', shortnames: [], category: 'symbols' }, + ':clock530:': { uc_base: '1f560', uc_full: '1f560', shortnames: [], category: 'symbols' }, + ':clock5:': { uc_base: '1f554', uc_full: '1f554', shortnames: [], category: 'symbols' }, + ':clock630:': { uc_base: '1f561', uc_full: '1f561', shortnames: [], category: 'symbols' }, + ':clock6:': { uc_base: '1f555', uc_full: '1f555', shortnames: [], category: 'symbols' }, + ':clock730:': { uc_base: '1f562', uc_full: '1f562', shortnames: [], category: 'symbols' }, + ':clock7:': { uc_base: '1f556', uc_full: '1f556', shortnames: [], category: 'symbols' }, + ':clock830:': { uc_base: '1f563', uc_full: '1f563', shortnames: [], category: 'symbols' }, + ':clock8:': { uc_base: '1f557', uc_full: '1f557', shortnames: [], category: 'symbols' }, + ':clock930:': { uc_base: '1f564', uc_full: '1f564', shortnames: [], category: 'symbols' }, + ':clock9:': { uc_base: '1f558', uc_full: '1f558', shortnames: [], category: 'symbols' }, + ':clock:': { uc_base: '1f570', uc_full: '1f570-fe0f', shortnames: [':mantlepiece_clock:'], category: 'objects' }, + ':closed_book:': { uc_base: '1f4d5', uc_full: '1f4d5', shortnames: [], category: 'objects' }, + ':closed_lock_with_key:': { uc_base: '1f510', uc_full: '1f510', shortnames: [], category: 'objects' }, + ':closed_umbrella:': { uc_base: '1f302', uc_full: '1f302', shortnames: [], category: 'people' }, + ':cloud_lightning:': { uc_base: '1f329', uc_full: '1f329-fe0f', shortnames: [':cloud_with_lightning:'], category: 'nature' }, + ':cloud_rain:': { uc_base: '1f327', uc_full: '1f327-fe0f', shortnames: [':cloud_with_rain:'], category: 'nature' }, + ':cloud_snow:': { uc_base: '1f328', uc_full: '1f328-fe0f', shortnames: [':cloud_with_snow:'], category: 'nature' }, + ':cloud_tornado:': { uc_base: '1f32a', uc_full: '1f32a-fe0f', shortnames: [':cloud_with_tornado:'], category: 'nature' }, + ':clown:': { uc_base: '1f921', uc_full: '1f921', shortnames: [':clown_face:'], category: 'people' }, + ':coat:': { uc_base: '1f9e5', uc_full: '1f9e5', shortnames: [], category: 'people' }, + ':cockroach:': { uc_base: '1fab3', uc_full: '1fab3', shortnames: [], category: 'nature' }, + ':cocktail:': { uc_base: '1f378', uc_full: '1f378', shortnames: [], category: 'food' }, + ':coconut:': { uc_base: '1f965', uc_full: '1f965', shortnames: [], category: 'food' }, + ':coin:': { uc_base: '1fa99', uc_full: '1fa99', shortnames: [], category: 'objects' }, + ':cold_face:': { uc_base: '1f976', uc_full: '1f976', shortnames: [], category: 'people' }, + ':cold_sweat:': { uc_base: '1f630', uc_full: '1f630', shortnames: [], category: 'people' }, + ':compass:': { uc_base: '1f9ed', uc_full: '1f9ed', shortnames: [], category: 'objects' }, + ':compression:': { uc_base: '1f5dc', uc_full: '1f5dc-fe0f', shortnames: [], category: 'objects' }, + ':computer:': { uc_base: '1f4bb', uc_full: '1f4bb', shortnames: [], category: 'objects' }, + ':confetti_ball:': { uc_base: '1f38a', uc_full: '1f38a', shortnames: [], category: 'objects' }, + ':confounded:': { uc_base: '1f616', uc_full: '1f616', shortnames: [], category: 'people' }, + ':confused:': { uc_base: '1f615', uc_full: '1f615', shortnames: [], category: 'people' }, + ':construction:': { uc_base: '1f6a7', uc_full: '1f6a7', shortnames: [], category: 'travel' }, + ':construction_site:': { uc_base: '1f3d7', uc_full: '1f3d7-fe0f', shortnames: [':building_construction:'], category: 'travel' }, + ':construction_worker:': { uc_base: '1f477', uc_full: '1f477', shortnames: [], category: 'people' }, + ':control_knobs:': { uc_base: '1f39b', uc_full: '1f39b-fe0f', shortnames: [], category: 'objects' }, + ':convenience_store:': { uc_base: '1f3ea', uc_full: '1f3ea', shortnames: [], category: 'travel' }, + ':cookie:': { uc_base: '1f36a', uc_full: '1f36a', shortnames: [], category: 'food' }, + ':cooking:': { uc_base: '1f373', uc_full: '1f373', shortnames: [], category: 'food' }, + ':cool:': { uc_base: '1f192', uc_full: '1f192', shortnames: [], category: 'symbols' }, + ':corn:': { uc_base: '1f33d', uc_full: '1f33d', shortnames: [], category: 'food' }, + ':couch:': { uc_base: '1f6cb', uc_full: '1f6cb-fe0f', shortnames: [':couch_and_lamp:'], category: 'objects' }, + ':couple:': { uc_base: '1f46b', uc_full: '1f46b', shortnames: [], category: 'people' }, + ':couple_with_heart:': { uc_base: '1f491', uc_full: '1f491', shortnames: [], category: 'people' }, + ':couplekiss:': { uc_base: '1f48f', uc_full: '1f48f', shortnames: [], category: 'people' }, + ':cow2:': { uc_base: '1f404', uc_full: '1f404', shortnames: [], category: 'nature' }, + ':cow:': { uc_base: '1f42e', uc_full: '1f42e', shortnames: [], category: 'nature' }, + ':cowboy:': { uc_base: '1f920', uc_full: '1f920', shortnames: [':face_with_cowboy_hat:'], category: 'people' }, + ':crab:': { uc_base: '1f980', uc_full: '1f980', shortnames: [], category: 'nature' }, + ':crayon:': { uc_base: '1f58d', uc_full: '1f58d-fe0f', shortnames: [':lower_left_crayon:'], category: 'objects' }, + ':credit_card:': { uc_base: '1f4b3', uc_full: '1f4b3', shortnames: [], category: 'objects' }, + ':crescent_moon:': { uc_base: '1f319', uc_full: '1f319', shortnames: [], category: 'nature' }, + ':cricket:': { uc_base: '1f997', uc_full: '1f997', shortnames: [], category: 'nature' }, + ':cricket_game:': { uc_base: '1f3cf', uc_full: '1f3cf', shortnames: [':cricket_bat_ball:'], category: 'activity' }, + ':crocodile:': { uc_base: '1f40a', uc_full: '1f40a', shortnames: [], category: 'nature' }, + ':croissant:': { uc_base: '1f950', uc_full: '1f950', shortnames: [], category: 'food' }, + ':crossed_flags:': { uc_base: '1f38c', uc_full: '1f38c', shortnames: [], category: 'flags' }, + ':crown:': { uc_base: '1f451', uc_full: '1f451', shortnames: [], category: 'people' }, + ':cruise_ship:': { uc_base: '1f6f3', uc_full: '1f6f3-fe0f', shortnames: [':passenger_ship:'], category: 'travel' }, + ':cry:': { uc_base: '1f622', uc_full: '1f622', shortnames: [], category: 'people' }, + ':crying_cat_face:': { uc_base: '1f63f', uc_full: '1f63f', shortnames: [], category: 'people' }, + ':crystal_ball:': { uc_base: '1f52e', uc_full: '1f52e', shortnames: [], category: 'objects' }, + ':cucumber:': { uc_base: '1f952', uc_full: '1f952', shortnames: [], category: 'food' }, + ':cup_with_straw:': { uc_base: '1f964', uc_full: '1f964', shortnames: [], category: 'food' }, + ':cupcake:': { uc_base: '1f9c1', uc_full: '1f9c1', shortnames: [], category: 'food' }, + ':cupid:': { uc_base: '1f498', uc_full: '1f498', shortnames: [], category: 'symbols' }, + ':curling_stone:': { uc_base: '1f94c', uc_full: '1f94c', shortnames: [], category: 'activity' }, + ':curly_haired:': { uc_base: '1f9b1', uc_full: '1f9b1', shortnames: [], category: 'people' }, + ':currency_exchange:': { uc_base: '1f4b1', uc_full: '1f4b1', shortnames: [], category: 'symbols' }, + ':curry:': { uc_base: '1f35b', uc_full: '1f35b', shortnames: [], category: 'food' }, + ':custard:': { uc_base: '1f36e', uc_full: '1f36e', shortnames: [':pudding:', ':flan:'], category: 'food' }, + ':customs:': { uc_base: '1f6c3', uc_full: '1f6c3', shortnames: [], category: 'symbols' }, + ':cut_of_meat:': { uc_base: '1f969', uc_full: '1f969', shortnames: [], category: 'food' }, + ':cyclone:': { uc_base: '1f300', uc_full: '1f300', shortnames: [], category: 'symbols' }, + ':dagger:': { uc_base: '1f5e1', uc_full: '1f5e1-fe0f', shortnames: [':dagger_knife:'], category: 'objects' }, + ':dancer:': { uc_base: '1f483', uc_full: '1f483', shortnames: [], category: 'people' }, + ':dango:': { uc_base: '1f361', uc_full: '1f361', shortnames: [], category: 'food' }, + ':dark_sunglasses:': { uc_base: '1f576', uc_full: '1f576-fe0f', shortnames: [], category: 'people' }, + ':dart:': { uc_base: '1f3af', uc_full: '1f3af', shortnames: [], category: 'activity' }, + ':dash:': { uc_base: '1f4a8', uc_full: '1f4a8', shortnames: [], category: 'nature' }, + ':date:': { uc_base: '1f4c5', uc_full: '1f4c5', shortnames: [], category: 'objects' }, + ':deaf_person:': { uc_base: '1f9cf', uc_full: '1f9cf', shortnames: [], category: 'people' }, + ':deciduous_tree:': { uc_base: '1f333', uc_full: '1f333', shortnames: [], category: 'nature' }, + ':deer:': { uc_base: '1f98c', uc_full: '1f98c', shortnames: [], category: 'nature' }, + ':department_store:': { uc_base: '1f3ec', uc_full: '1f3ec', shortnames: [], category: 'travel' }, + ':desert:': { uc_base: '1f3dc', uc_full: '1f3dc-fe0f', shortnames: [], category: 'travel' }, + ':desktop:': { uc_base: '1f5a5', uc_full: '1f5a5-fe0f', shortnames: [':desktop_computer:'], category: 'objects' }, + ':detective:': { uc_base: '1f575', uc_full: '1f575', shortnames: [':spy:', ':sleuth_or_spy:'], category: 'people' }, + ':diamond_shape_with_a_dot_inside:': { uc_base: '1f4a0', uc_full: '1f4a0', shortnames: [], category: 'symbols' }, + ':disappointed:': { uc_base: '1f61e', uc_full: '1f61e', shortnames: [], category: 'people' }, + ':disappointed_relieved:': { uc_base: '1f625', uc_full: '1f625', shortnames: [], category: 'people' }, + ':disguised_face:': { uc_base: '1f978', uc_full: '1f978', shortnames: [], category: 'people' }, + ':dividers:': { uc_base: '1f5c2', uc_full: '1f5c2-fe0f', shortnames: [':card_index_dividers:'], category: 'objects' }, + ':diving_mask:': { uc_base: '1f93f', uc_full: '1f93f', shortnames: [], category: 'activity' }, + ':diya_lamp:': { uc_base: '1fa94', uc_full: '1fa94', shortnames: [], category: 'objects' }, + ':dizzy:': { uc_base: '1f4ab', uc_full: '1f4ab', shortnames: [], category: 'nature' }, + ':dizzy_face:': { uc_base: '1f635', uc_full: '1f635', shortnames: [], category: 'people' }, + ':dna:': { uc_base: '1f9ec', uc_full: '1f9ec', shortnames: [], category: 'objects' }, + ':do_not_litter:': { uc_base: '1f6af', uc_full: '1f6af', shortnames: [], category: 'symbols' }, + ':dodo:': { uc_base: '1f9a4', uc_full: '1f9a4', shortnames: [], category: 'nature' }, + ':dog2:': { uc_base: '1f415', uc_full: '1f415', shortnames: [], category: 'nature' }, + ':dog:': { uc_base: '1f436', uc_full: '1f436', shortnames: [], category: 'nature' }, + ':dollar:': { uc_base: '1f4b5', uc_full: '1f4b5', shortnames: [], category: 'objects' }, + ':dolls:': { uc_base: '1f38e', uc_full: '1f38e', shortnames: [], category: 'objects' }, + ':dolphin:': { uc_base: '1f42c', uc_full: '1f42c', shortnames: [], category: 'nature' }, + ':door:': { uc_base: '1f6aa', uc_full: '1f6aa', shortnames: [], category: 'objects' }, + ':doughnut:': { uc_base: '1f369', uc_full: '1f369', shortnames: [], category: 'food' }, + ':dove:': { uc_base: '1f54a', uc_full: '1f54a-fe0f', shortnames: [':dove_of_peace:'], category: 'nature' }, + ':dragon:': { uc_base: '1f409', uc_full: '1f409', shortnames: [], category: 'nature' }, + ':dragon_face:': { uc_base: '1f432', uc_full: '1f432', shortnames: [], category: 'nature' }, + ':dress:': { uc_base: '1f457', uc_full: '1f457', shortnames: [], category: 'people' }, + ':dromedary_camel:': { uc_base: '1f42a', uc_full: '1f42a', shortnames: [], category: 'nature' }, + ':drooling_face:': { uc_base: '1f924', uc_full: '1f924', shortnames: [':drool:'], category: 'people' }, + ':drop_of_blood:': { uc_base: '1fa78', uc_full: '1fa78', shortnames: [], category: 'objects' }, + ':droplet:': { uc_base: '1f4a7', uc_full: '1f4a7', shortnames: [], category: 'nature' }, + ':drum:': { uc_base: '1f941', uc_full: '1f941', shortnames: [':drum_with_drumsticks:'], category: 'activity' }, + ':duck:': { uc_base: '1f986', uc_full: '1f986', shortnames: [], category: 'nature' }, + ':dumpling:': { uc_base: '1f95f', uc_full: '1f95f', shortnames: [], category: 'food' }, + ':dvd:': { uc_base: '1f4c0', uc_full: '1f4c0', shortnames: [], category: 'objects' }, + ':e-mail:': { uc_base: '1f4e7', uc_full: '1f4e7', shortnames: [':email:'], category: 'objects' }, + ':eagle:': { uc_base: '1f985', uc_full: '1f985', shortnames: [], category: 'nature' }, + ':ear:': { uc_base: '1f442', uc_full: '1f442', shortnames: [], category: 'people' }, + ':ear_of_rice:': { uc_base: '1f33e', uc_full: '1f33e', shortnames: [], category: 'nature' }, + ':ear_with_hearing_aid:': { uc_base: '1f9bb', uc_full: '1f9bb', shortnames: [], category: 'people' }, + ':earth_africa:': { uc_base: '1f30d', uc_full: '1f30d', shortnames: [], category: 'nature' }, + ':earth_americas:': { uc_base: '1f30e', uc_full: '1f30e', shortnames: [], category: 'nature' }, + ':earth_asia:': { uc_base: '1f30f', uc_full: '1f30f', shortnames: [], category: 'nature' }, + ':egg:': { uc_base: '1f95a', uc_full: '1f95a', shortnames: [], category: 'food' }, + ':eggplant:': { uc_base: '1f346', uc_full: '1f346', shortnames: [], category: 'food' }, + ':electric_plug:': { uc_base: '1f50c', uc_full: '1f50c', shortnames: [], category: 'objects' }, + ':elephant:': { uc_base: '1f418', uc_full: '1f418', shortnames: [], category: 'nature' }, + ':elevator:': { uc_base: '1f6d7', uc_full: '1f6d7', shortnames: [], category: 'symbols' }, + ':elf:': { uc_base: '1f9dd', uc_full: '1f9dd', shortnames: [], category: 'people' }, + ':end:': { uc_base: '1f51a', uc_full: '1f51a', shortnames: [], category: 'symbols' }, + ':envelope_with_arrow:': { uc_base: '1f4e9', uc_full: '1f4e9', shortnames: [], category: 'objects' }, + ':euro:': { uc_base: '1f4b6', uc_full: '1f4b6', shortnames: [], category: 'objects' }, + ':european_castle:': { uc_base: '1f3f0', uc_full: '1f3f0', shortnames: [], category: 'travel' }, + ':european_post_office:': { uc_base: '1f3e4', uc_full: '1f3e4', shortnames: [], category: 'travel' }, + ':evergreen_tree:': { uc_base: '1f332', uc_full: '1f332', shortnames: [], category: 'nature' }, + ':exploding_head:': { uc_base: '1f92f', uc_full: '1f92f', shortnames: [], category: 'people' }, + ':expressionless:': { uc_base: '1f611', uc_full: '1f611', shortnames: [], category: 'people' }, + ':eye:': { uc_base: '1f441', uc_full: '1f441-fe0f', shortnames: [], category: 'people' }, + ':eyeglasses:': { uc_base: '1f453', uc_full: '1f453', shortnames: [], category: 'people' }, + ':eyes:': { uc_base: '1f440', uc_full: '1f440', shortnames: [], category: 'people' }, + ':face_vomiting:': { uc_base: '1f92e', uc_full: '1f92e', shortnames: [], category: 'people' }, + ':face_with_hand_over_mouth:': { uc_base: '1f92d', uc_full: '1f92d', shortnames: [], category: 'people' }, + ':face_with_monocle:': { uc_base: '1f9d0', uc_full: '1f9d0', shortnames: [], category: 'people' }, + ':face_with_raised_eyebrow:': { uc_base: '1f928', uc_full: '1f928', shortnames: [], category: 'people' }, + ':face_with_symbols_over_mouth:': { uc_base: '1f92c', uc_full: '1f92c', shortnames: [], category: 'people' }, + ':factory:': { uc_base: '1f3ed', uc_full: '1f3ed', shortnames: [], category: 'travel' }, + ':fairy:': { uc_base: '1f9da', uc_full: '1f9da', shortnames: [], category: 'people' }, + ':falafel:': { uc_base: '1f9c6', uc_full: '1f9c6', shortnames: [], category: 'food' }, + ':fallen_leaf:': { uc_base: '1f342', uc_full: '1f342', shortnames: [], category: 'nature' }, + ':family:': { uc_base: '1f46a', uc_full: '1f46a', shortnames: [], category: 'people' }, + ':fax:': { uc_base: '1f4e0', uc_full: '1f4e0', shortnames: [], category: 'objects' }, + ':fearful:': { uc_base: '1f628', uc_full: '1f628', shortnames: [], category: 'people' }, + ':feather:': { uc_base: '1fab6', uc_full: '1fab6', shortnames: [], category: 'nature' }, + ':feet:': { uc_base: '1f43e', uc_full: '1f43e', shortnames: [':paw_prints:'], category: 'nature' }, + ':ferris_wheel:': { uc_base: '1f3a1', uc_full: '1f3a1', shortnames: [], category: 'travel' }, + ':field_hockey:': { uc_base: '1f3d1', uc_full: '1f3d1', shortnames: [], category: 'activity' }, + ':file_cabinet:': { uc_base: '1f5c4', uc_full: '1f5c4-fe0f', shortnames: [], category: 'objects' }, + ':file_folder:': { uc_base: '1f4c1', uc_full: '1f4c1', shortnames: [], category: 'objects' }, + ':film_frames:': { uc_base: '1f39e', uc_full: '1f39e-fe0f', shortnames: [], category: 'objects' }, + ':fingers_crossed:': { + uc_base: '1f91e', + uc_full: '1f91e', + shortnames: [':hand_with_index_and_middle_finger_crossed:'], + category: 'people', + }, + ':fire:': { uc_base: '1f525', uc_full: '1f525', shortnames: [':flame:'], category: 'nature' }, + ':fire_engine:': { uc_base: '1f692', uc_full: '1f692', shortnames: [], category: 'travel' }, + ':fire_extinguisher:': { uc_base: '1f9ef', uc_full: '1f9ef', shortnames: [], category: 'objects' }, + ':firecracker:': { uc_base: '1f9e8', uc_full: '1f9e8', shortnames: [], category: 'objects' }, + ':fireworks:': { uc_base: '1f386', uc_full: '1f386', shortnames: [], category: 'travel' }, + ':first_place:': { uc_base: '1f947', uc_full: '1f947', shortnames: [':first_place_medal:'], category: 'activity' }, + ':first_quarter_moon:': { uc_base: '1f313', uc_full: '1f313', shortnames: [], category: 'nature' }, + ':first_quarter_moon_with_face:': { uc_base: '1f31b', uc_full: '1f31b', shortnames: [], category: 'nature' }, + ':fish:': { uc_base: '1f41f', uc_full: '1f41f', shortnames: [], category: 'nature' }, + ':fish_cake:': { uc_base: '1f365', uc_full: '1f365', shortnames: [], category: 'food' }, + ':fishing_pole_and_fish:': { uc_base: '1f3a3', uc_full: '1f3a3', shortnames: [], category: 'activity' }, + ':flag_black:': { uc_base: '1f3f4', uc_full: '1f3f4', shortnames: [':waving_black_flag:'], category: 'flags' }, + ':flag_white:': { uc_base: '1f3f3', uc_full: '1f3f3-fe0f', shortnames: [':waving_white_flag:'], category: 'flags' }, + ':flags:': { uc_base: '1f38f', uc_full: '1f38f', shortnames: [], category: 'objects' }, + ':flamingo:': { uc_base: '1f9a9', uc_full: '1f9a9', shortnames: [], category: 'nature' }, + ':flashlight:': { uc_base: '1f526', uc_full: '1f526', shortnames: [], category: 'objects' }, + ':flatbread:': { uc_base: '1fad3', uc_full: '1fad3', shortnames: [], category: 'food' }, + ':floppy_disk:': { uc_base: '1f4be', uc_full: '1f4be', shortnames: [], category: 'objects' }, + ':flower_playing_cards:': { uc_base: '1f3b4', uc_full: '1f3b4', shortnames: [], category: 'symbols' }, + ':flushed:': { uc_base: '1f633', uc_full: '1f633', shortnames: [], category: 'people' }, + ':fly:': { uc_base: '1fab0', uc_full: '1fab0', shortnames: [], category: 'nature' }, + ':flying_disc:': { uc_base: '1f94f', uc_full: '1f94f', shortnames: [], category: 'activity' }, + ':flying_saucer:': { uc_base: '1f6f8', uc_full: '1f6f8', shortnames: [], category: 'travel' }, + ':fog:': { uc_base: '1f32b', uc_full: '1f32b-fe0f', shortnames: [], category: 'nature' }, + ':foggy:': { uc_base: '1f301', uc_full: '1f301', shortnames: [], category: 'travel' }, + ':fondue:': { uc_base: '1fad5', uc_full: '1fad5', shortnames: [], category: 'food' }, + ':foot:': { uc_base: '1f9b6', uc_full: '1f9b6', shortnames: [], category: 'people' }, + ':football:': { uc_base: '1f3c8', uc_full: '1f3c8', shortnames: [], category: 'activity' }, + ':footprints:': { uc_base: '1f463', uc_full: '1f463', shortnames: [], category: 'people' }, + ':fork_and_knife:': { uc_base: '1f374', uc_full: '1f374', shortnames: [], category: 'food' }, + ':fork_knife_plate:': { uc_base: '1f37d', uc_full: '1f37d-fe0f', shortnames: [':fork_and_knife_with_plate:'], category: 'food' }, + ':fortune_cookie:': { uc_base: '1f960', uc_full: '1f960', shortnames: [], category: 'food' }, + ':four_leaf_clover:': { uc_base: '1f340', uc_full: '1f340', shortnames: [], category: 'nature' }, + ':fox:': { uc_base: '1f98a', uc_full: '1f98a', shortnames: [':fox_face:'], category: 'nature' }, + ':frame_photo:': { uc_base: '1f5bc', uc_full: '1f5bc-fe0f', shortnames: [':frame_with_picture:'], category: 'objects' }, + ':free:': { uc_base: '1f193', uc_full: '1f193', shortnames: [], category: 'symbols' }, + ':french_bread:': { uc_base: '1f956', uc_full: '1f956', shortnames: [':baguette_bread:'], category: 'food' }, + ':fried_shrimp:': { uc_base: '1f364', uc_full: '1f364', shortnames: [], category: 'food' }, + ':fries:': { uc_base: '1f35f', uc_full: '1f35f', shortnames: [], category: 'food' }, + ':frog:': { uc_base: '1f438', uc_full: '1f438', shortnames: [], category: 'nature' }, + ':frowning:': { uc_base: '1f626', uc_full: '1f626', shortnames: [], category: 'people' }, + ':full_moon:': { uc_base: '1f315', uc_full: '1f315', shortnames: [], category: 'nature' }, + ':full_moon_with_face:': { uc_base: '1f31d', uc_full: '1f31d', shortnames: [], category: 'nature' }, + ':game_die:': { uc_base: '1f3b2', uc_full: '1f3b2', shortnames: [], category: 'activity' }, + ':garlic:': { uc_base: '1f9c4', uc_full: '1f9c4', shortnames: [], category: 'food' }, + ':gem:': { uc_base: '1f48e', uc_full: '1f48e', shortnames: [], category: 'objects' }, + ':genie:': { uc_base: '1f9de', uc_full: '1f9de', shortnames: [], category: 'people' }, + ':ghost:': { uc_base: '1f47b', uc_full: '1f47b', shortnames: [], category: 'people' }, + ':gift:': { uc_base: '1f381', uc_full: '1f381', shortnames: [], category: 'objects' }, + ':gift_heart:': { uc_base: '1f49d', uc_full: '1f49d', shortnames: [], category: 'symbols' }, + ':giraffe:': { uc_base: '1f992', uc_full: '1f992', shortnames: [], category: 'nature' }, + ':girl:': { uc_base: '1f467', uc_full: '1f467', shortnames: [], category: 'people' }, + ':globe_with_meridians:': { uc_base: '1f310', uc_full: '1f310', shortnames: [], category: 'symbols' }, + ':gloves:': { uc_base: '1f9e4', uc_full: '1f9e4', shortnames: [], category: 'people' }, + ':goal:': { uc_base: '1f945', uc_full: '1f945', shortnames: [':goal_net:'], category: 'activity' }, + ':goat:': { uc_base: '1f410', uc_full: '1f410', shortnames: [], category: 'nature' }, + ':goggles:': { uc_base: '1f97d', uc_full: '1f97d', shortnames: [], category: 'people' }, + ':gorilla:': { uc_base: '1f98d', uc_full: '1f98d', shortnames: [], category: 'nature' }, + ':grapes:': { uc_base: '1f347', uc_full: '1f347', shortnames: [], category: 'food' }, + ':green_apple:': { uc_base: '1f34f', uc_full: '1f34f', shortnames: [], category: 'food' }, + ':green_book:': { uc_base: '1f4d7', uc_full: '1f4d7', shortnames: [], category: 'objects' }, + ':green_circle:': { uc_base: '1f7e2', uc_full: '1f7e2', shortnames: [], category: 'symbols' }, + ':green_heart:': { uc_base: '1f49a', uc_full: '1f49a', shortnames: [], category: 'symbols' }, + ':green_square:': { uc_base: '1f7e9', uc_full: '1f7e9', shortnames: [], category: 'symbols' }, + ':grimacing:': { uc_base: '1f62c', uc_full: '1f62c', shortnames: [], category: 'people' }, + ':grin:': { uc_base: '1f601', uc_full: '1f601', shortnames: [], category: 'people' }, + ':grinning:': { uc_base: '1f600', uc_full: '1f600', shortnames: [], category: 'people' }, + ':guard:': { uc_base: '1f482', uc_full: '1f482', shortnames: [':guardsman:'], category: 'people' }, + ':guide_dog:': { uc_base: '1f9ae', uc_full: '1f9ae', shortnames: [], category: 'nature' }, + ':guitar:': { uc_base: '1f3b8', uc_full: '1f3b8', shortnames: [], category: 'activity' }, + ':gun:': { uc_base: '1f52b', uc_full: '1f52b', shortnames: [], category: 'objects' }, + ':hamburger:': { uc_base: '1f354', uc_full: '1f354', shortnames: [], category: 'food' }, + ':hammer:': { uc_base: '1f528', uc_full: '1f528', shortnames: [], category: 'objects' }, + ':hamster:': { uc_base: '1f439', uc_full: '1f439', shortnames: [], category: 'nature' }, + ':hand_splayed:': { uc_base: '1f590', uc_full: '1f590', shortnames: [':raised_hand_with_fingers_splayed:'], category: 'people' }, + ':handbag:': { uc_base: '1f45c', uc_full: '1f45c', shortnames: [], category: 'people' }, + ':handshake:': { uc_base: '1f91d', uc_full: '1f91d', shortnames: [':shaking_hands:'], category: 'people' }, + ':hatched_chick:': { uc_base: '1f425', uc_full: '1f425', shortnames: [], category: 'nature' }, + ':hatching_chick:': { uc_base: '1f423', uc_full: '1f423', shortnames: [], category: 'nature' }, + ':head_bandage:': { uc_base: '1f915', uc_full: '1f915', shortnames: [':face_with_head_bandage:'], category: 'people' }, + ':headphones:': { uc_base: '1f3a7', uc_full: '1f3a7', shortnames: [], category: 'activity' }, + ':headstone:': { uc_base: '1faa6', uc_full: '1faa6', shortnames: [], category: 'objects' }, + ':hear_no_evil:': { uc_base: '1f649', uc_full: '1f649', shortnames: [], category: 'nature' }, + ':heart_decoration:': { uc_base: '1f49f', uc_full: '1f49f', shortnames: [], category: 'symbols' }, + ':heart_eyes:': { uc_base: '1f60d', uc_full: '1f60d', shortnames: [], category: 'people' }, + ':heart_eyes_cat:': { uc_base: '1f63b', uc_full: '1f63b', shortnames: [], category: 'people' }, + ':heartbeat:': { uc_base: '1f493', uc_full: '1f493', shortnames: [], category: 'symbols' }, + ':heartpulse:': { uc_base: '1f497', uc_full: '1f497', shortnames: [], category: 'symbols' }, + ':heavy_dollar_sign:': { uc_base: '1f4b2', uc_full: '1f4b2', shortnames: [], category: 'symbols' }, + ':hedgehog:': { uc_base: '1f994', uc_full: '1f994', shortnames: [], category: 'nature' }, + ':helicopter:': { uc_base: '1f681', uc_full: '1f681', shortnames: [], category: 'travel' }, + ':herb:': { uc_base: '1f33f', uc_full: '1f33f', shortnames: [], category: 'nature' }, + ':hibiscus:': { uc_base: '1f33a', uc_full: '1f33a', shortnames: [], category: 'nature' }, + ':high_brightness:': { uc_base: '1f506', uc_full: '1f506', shortnames: [], category: 'symbols' }, + ':high_heel:': { uc_base: '1f460', uc_full: '1f460', shortnames: [], category: 'people' }, + ':hiking_boot:': { uc_base: '1f97e', uc_full: '1f97e', shortnames: [], category: 'people' }, + ':hindu_temple:': { uc_base: '1f6d5', uc_full: '1f6d5', shortnames: [], category: 'travel' }, + ':hippopotamus:': { uc_base: '1f99b', uc_full: '1f99b', shortnames: [], category: 'nature' }, + ':hockey:': { uc_base: '1f3d2', uc_full: '1f3d2', shortnames: [], category: 'activity' }, + ':hole:': { uc_base: '1f573', uc_full: '1f573-fe0f', shortnames: [], category: 'objects' }, + ':homes:': { uc_base: '1f3d8', uc_full: '1f3d8-fe0f', shortnames: [':house_buildings:'], category: 'travel' }, + ':honey_pot:': { uc_base: '1f36f', uc_full: '1f36f', shortnames: [], category: 'food' }, + ':hook:': { uc_base: '1fa9d', uc_full: '1fa9d', shortnames: [], category: 'objects' }, + ':horse:': { uc_base: '1f434', uc_full: '1f434', shortnames: [], category: 'nature' }, + ':horse_racing:': { uc_base: '1f3c7', uc_full: '1f3c7', shortnames: [], category: 'activity' }, + ':hospital:': { uc_base: '1f3e5', uc_full: '1f3e5', shortnames: [], category: 'travel' }, + ':hot_face:': { uc_base: '1f975', uc_full: '1f975', shortnames: [], category: 'people' }, + ':hot_pepper:': { uc_base: '1f336', uc_full: '1f336-fe0f', shortnames: [], category: 'food' }, + ':hotdog:': { uc_base: '1f32d', uc_full: '1f32d', shortnames: [':hot_dog:'], category: 'food' }, + ':hotel:': { uc_base: '1f3e8', uc_full: '1f3e8', shortnames: [], category: 'travel' }, + ':house:': { uc_base: '1f3e0', uc_full: '1f3e0', shortnames: [], category: 'travel' }, + ':house_abandoned:': { uc_base: '1f3da', uc_full: '1f3da-fe0f', shortnames: [':derelict_house_building:'], category: 'travel' }, + ':house_with_garden:': { uc_base: '1f3e1', uc_full: '1f3e1', shortnames: [], category: 'travel' }, + ':hugging:': { uc_base: '1f917', uc_full: '1f917', shortnames: [':hugging_face:'], category: 'people' }, + ':hushed:': { uc_base: '1f62f', uc_full: '1f62f', shortnames: [], category: 'people' }, + ':hut:': { uc_base: '1f6d6', uc_full: '1f6d6', shortnames: [], category: 'travel' }, + ':ice_cream:': { uc_base: '1f368', uc_full: '1f368', shortnames: [], category: 'food' }, + ':ice_cube:': { uc_base: '1f9ca', uc_full: '1f9ca', shortnames: [], category: 'food' }, + ':icecream:': { uc_base: '1f366', uc_full: '1f366', shortnames: [], category: 'food' }, + ':id:': { uc_base: '1f194', uc_full: '1f194', shortnames: [], category: 'symbols' }, + ':ideograph_advantage:': { uc_base: '1f250', uc_full: '1f250', shortnames: [], category: 'symbols' }, + ':imp:': { uc_base: '1f47f', uc_full: '1f47f', shortnames: [], category: 'people' }, + ':inbox_tray:': { uc_base: '1f4e5', uc_full: '1f4e5', shortnames: [], category: 'objects' }, + ':incoming_envelope:': { uc_base: '1f4e8', uc_full: '1f4e8', shortnames: [], category: 'objects' }, + ':innocent:': { uc_base: '1f607', uc_full: '1f607', shortnames: [], category: 'people' }, + ':island:': { uc_base: '1f3dd', uc_full: '1f3dd-fe0f', shortnames: [':desert_island:'], category: 'travel' }, + ':izakaya_lantern:': { uc_base: '1f3ee', uc_full: '1f3ee', shortnames: [], category: 'objects' }, + ':jack_o_lantern:': { uc_base: '1f383', uc_full: '1f383', shortnames: [], category: 'people' }, + ':japan:': { uc_base: '1f5fe', uc_full: '1f5fe', shortnames: [], category: 'travel' }, + ':japanese_castle:': { uc_base: '1f3ef', uc_full: '1f3ef', shortnames: [], category: 'travel' }, + ':japanese_goblin:': { uc_base: '1f47a', uc_full: '1f47a', shortnames: [], category: 'people' }, + ':japanese_ogre:': { uc_base: '1f479', uc_full: '1f479', shortnames: [], category: 'people' }, + ':jeans:': { uc_base: '1f456', uc_full: '1f456', shortnames: [], category: 'people' }, + ':jigsaw:': { uc_base: '1f9e9', uc_full: '1f9e9', shortnames: [], category: 'activity' }, + ':joy:': { uc_base: '1f602', uc_full: '1f602', shortnames: [], category: 'people' }, + ':joy_cat:': { uc_base: '1f639', uc_full: '1f639', shortnames: [], category: 'people' }, + ':joystick:': { uc_base: '1f579', uc_full: '1f579-fe0f', shortnames: [], category: 'objects' }, + ':kaaba:': { uc_base: '1f54b', uc_full: '1f54b', shortnames: [], category: 'travel' }, + ':kangaroo:': { uc_base: '1f998', uc_full: '1f998', shortnames: [], category: 'nature' }, + ':key2:': { uc_base: '1f5dd', uc_full: '1f5dd-fe0f', shortnames: [':old_key:'], category: 'objects' }, + ':key:': { uc_base: '1f511', uc_full: '1f511', shortnames: [], category: 'objects' }, + ':keycap_ten:': { uc_base: '1f51f', uc_full: '1f51f', shortnames: [], category: 'symbols' }, + ':kimono:': { uc_base: '1f458', uc_full: '1f458', shortnames: [], category: 'people' }, + ':kiss:': { uc_base: '1f48b', uc_full: '1f48b', shortnames: [], category: 'people' }, + ':kissing:': { uc_base: '1f617', uc_full: '1f617', shortnames: [], category: 'people' }, + ':kissing_cat:': { uc_base: '1f63d', uc_full: '1f63d', shortnames: [], category: 'people' }, + ':kissing_closed_eyes:': { uc_base: '1f61a', uc_full: '1f61a', shortnames: [], category: 'people' }, + ':kissing_heart:': { uc_base: '1f618', uc_full: '1f618', shortnames: [], category: 'people' }, + ':kissing_smiling_eyes:': { uc_base: '1f619', uc_full: '1f619', shortnames: [], category: 'people' }, + ':kite:': { uc_base: '1fa81', uc_full: '1fa81', shortnames: [], category: 'activity' }, + ':kiwi:': { uc_base: '1f95d', uc_full: '1f95d', shortnames: [':kiwifruit:'], category: 'food' }, + ':knife:': { uc_base: '1f52a', uc_full: '1f52a', shortnames: [], category: 'objects' }, + ':knot:': { uc_base: '1faa2', uc_full: '1faa2', shortnames: [], category: 'objects' }, + ':koala:': { uc_base: '1f428', uc_full: '1f428', shortnames: [], category: 'nature' }, + ':koko:': { uc_base: '1f201', uc_full: '1f201', shortnames: [], category: 'symbols' }, + ':lab_coat:': { uc_base: '1f97c', uc_full: '1f97c', shortnames: [], category: 'people' }, + ':label:': { uc_base: '1f3f7', uc_full: '1f3f7-fe0f', shortnames: [], category: 'objects' }, + ':lacrosse:': { uc_base: '1f94d', uc_full: '1f94d', shortnames: [], category: 'activity' }, + ':ladder:': { uc_base: '1fa9c', uc_full: '1fa9c', shortnames: [], category: 'objects' }, + ':lady_beetle:': { uc_base: '1f41e', uc_full: '1f41e', shortnames: [], category: 'nature' }, + ':large_blue_diamond:': { uc_base: '1f537', uc_full: '1f537', shortnames: [], category: 'symbols' }, + ':large_orange_diamond:': { uc_base: '1f536', uc_full: '1f536', shortnames: [], category: 'symbols' }, + ':last_quarter_moon:': { uc_base: '1f317', uc_full: '1f317', shortnames: [], category: 'nature' }, + ':last_quarter_moon_with_face:': { uc_base: '1f31c', uc_full: '1f31c', shortnames: [], category: 'nature' }, + ':laughing:': { uc_base: '1f606', uc_full: '1f606', shortnames: [':satisfied:'], category: 'people' }, + ':leafy_green:': { uc_base: '1f96c', uc_full: '1f96c', shortnames: [], category: 'food' }, + ':leaves:': { uc_base: '1f343', uc_full: '1f343', shortnames: [], category: 'nature' }, + ':ledger:': { uc_base: '1f4d2', uc_full: '1f4d2', shortnames: [], category: 'objects' }, + ':left_facing_fist:': { uc_base: '1f91b', uc_full: '1f91b', shortnames: [':left_fist:'], category: 'people' }, + ':left_luggage:': { uc_base: '1f6c5', uc_full: '1f6c5', shortnames: [], category: 'symbols' }, + ':leg:': { uc_base: '1f9b5', uc_full: '1f9b5', shortnames: [], category: 'people' }, + ':lemon:': { uc_base: '1f34b', uc_full: '1f34b', shortnames: [], category: 'food' }, + ':leopard:': { uc_base: '1f406', uc_full: '1f406', shortnames: [], category: 'nature' }, + ':level_slider:': { uc_base: '1f39a', uc_full: '1f39a-fe0f', shortnames: [], category: 'objects' }, + ':levitate:': { uc_base: '1f574', uc_full: '1f574-fe0f', shortnames: [':man_in_business_suit_levitating:'], category: 'people' }, + ':light_rail:': { uc_base: '1f688', uc_full: '1f688', shortnames: [], category: 'travel' }, + ':link:': { uc_base: '1f517', uc_full: '1f517', shortnames: [], category: 'objects' }, + ':lion_face:': { uc_base: '1f981', uc_full: '1f981', shortnames: [':lion:'], category: 'nature' }, + ':lips:': { uc_base: '1f444', uc_full: '1f444', shortnames: [], category: 'people' }, + ':lipstick:': { uc_base: '1f484', uc_full: '1f484', shortnames: [], category: 'people' }, + ':lizard:': { uc_base: '1f98e', uc_full: '1f98e', shortnames: [], category: 'nature' }, + ':llama:': { uc_base: '1f999', uc_full: '1f999', shortnames: [], category: 'nature' }, + ':lobster:': { uc_base: '1f99e', uc_full: '1f99e', shortnames: [], category: 'nature' }, + ':lock:': { uc_base: '1f512', uc_full: '1f512', shortnames: [], category: 'objects' }, + ':lock_with_ink_pen:': { uc_base: '1f50f', uc_full: '1f50f', shortnames: [], category: 'objects' }, + ':lollipop:': { uc_base: '1f36d', uc_full: '1f36d', shortnames: [], category: 'food' }, + ':long_drum:': { uc_base: '1fa98', uc_full: '1fa98', shortnames: [], category: 'activity' }, + ':loud_sound:': { uc_base: '1f50a', uc_full: '1f50a', shortnames: [], category: 'symbols' }, + ':loudspeaker:': { uc_base: '1f4e2', uc_full: '1f4e2', shortnames: [], category: 'symbols' }, + ':love_hotel:': { uc_base: '1f3e9', uc_full: '1f3e9', shortnames: [], category: 'travel' }, + ':love_letter:': { uc_base: '1f48c', uc_full: '1f48c', shortnames: [], category: 'objects' }, + ':love_you_gesture:': { uc_base: '1f91f', uc_full: '1f91f', shortnames: [], category: 'people' }, + ':low_brightness:': { uc_base: '1f505', uc_full: '1f505', shortnames: [], category: 'symbols' }, + ':luggage:': { uc_base: '1f9f3', uc_full: '1f9f3', shortnames: [], category: 'people' }, + ':lungs:': { uc_base: '1fac1', uc_full: '1fac1', shortnames: [], category: 'people' }, + ':lying_face:': { uc_base: '1f925', uc_full: '1f925', shortnames: [':liar:'], category: 'people' }, + ':mag:': { uc_base: '1f50d', uc_full: '1f50d', shortnames: [], category: 'objects' }, + ':mag_right:': { uc_base: '1f50e', uc_full: '1f50e', shortnames: [], category: 'objects' }, + ':mage:': { uc_base: '1f9d9', uc_full: '1f9d9', shortnames: [], category: 'people' }, + ':magic_wand:': { uc_base: '1fa84', uc_full: '1fa84', shortnames: [], category: 'objects' }, + ':magnet:': { uc_base: '1f9f2', uc_full: '1f9f2', shortnames: [], category: 'objects' }, + ':mahjong:': { uc_base: '1f004', uc_full: '1f004', shortnames: [], category: 'symbols' }, + ':mailbox:': { uc_base: '1f4eb', uc_full: '1f4eb', shortnames: [], category: 'objects' }, + ':mailbox_closed:': { uc_base: '1f4ea', uc_full: '1f4ea', shortnames: [], category: 'objects' }, + ':mailbox_with_mail:': { uc_base: '1f4ec', uc_full: '1f4ec', shortnames: [], category: 'objects' }, + ':mailbox_with_no_mail:': { uc_base: '1f4ed', uc_full: '1f4ed', shortnames: [], category: 'objects' }, + ':mammoth:': { uc_base: '1f9a3', uc_full: '1f9a3', shortnames: [], category: 'nature' }, + ':man:': { uc_base: '1f468', uc_full: '1f468', shortnames: [], category: 'people' }, + ':man_dancing:': { uc_base: '1f57a', uc_full: '1f57a', shortnames: [':male_dancer:'], category: 'people' }, + ':man_with_chinese_cap:': { uc_base: '1f472', uc_full: '1f472', shortnames: [':man_with_gua_pi_mao:'], category: 'people' }, + ':mango:': { uc_base: '1f96d', uc_full: '1f96d', shortnames: [], category: 'food' }, + ':mans_shoe:': { uc_base: '1f45e', uc_full: '1f45e', shortnames: [], category: 'people' }, + ':manual_wheelchair:': { uc_base: '1f9bd', uc_full: '1f9bd', shortnames: [], category: 'travel' }, + ':map:': { uc_base: '1f5fa', uc_full: '1f5fa-fe0f', shortnames: [':world_map:'], category: 'travel' }, + ':maple_leaf:': { uc_base: '1f341', uc_full: '1f341', shortnames: [], category: 'nature' }, + ':martial_arts_uniform:': { uc_base: '1f94b', uc_full: '1f94b', shortnames: [':karate_uniform:'], category: 'activity' }, + ':mask:': { uc_base: '1f637', uc_full: '1f637', shortnames: [], category: 'people' }, + ':mate:': { uc_base: '1f9c9', uc_full: '1f9c9', shortnames: [], category: 'food' }, + ':meat_on_bone:': { uc_base: '1f356', uc_full: '1f356', shortnames: [], category: 'food' }, + ':mechanical_arm:': { uc_base: '1f9be', uc_full: '1f9be', shortnames: [], category: 'people' }, + ':mechanical_leg:': { uc_base: '1f9bf', uc_full: '1f9bf', shortnames: [], category: 'people' }, + ':medal:': { uc_base: '1f3c5', uc_full: '1f3c5', shortnames: [':sports_medal:'], category: 'activity' }, + ':mega:': { uc_base: '1f4e3', uc_full: '1f4e3', shortnames: [], category: 'symbols' }, + ':melon:': { uc_base: '1f348', uc_full: '1f348', shortnames: [], category: 'food' }, + ':menorah:': { uc_base: '1f54e', uc_full: '1f54e', shortnames: [], category: 'symbols' }, + ':mens:': { uc_base: '1f6b9', uc_full: '1f6b9', shortnames: [], category: 'symbols' }, + ':merperson:': { uc_base: '1f9dc', uc_full: '1f9dc', shortnames: [], category: 'people' }, + ':metal:': { uc_base: '1f918', uc_full: '1f918', shortnames: [':sign_of_the_horns:'], category: 'people' }, + ':metro:': { uc_base: '1f687', uc_full: '1f687', shortnames: [], category: 'travel' }, + ':microbe:': { uc_base: '1f9a0', uc_full: '1f9a0', shortnames: [], category: 'objects' }, + ':microphone2:': { uc_base: '1f399', uc_full: '1f399-fe0f', shortnames: [':studio_microphone:'], category: 'objects' }, + ':microphone:': { uc_base: '1f3a4', uc_full: '1f3a4', shortnames: [], category: 'activity' }, + ':microscope:': { uc_base: '1f52c', uc_full: '1f52c', shortnames: [], category: 'objects' }, + ':middle_finger:': { + uc_base: '1f595', + uc_full: '1f595', + shortnames: [':reversed_hand_with_middle_finger_extended:'], + category: 'people', + }, + ':military_helmet:': { uc_base: '1fa96', uc_full: '1fa96', shortnames: [], category: 'people' }, + ':military_medal:': { uc_base: '1f396', uc_full: '1f396-fe0f', shortnames: [], category: 'activity' }, + ':milk:': { uc_base: '1f95b', uc_full: '1f95b', shortnames: [':glass_of_milk:'], category: 'food' }, + ':milky_way:': { uc_base: '1f30c', uc_full: '1f30c', shortnames: [], category: 'travel' }, + ':minibus:': { uc_base: '1f690', uc_full: '1f690', shortnames: [], category: 'travel' }, + ':minidisc:': { uc_base: '1f4bd', uc_full: '1f4bd', shortnames: [], category: 'objects' }, + ':mirror:': { uc_base: '1fa9e', uc_full: '1fa9e', shortnames: [], category: 'objects' }, + ':mobile_phone:': { uc_base: '1f4f1', uc_full: '1f4f1', shortnames: [], category: 'objects' }, + ':mobile_phone_off:': { uc_base: '1f4f4', uc_full: '1f4f4', shortnames: [], category: 'symbols' }, + ':money_mouth:': { uc_base: '1f911', uc_full: '1f911', shortnames: [':money_mouth_face:'], category: 'people' }, + ':money_with_wings:': { uc_base: '1f4b8', uc_full: '1f4b8', shortnames: [], category: 'objects' }, + ':moneybag:': { uc_base: '1f4b0', uc_full: '1f4b0', shortnames: [], category: 'objects' }, + ':monkey:': { uc_base: '1f412', uc_full: '1f412', shortnames: [], category: 'nature' }, + ':monkey_face:': { uc_base: '1f435', uc_full: '1f435', shortnames: [], category: 'nature' }, + ':monorail:': { uc_base: '1f69d', uc_full: '1f69d', shortnames: [], category: 'travel' }, + ':moon_cake:': { uc_base: '1f96e', uc_full: '1f96e', shortnames: [], category: 'food' }, + ':mortar_board:': { uc_base: '1f393', uc_full: '1f393', shortnames: [], category: 'people' }, + ':mosque:': { uc_base: '1f54c', uc_full: '1f54c', shortnames: [], category: 'travel' }, + ':mosquito:': { uc_base: '1f99f', uc_full: '1f99f', shortnames: [], category: 'nature' }, + ':motor_scooter:': { uc_base: '1f6f5', uc_full: '1f6f5', shortnames: [':motorbike:'], category: 'travel' }, + ':motorboat:': { uc_base: '1f6e5', uc_full: '1f6e5-fe0f', shortnames: [], category: 'travel' }, + ':motorcycle:': { uc_base: '1f3cd', uc_full: '1f3cd-fe0f', shortnames: [':racing_motorcycle:'], category: 'travel' }, + ':motorized_wheelchair:': { uc_base: '1f9bc', uc_full: '1f9bc', shortnames: [], category: 'travel' }, + ':motorway:': { uc_base: '1f6e3', uc_full: '1f6e3-fe0f', shortnames: [], category: 'travel' }, + ':mount_fuji:': { uc_base: '1f5fb', uc_full: '1f5fb', shortnames: [], category: 'travel' }, + ':mountain_cableway:': { uc_base: '1f6a0', uc_full: '1f6a0', shortnames: [], category: 'travel' }, + ':mountain_railway:': { uc_base: '1f69e', uc_full: '1f69e', shortnames: [], category: 'travel' }, + ':mountain_snow:': { uc_base: '1f3d4', uc_full: '1f3d4-fe0f', shortnames: [':snow_capped_mountain:'], category: 'travel' }, + ':mouse2:': { uc_base: '1f401', uc_full: '1f401', shortnames: [], category: 'nature' }, + ':mouse:': { uc_base: '1f42d', uc_full: '1f42d', shortnames: [], category: 'nature' }, + ':mouse_three_button:': { uc_base: '1f5b1', uc_full: '1f5b1-fe0f', shortnames: [':three_button_mouse:'], category: 'objects' }, + ':mouse_trap:': { uc_base: '1faa4', uc_full: '1faa4', shortnames: [], category: 'objects' }, + ':movie_camera:': { uc_base: '1f3a5', uc_full: '1f3a5', shortnames: [], category: 'objects' }, + ':moyai:': { uc_base: '1f5ff', uc_full: '1f5ff', shortnames: [], category: 'travel' }, + ':mrs_claus:': { uc_base: '1f936', uc_full: '1f936', shortnames: [':mother_christmas:'], category: 'people' }, + ':muscle:': { uc_base: '1f4aa', uc_full: '1f4aa', shortnames: [], category: 'people' }, + ':mushroom:': { uc_base: '1f344', uc_full: '1f344', shortnames: [], category: 'nature' }, + ':musical_keyboard:': { uc_base: '1f3b9', uc_full: '1f3b9', shortnames: [], category: 'activity' }, + ':musical_note:': { uc_base: '1f3b5', uc_full: '1f3b5', shortnames: [], category: 'symbols' }, + ':musical_score:': { uc_base: '1f3bc', uc_full: '1f3bc', shortnames: [], category: 'activity' }, + ':mute:': { uc_base: '1f507', uc_full: '1f507', shortnames: [], category: 'symbols' }, + ':nail_care:': { uc_base: '1f485', uc_full: '1f485', shortnames: [], category: 'people' }, + ':name_badge:': { uc_base: '1f4db', uc_full: '1f4db', shortnames: [], category: 'symbols' }, + ':nauseated_face:': { uc_base: '1f922', uc_full: '1f922', shortnames: [':sick:'], category: 'people' }, + ':nazar_amulet:': { uc_base: '1f9ff', uc_full: '1f9ff', shortnames: [], category: 'objects' }, + ':necktie:': { uc_base: '1f454', uc_full: '1f454', shortnames: [], category: 'people' }, + ':nerd:': { uc_base: '1f913', uc_full: '1f913', shortnames: [':nerd_face:'], category: 'people' }, + ':nesting_dolls:': { uc_base: '1fa86', uc_full: '1fa86', shortnames: [], category: 'objects' }, + ':neutral_face:': { uc_base: '1f610', uc_full: '1f610', shortnames: [], category: 'people' }, + ':new:': { uc_base: '1f195', uc_full: '1f195', shortnames: [], category: 'symbols' }, + ':new_moon:': { uc_base: '1f311', uc_full: '1f311', shortnames: [], category: 'nature' }, + ':new_moon_with_face:': { uc_base: '1f31a', uc_full: '1f31a', shortnames: [], category: 'nature' }, + ':newspaper2:': { uc_base: '1f5de', uc_full: '1f5de-fe0f', shortnames: [':rolled_up_newspaper:'], category: 'objects' }, + ':newspaper:': { uc_base: '1f4f0', uc_full: '1f4f0', shortnames: [], category: 'objects' }, + ':ng:': { uc_base: '1f196', uc_full: '1f196', shortnames: [], category: 'symbols' }, + ':night_with_stars:': { uc_base: '1f303', uc_full: '1f303', shortnames: [], category: 'travel' }, + ':ninja:': { uc_base: '1f977', uc_full: '1f977', shortnames: [], category: 'people' }, + ':no_bell:': { uc_base: '1f515', uc_full: '1f515', shortnames: [], category: 'symbols' }, + ':no_bicycles:': { uc_base: '1f6b3', uc_full: '1f6b3', shortnames: [], category: 'symbols' }, + ':no_entry_sign:': { uc_base: '1f6ab', uc_full: '1f6ab', shortnames: [], category: 'symbols' }, + ':no_mobile_phones:': { uc_base: '1f4f5', uc_full: '1f4f5', shortnames: [], category: 'symbols' }, + ':no_mouth:': { uc_base: '1f636', uc_full: '1f636', shortnames: [], category: 'people' }, + ':no_pedestrians:': { uc_base: '1f6b7', uc_full: '1f6b7', shortnames: [], category: 'symbols' }, + ':no_smoking:': { uc_base: '1f6ad', uc_full: '1f6ad', shortnames: [], category: 'symbols' }, + ':non-potable_water:': { uc_base: '1f6b1', uc_full: '1f6b1', shortnames: [], category: 'symbols' }, + ':nose:': { uc_base: '1f443', uc_full: '1f443', shortnames: [], category: 'people' }, + ':notebook:': { uc_base: '1f4d3', uc_full: '1f4d3', shortnames: [], category: 'objects' }, + ':notebook_with_decorative_cover:': { uc_base: '1f4d4', uc_full: '1f4d4', shortnames: [], category: 'objects' }, + ':notepad_spiral:': { uc_base: '1f5d2', uc_full: '1f5d2-fe0f', shortnames: [':spiral_note_pad:'], category: 'objects' }, + ':notes:': { uc_base: '1f3b6', uc_full: '1f3b6', shortnames: [], category: 'symbols' }, + ':nut_and_bolt:': { uc_base: '1f529', uc_full: '1f529', shortnames: [], category: 'objects' }, + ':o2:': { uc_base: '1f17e', uc_full: '1f17e-fe0f', shortnames: [], category: 'symbols' }, + ':ocean:': { uc_base: '1f30a', uc_full: '1f30a', shortnames: [], category: 'nature' }, + ':octagonal_sign:': { uc_base: '1f6d1', uc_full: '1f6d1', shortnames: [':stop_sign:'], category: 'symbols' }, + ':octopus:': { uc_base: '1f419', uc_full: '1f419', shortnames: [], category: 'nature' }, + ':oden:': { uc_base: '1f362', uc_full: '1f362', shortnames: [], category: 'food' }, + ':office:': { uc_base: '1f3e2', uc_full: '1f3e2', shortnames: [], category: 'travel' }, + ':oil:': { uc_base: '1f6e2', uc_full: '1f6e2-fe0f', shortnames: [':oil_drum:'], category: 'objects' }, + ':ok:': { uc_base: '1f197', uc_full: '1f197', shortnames: [], category: 'symbols' }, + ':ok_hand:': { uc_base: '1f44c', uc_full: '1f44c', shortnames: [], category: 'people' }, + ':older_adult:': { uc_base: '1f9d3', uc_full: '1f9d3', shortnames: [], category: 'people' }, + ':older_man:': { uc_base: '1f474', uc_full: '1f474', shortnames: [], category: 'people' }, + ':older_woman:': { uc_base: '1f475', uc_full: '1f475', shortnames: [':grandma:'], category: 'people' }, + ':olive:': { uc_base: '1fad2', uc_full: '1fad2', shortnames: [], category: 'food' }, + ':om_symbol:': { uc_base: '1f549', uc_full: '1f549-fe0f', shortnames: [], category: 'symbols' }, + ':on:': { uc_base: '1f51b', uc_full: '1f51b', shortnames: [], category: 'symbols' }, + ':oncoming_automobile:': { uc_base: '1f698', uc_full: '1f698', shortnames: [], category: 'travel' }, + ':oncoming_bus:': { uc_base: '1f68d', uc_full: '1f68d', shortnames: [], category: 'travel' }, + ':oncoming_police_car:': { uc_base: '1f694', uc_full: '1f694', shortnames: [], category: 'travel' }, + ':oncoming_taxi:': { uc_base: '1f696', uc_full: '1f696', shortnames: [], category: 'travel' }, + ':one_piece_swimsuit:': { uc_base: '1fa71', uc_full: '1fa71', shortnames: [], category: 'people' }, + ':onion:': { uc_base: '1f9c5', uc_full: '1f9c5', shortnames: [], category: 'food' }, + ':open_file_folder:': { uc_base: '1f4c2', uc_full: '1f4c2', shortnames: [], category: 'objects' }, + ':open_hands:': { uc_base: '1f450', uc_full: '1f450', shortnames: [], category: 'people' }, + ':open_mouth:': { uc_base: '1f62e', uc_full: '1f62e', shortnames: [], category: 'people' }, + ':orange_book:': { uc_base: '1f4d9', uc_full: '1f4d9', shortnames: [], category: 'objects' }, + ':orange_circle:': { uc_base: '1f7e0', uc_full: '1f7e0', shortnames: [], category: 'symbols' }, + ':orange_heart:': { uc_base: '1f9e1', uc_full: '1f9e1', shortnames: [], category: 'symbols' }, + ':orange_square:': { uc_base: '1f7e7', uc_full: '1f7e7', shortnames: [], category: 'symbols' }, + ':orangutan:': { uc_base: '1f9a7', uc_full: '1f9a7', shortnames: [], category: 'nature' }, + ':otter:': { uc_base: '1f9a6', uc_full: '1f9a6', shortnames: [], category: 'nature' }, + ':outbox_tray:': { uc_base: '1f4e4', uc_full: '1f4e4', shortnames: [], category: 'objects' }, + ':owl:': { uc_base: '1f989', uc_full: '1f989', shortnames: [], category: 'nature' }, + ':ox:': { uc_base: '1f402', uc_full: '1f402', shortnames: [], category: 'nature' }, + ':oyster:': { uc_base: '1f9aa', uc_full: '1f9aa', shortnames: [], category: 'food' }, + ':package:': { uc_base: '1f4e6', uc_full: '1f4e6', shortnames: [], category: 'objects' }, + ':page_facing_up:': { uc_base: '1f4c4', uc_full: '1f4c4', shortnames: [], category: 'objects' }, + ':page_with_curl:': { uc_base: '1f4c3', uc_full: '1f4c3', shortnames: [], category: 'objects' }, + ':pager:': { uc_base: '1f4df', uc_full: '1f4df', shortnames: [], category: 'objects' }, + ':paintbrush:': { uc_base: '1f58c', uc_full: '1f58c-fe0f', shortnames: [':lower_left_paintbrush:'], category: 'objects' }, + ':palm_tree:': { uc_base: '1f334', uc_full: '1f334', shortnames: [], category: 'nature' }, + ':palms_up_together:': { uc_base: '1f932', uc_full: '1f932', shortnames: [], category: 'people' }, + ':pancakes:': { uc_base: '1f95e', uc_full: '1f95e', shortnames: [], category: 'food' }, + ':panda_face:': { uc_base: '1f43c', uc_full: '1f43c', shortnames: [], category: 'nature' }, + ':paperclip:': { uc_base: '1f4ce', uc_full: '1f4ce', shortnames: [], category: 'objects' }, + ':paperclips:': { uc_base: '1f587', uc_full: '1f587-fe0f', shortnames: [':linked_paperclips:'], category: 'objects' }, + ':parachute:': { uc_base: '1fa82', uc_full: '1fa82', shortnames: [], category: 'activity' }, + ':park:': { uc_base: '1f3de', uc_full: '1f3de-fe0f', shortnames: [':national_park:'], category: 'travel' }, + ':parking:': { uc_base: '1f17f', uc_full: '1f17f-fe0f', shortnames: [], category: 'symbols' }, + ':parrot:': { uc_base: '1f99c', uc_full: '1f99c', shortnames: [], category: 'nature' }, + ':partying_face:': { uc_base: '1f973', uc_full: '1f973', shortnames: [], category: 'people' }, + ':passport_control:': { uc_base: '1f6c2', uc_full: '1f6c2', shortnames: [], category: 'symbols' }, + ':peach:': { uc_base: '1f351', uc_full: '1f351', shortnames: [], category: 'food' }, + ':peacock:': { uc_base: '1f99a', uc_full: '1f99a', shortnames: [], category: 'nature' }, + ':peanuts:': { uc_base: '1f95c', uc_full: '1f95c', shortnames: [':shelled_peanut:'], category: 'food' }, + ':pear:': { uc_base: '1f350', uc_full: '1f350', shortnames: [], category: 'food' }, + ':pen_ballpoint:': { uc_base: '1f58a', uc_full: '1f58a-fe0f', shortnames: [':lower_left_ballpoint_pen:'], category: 'objects' }, + ':pen_fountain:': { uc_base: '1f58b', uc_full: '1f58b-fe0f', shortnames: [':lower_left_fountain_pen:'], category: 'objects' }, + ':pencil:': { uc_base: '1f4dd', uc_full: '1f4dd', shortnames: [':memo:'], category: 'objects' }, + ':penguin:': { uc_base: '1f427', uc_full: '1f427', shortnames: [], category: 'nature' }, + ':pensive:': { uc_base: '1f614', uc_full: '1f614', shortnames: [], category: 'people' }, + ':people_hugging:': { uc_base: '1fac2', uc_full: '1fac2', shortnames: [], category: 'people' }, + ':people_with_bunny_ears_partying:': { uc_base: '1f46f', uc_full: '1f46f', shortnames: [':dancers:'], category: 'people' }, + ':people_wrestling:': { uc_base: '1f93c', uc_full: '1f93c', shortnames: [':wrestlers:', ':wrestling:'], category: 'activity' }, + ':performing_arts:': { uc_base: '1f3ad', uc_full: '1f3ad', shortnames: [], category: 'activity' }, + ':persevere:': { uc_base: '1f623', uc_full: '1f623', shortnames: [], category: 'people' }, + ':person_biking:': { uc_base: '1f6b4', uc_full: '1f6b4', shortnames: [':bicyclist:'], category: 'activity' }, + ':person_bowing:': { uc_base: '1f647', uc_full: '1f647', shortnames: [':bow:'], category: 'people' }, + ':person_climbing:': { uc_base: '1f9d7', uc_full: '1f9d7', shortnames: [], category: 'activity' }, + ':person_doing_cartwheel:': { uc_base: '1f938', uc_full: '1f938', shortnames: [':cartwheel:'], category: 'activity' }, + ':person_facepalming:': { uc_base: '1f926', uc_full: '1f926', shortnames: [':face_palm:', ':facepalm:'], category: 'people' }, + ':person_fencing:': { uc_base: '1f93a', uc_full: '1f93a', shortnames: [':fencer:', ':fencing:'], category: 'activity' }, + ':person_frowning:': { uc_base: '1f64d', uc_full: '1f64d', shortnames: [], category: 'people' }, + ':person_gesturing_no:': { uc_base: '1f645', uc_full: '1f645', shortnames: [':no_good:'], category: 'people' }, + ':person_gesturing_ok:': { uc_base: '1f646', uc_full: '1f646', shortnames: [':ok_woman:'], category: 'people' }, + ':person_getting_haircut:': { uc_base: '1f487', uc_full: '1f487', shortnames: [':haircut:'], category: 'people' }, + ':person_getting_massage:': { uc_base: '1f486', uc_full: '1f486', shortnames: [':massage:'], category: 'people' }, + ':person_golfing:': { uc_base: '1f3cc', uc_full: '1f3cc', shortnames: [':golfer:'], category: 'activity' }, + ':person_in_lotus_position:': { uc_base: '1f9d8', uc_full: '1f9d8', shortnames: [], category: 'activity' }, + ':person_in_steamy_room:': { uc_base: '1f9d6', uc_full: '1f9d6', shortnames: [], category: 'people' }, + ':person_in_tuxedo:': { uc_base: '1f935', uc_full: '1f935', shortnames: [], category: 'people' }, + ':person_juggling:': { uc_base: '1f939', uc_full: '1f939', shortnames: [':juggling:', ':juggler:'], category: 'activity' }, + ':person_kneeling:': { uc_base: '1f9ce', uc_full: '1f9ce', shortnames: [], category: 'people' }, + ':person_lifting_weights:': { uc_base: '1f3cb', uc_full: '1f3cb', shortnames: [':lifter:', ':weight_lifter:'], category: 'activity' }, + ':person_mountain_biking:': { uc_base: '1f6b5', uc_full: '1f6b5', shortnames: [':mountain_bicyclist:'], category: 'activity' }, + ':person_playing_handball:': { uc_base: '1f93e', uc_full: '1f93e', shortnames: [':handball:'], category: 'activity' }, + ':person_playing_water_polo:': { uc_base: '1f93d', uc_full: '1f93d', shortnames: [':water_polo:'], category: 'activity' }, + ':person_pouting:': { uc_base: '1f64e', uc_full: '1f64e', shortnames: [':person_with_pouting_face:'], category: 'people' }, + ':person_raising_hand:': { uc_base: '1f64b', uc_full: '1f64b', shortnames: [':raising_hand:'], category: 'people' }, + ':person_rowing_boat:': { uc_base: '1f6a3', uc_full: '1f6a3', shortnames: [':rowboat:'], category: 'activity' }, + ':person_running:': { uc_base: '1f3c3', uc_full: '1f3c3', shortnames: [':runner:'], category: 'people' }, + ':person_shrugging:': { uc_base: '1f937', uc_full: '1f937', shortnames: [':shrug:'], category: 'people' }, + ':person_standing:': { uc_base: '1f9cd', uc_full: '1f9cd', shortnames: [], category: 'people' }, + ':person_surfing:': { uc_base: '1f3c4', uc_full: '1f3c4', shortnames: [':surfer:'], category: 'activity' }, + ':person_swimming:': { uc_base: '1f3ca', uc_full: '1f3ca', shortnames: [':swimmer:'], category: 'activity' }, + ':person_tipping_hand:': { uc_base: '1f481', uc_full: '1f481', shortnames: [':information_desk_person:'], category: 'people' }, + ':person_walking:': { uc_base: '1f6b6', uc_full: '1f6b6', shortnames: [':walking:'], category: 'people' }, + ':person_wearing_turban:': { uc_base: '1f473', uc_full: '1f473', shortnames: [':man_with_turban:'], category: 'people' }, + ':person_with_veil:': { uc_base: '1f470', uc_full: '1f470', shortnames: [], category: 'people' }, + ':petri_dish:': { uc_base: '1f9eb', uc_full: '1f9eb', shortnames: [], category: 'objects' }, + ':pickup_truck:': { uc_base: '1f6fb', uc_full: '1f6fb', shortnames: [], category: 'travel' }, + ':pie:': { uc_base: '1f967', uc_full: '1f967', shortnames: [], category: 'food' }, + ':pig2:': { uc_base: '1f416', uc_full: '1f416', shortnames: [], category: 'nature' }, + ':pig:': { uc_base: '1f437', uc_full: '1f437', shortnames: [], category: 'nature' }, + ':pig_nose:': { + uc_base: '1f43d', + uc_full: '1f43d', + shortnames: [], + category: 'nature', + }, + ':pill:': { uc_base: '1f48a', uc_full: '1f48a', shortnames: [], category: 'objects' }, + ':pinched_fingers:': { uc_base: '1f90c', uc_full: '1f90c', shortnames: [], category: 'people' }, + ':pinching_hand:': { uc_base: '1f90f', uc_full: '1f90f', shortnames: [], category: 'people' }, + ':pineapple:': { uc_base: '1f34d', uc_full: '1f34d', shortnames: [], category: 'food' }, + ':ping_pong:': { uc_base: '1f3d3', uc_full: '1f3d3', shortnames: [':table_tennis:'], category: 'activity' }, + ':pizza:': { uc_base: '1f355', uc_full: '1f355', shortnames: [], category: 'food' }, + ':pi\xf1ata:': { uc_base: '1fa85', uc_full: '1fa85', shortnames: [], category: 'objects' }, + ':placard:': { uc_base: '1faa7', uc_full: '1faa7', shortnames: [], category: 'objects' }, + ':place_of_worship:': { uc_base: '1f6d0', uc_full: '1f6d0', shortnames: [':worship_symbol:'], category: 'symbols' }, + ':pleading_face:': { uc_base: '1f97a', uc_full: '1f97a', shortnames: [], category: 'people' }, + ':plunger:': { uc_base: '1faa0', uc_full: '1faa0', shortnames: [], category: 'objects' }, + ':point_down:': { uc_base: '1f447', uc_full: '1f447', shortnames: [], category: 'people' }, + ':point_left:': { uc_base: '1f448', uc_full: '1f448', shortnames: [], category: 'people' }, + ':point_right:': { uc_base: '1f449', uc_full: '1f449', shortnames: [], category: 'people' }, + ':point_up_2:': { uc_base: '1f446', uc_full: '1f446', shortnames: [], category: 'people' }, + ':police_car:': { uc_base: '1f693', uc_full: '1f693', shortnames: [], category: 'travel' }, + ':police_officer:': { uc_base: '1f46e', uc_full: '1f46e', shortnames: [':cop:'], category: 'people' }, + ':poodle:': { uc_base: '1f429', uc_full: '1f429', shortnames: [], category: 'nature' }, + ':poop:': { uc_base: '1f4a9', uc_full: '1f4a9', shortnames: [':shit:', ':hankey:', ':poo:'], category: 'people' }, + ':popcorn:': { uc_base: '1f37f', uc_full: '1f37f', shortnames: [], category: 'food' }, + ':post_office:': { uc_base: '1f3e3', uc_full: '1f3e3', shortnames: [], category: 'travel' }, + ':postal_horn:': { uc_base: '1f4ef', uc_full: '1f4ef', shortnames: [], category: 'objects' }, + ':postbox:': { uc_base: '1f4ee', uc_full: '1f4ee', shortnames: [], category: 'objects' }, + ':potable_water:': { uc_base: '1f6b0', uc_full: '1f6b0', shortnames: [], category: 'objects' }, + ':potato:': { uc_base: '1f954', uc_full: '1f954', shortnames: [], category: 'food' }, + ':potted_plant:': { uc_base: '1fab4', uc_full: '1fab4', shortnames: [], category: 'nature' }, + ':pouch:': { uc_base: '1f45d', uc_full: '1f45d', shortnames: [], category: 'people' }, + ':poultry_leg:': { uc_base: '1f357', uc_full: '1f357', shortnames: [], category: 'food' }, + ':pound:': { uc_base: '1f4b7', uc_full: '1f4b7', shortnames: [], category: 'objects' }, + ':pouting_cat:': { uc_base: '1f63e', uc_full: '1f63e', shortnames: [], category: 'people' }, + ':pray:': { uc_base: '1f64f', uc_full: '1f64f', shortnames: [], category: 'people' }, + ':prayer_beads:': { uc_base: '1f4ff', uc_full: '1f4ff', shortnames: [], category: 'objects' }, + ':pregnant_woman:': { uc_base: '1f930', uc_full: '1f930', shortnames: [':expecting_woman:'], category: 'people' }, + ':pretzel:': { uc_base: '1f968', uc_full: '1f968', shortnames: [], category: 'food' }, + ':prince:': { uc_base: '1f934', uc_full: '1f934', shortnames: [], category: 'people' }, + ':princess:': { uc_base: '1f478', uc_full: '1f478', shortnames: [], category: 'people' }, + ':printer:': { uc_base: '1f5a8', uc_full: '1f5a8-fe0f', shortnames: [], category: 'objects' }, + ':probing_cane:': { uc_base: '1f9af', uc_full: '1f9af', shortnames: [], category: 'travel' }, + ':projector:': { uc_base: '1f4fd', uc_full: '1f4fd-fe0f', shortnames: [':film_projector:'], category: 'objects' }, + ':punch:': { uc_base: '1f44a', uc_full: '1f44a', shortnames: [], category: 'people' }, + ':purple_circle:': { uc_base: '1f7e3', uc_full: '1f7e3', shortnames: [], category: 'symbols' }, + ':purple_heart:': { uc_base: '1f49c', uc_full: '1f49c', shortnames: [], category: 'symbols' }, + ':purple_square:': { uc_base: '1f7ea', uc_full: '1f7ea', shortnames: [], category: 'symbols' }, + ':purse:': { uc_base: '1f45b', uc_full: '1f45b', shortnames: [], category: 'people' }, + ':pushpin:': { uc_base: '1f4cc', uc_full: '1f4cc', shortnames: [], category: 'objects' }, + ':put_litter_in_its_place:': { uc_base: '1f6ae', uc_full: '1f6ae', shortnames: [], category: 'symbols' }, + ':rabbit2:': { uc_base: '1f407', uc_full: '1f407', shortnames: [], category: 'nature' }, + ':rabbit:': { uc_base: '1f430', uc_full: '1f430', shortnames: [], category: 'nature' }, + ':raccoon:': { uc_base: '1f99d', uc_full: '1f99d', shortnames: [], category: 'nature' }, + ':race_car:': { uc_base: '1f3ce', uc_full: '1f3ce-fe0f', shortnames: [':racing_car:'], category: 'travel' }, + ':racehorse:': { uc_base: '1f40e', uc_full: '1f40e', shortnames: [], category: 'nature' }, + ':radio:': { uc_base: '1f4fb', uc_full: '1f4fb', shortnames: [], category: 'objects' }, + ':radio_button:': { uc_base: '1f518', uc_full: '1f518', shortnames: [], category: 'symbols' }, + ':rage:': { uc_base: '1f621', uc_full: '1f621', shortnames: [], category: 'people' }, + ':railway_car:': { uc_base: '1f683', uc_full: '1f683', shortnames: [], category: 'travel' }, + ':railway_track:': { uc_base: '1f6e4', uc_full: '1f6e4-fe0f', shortnames: [':railroad_track:'], category: 'travel' }, + ':rainbow:': { uc_base: '1f308', uc_full: '1f308', shortnames: [], category: 'nature' }, + ':raised_back_of_hand:': { uc_base: '1f91a', uc_full: '1f91a', shortnames: [':back_of_hand:'], category: 'people' }, + ':raised_hands:': { uc_base: '1f64c', uc_full: '1f64c', shortnames: [], category: 'people' }, + ':ram:': { uc_base: '1f40f', uc_full: '1f40f', shortnames: [], category: 'nature' }, + ':ramen:': { uc_base: '1f35c', uc_full: '1f35c', shortnames: [], category: 'food' }, + ':rat:': { uc_base: '1f400', uc_full: '1f400', shortnames: [], category: 'nature' }, + ':razor:': { uc_base: '1fa92', uc_full: '1fa92', shortnames: [], category: 'objects' }, + ':receipt:': { uc_base: '1f9fe', uc_full: '1f9fe', shortnames: [], category: 'objects' }, + ':red_car:': { uc_base: '1f697', uc_full: '1f697', shortnames: [], category: 'travel' }, + ':red_circle:': { uc_base: '1f534', uc_full: '1f534', shortnames: [], category: 'symbols' }, + ':red_envelope:': { uc_base: '1f9e7', uc_full: '1f9e7', shortnames: [], category: 'objects' }, + ':red_haired:': { uc_base: '1f9b0', uc_full: '1f9b0', shortnames: [], category: 'people' }, + ':red_square:': { uc_base: '1f7e5', uc_full: '1f7e5', shortnames: [], category: 'symbols' }, + ':regional_indicator_a:': { uc_base: '1f1e6', uc_full: '1f1e6', shortnames: [], category: 'regional' }, + ':regional_indicator_b:': { uc_base: '1f1e7', uc_full: '1f1e7', shortnames: [], category: 'regional' }, + ':regional_indicator_c:': { uc_base: '1f1e8', uc_full: '1f1e8', shortnames: [], category: 'regional' }, + ':regional_indicator_d:': { uc_base: '1f1e9', uc_full: '1f1e9', shortnames: [], category: 'regional' }, + ':regional_indicator_e:': { uc_base: '1f1ea', uc_full: '1f1ea', shortnames: [], category: 'regional' }, + ':regional_indicator_f:': { uc_base: '1f1eb', uc_full: '1f1eb', shortnames: [], category: 'regional' }, + ':regional_indicator_g:': { uc_base: '1f1ec', uc_full: '1f1ec', shortnames: [], category: 'regional' }, + ':regional_indicator_h:': { uc_base: '1f1ed', uc_full: '1f1ed', shortnames: [], category: 'regional' }, + ':regional_indicator_i:': { uc_base: '1f1ee', uc_full: '1f1ee', shortnames: [], category: 'regional' }, + ':regional_indicator_j:': { uc_base: '1f1ef', uc_full: '1f1ef', shortnames: [], category: 'regional' }, + ':regional_indicator_k:': { uc_base: '1f1f0', uc_full: '1f1f0', shortnames: [], category: 'regional' }, + ':regional_indicator_l:': { uc_base: '1f1f1', uc_full: '1f1f1', shortnames: [], category: 'regional' }, + ':regional_indicator_m:': { uc_base: '1f1f2', uc_full: '1f1f2', shortnames: [], category: 'regional' }, + ':regional_indicator_n:': { uc_base: '1f1f3', uc_full: '1f1f3', shortnames: [], category: 'regional' }, + ':regional_indicator_o:': { uc_base: '1f1f4', uc_full: '1f1f4', shortnames: [], category: 'regional' }, + ':regional_indicator_p:': { uc_base: '1f1f5', uc_full: '1f1f5', shortnames: [], category: 'regional' }, + ':regional_indicator_q:': { uc_base: '1f1f6', uc_full: '1f1f6', shortnames: [], category: 'regional' }, + ':regional_indicator_r:': { uc_base: '1f1f7', uc_full: '1f1f7', shortnames: [], category: 'regional' }, + ':regional_indicator_s:': { uc_base: '1f1f8', uc_full: '1f1f8', shortnames: [], category: 'regional' }, + ':regional_indicator_t:': { uc_base: '1f1f9', uc_full: '1f1f9', shortnames: [], category: 'regional' }, + ':regional_indicator_u:': { uc_base: '1f1fa', uc_full: '1f1fa', shortnames: [], category: 'regional' }, + ':regional_indicator_v:': { uc_base: '1f1fb', uc_full: '1f1fb', shortnames: [], category: 'regional' }, + ':regional_indicator_w:': { uc_base: '1f1fc', uc_full: '1f1fc', shortnames: [], category: 'regional' }, + ':regional_indicator_x:': { uc_base: '1f1fd', uc_full: '1f1fd', shortnames: [], category: 'regional' }, + ':regional_indicator_y:': { uc_base: '1f1fe', uc_full: '1f1fe', shortnames: [], category: 'regional' }, + ':regional_indicator_z:': { uc_base: '1f1ff', uc_full: '1f1ff', shortnames: [], category: 'regional' }, + ':relieved:': { uc_base: '1f60c', uc_full: '1f60c', shortnames: [], category: 'people' }, + ':reminder_ribbon:': { uc_base: '1f397', uc_full: '1f397-fe0f', shortnames: [], category: 'activity' }, + ':repeat:': { uc_base: '1f501', uc_full: '1f501', shortnames: [], category: 'symbols' }, + ':repeat_one:': { uc_base: '1f502', uc_full: '1f502', shortnames: [], category: 'symbols' }, + ':restroom:': { uc_base: '1f6bb', uc_full: '1f6bb', shortnames: [], category: 'symbols' }, + ':revolving_hearts:': { uc_base: '1f49e', uc_full: '1f49e', shortnames: [], category: 'symbols' }, + ':rhino:': { uc_base: '1f98f', uc_full: '1f98f', shortnames: [':rhinoceros:'], category: 'nature' }, + ':ribbon:': { uc_base: '1f380', uc_full: '1f380', shortnames: [], category: 'objects' }, + ':rice:': { uc_base: '1f35a', uc_full: '1f35a', shortnames: [], category: 'food' }, + ':rice_ball:': { uc_base: '1f359', uc_full: '1f359', shortnames: [], category: 'food' }, + ':rice_cracker:': { uc_base: '1f358', uc_full: '1f358', shortnames: [], category: 'food' }, + ':rice_scene:': { uc_base: '1f391', uc_full: '1f391', shortnames: [], category: 'travel' }, + ':right_facing_fist:': { uc_base: '1f91c', uc_full: '1f91c', shortnames: [':right_fist:'], category: 'people' }, + ':ring:': { uc_base: '1f48d', uc_full: '1f48d', shortnames: [], category: 'people' }, + ':ringed_planet:': { uc_base: '1fa90', uc_full: '1fa90', shortnames: [], category: 'nature' }, + ':robot:': { uc_base: '1f916', uc_full: '1f916', shortnames: [':robot_face:'], category: 'people' }, + ':rock:': { uc_base: '1faa8', uc_full: '1faa8', shortnames: [], category: 'nature' }, + ':rocket:': { uc_base: '1f680', uc_full: '1f680', shortnames: [], category: 'travel' }, + ':rofl:': { uc_base: '1f923', uc_full: '1f923', shortnames: [':rolling_on_the_floor_laughing:'], category: 'people' }, + ':roll_of_paper:': { uc_base: '1f9fb', uc_full: '1f9fb', shortnames: [], category: 'objects' }, + ':roller_coaster:': { uc_base: '1f3a2', uc_full: '1f3a2', shortnames: [], category: 'travel' }, + ':roller_skate:': { uc_base: '1f6fc', uc_full: '1f6fc', shortnames: [], category: 'activity' }, + ':rolling_eyes:': { uc_base: '1f644', uc_full: '1f644', shortnames: [':face_with_rolling_eyes:'], category: 'people' }, + ':rooster:': { uc_base: '1f413', uc_full: '1f413', shortnames: [], category: 'nature' }, + ':rose:': { uc_base: '1f339', uc_full: '1f339', shortnames: [], category: 'nature' }, + ':rosette:': { uc_base: '1f3f5', uc_full: '1f3f5-fe0f', shortnames: [], category: 'activity' }, + ':rotating_light:': { uc_base: '1f6a8', uc_full: '1f6a8', shortnames: [], category: 'travel' }, + ':round_pushpin:': { uc_base: '1f4cd', uc_full: '1f4cd', shortnames: [], category: 'objects' }, + ':rugby_football:': { uc_base: '1f3c9', uc_full: '1f3c9', shortnames: [], category: 'activity' }, + ':running_shirt_with_sash:': { uc_base: '1f3bd', uc_full: '1f3bd', shortnames: [], category: 'activity' }, + ':sa:': { uc_base: '1f202', uc_full: '1f202-fe0f', shortnames: [], category: 'symbols' }, + ':safety_pin:': { uc_base: '1f9f7', uc_full: '1f9f7', shortnames: [], category: 'objects' }, + ':safety_vest:': { uc_base: '1f9ba', uc_full: '1f9ba', shortnames: [], category: 'people' }, + ':sake:': { uc_base: '1f376', uc_full: '1f376', shortnames: [], category: 'food' }, + ':salad:': { uc_base: '1f957', uc_full: '1f957', shortnames: [':green_salad:'], category: 'food' }, + ':salt:': { uc_base: '1f9c2', uc_full: '1f9c2', shortnames: [], category: 'food' }, + ':sandal:': { uc_base: '1f461', uc_full: '1f461', shortnames: [], category: 'people' }, + ':sandwich:': { uc_base: '1f96a', uc_full: '1f96a', shortnames: [], category: 'food' }, + ':santa:': { uc_base: '1f385', uc_full: '1f385', shortnames: [], category: 'people' }, + ':sari:': { uc_base: '1f97b', uc_full: '1f97b', shortnames: [], category: 'people' }, + ':satellite:': { uc_base: '1f4e1', uc_full: '1f4e1', shortnames: [], category: 'objects' }, + ':satellite_orbital:': { uc_base: '1f6f0', uc_full: '1f6f0-fe0f', shortnames: [], category: 'travel' }, + ':sauropod:': { uc_base: '1f995', uc_full: '1f995', shortnames: [], category: 'nature' }, + ':saxophone:': { uc_base: '1f3b7', uc_full: '1f3b7', shortnames: [], category: 'activity' }, + ':scarf:': { uc_base: '1f9e3', uc_full: '1f9e3', shortnames: [], category: 'people' }, + ':school:': { uc_base: '1f3eb', uc_full: '1f3eb', shortnames: [], category: 'travel' }, + ':school_satchel:': { uc_base: '1f392', uc_full: '1f392', shortnames: [], category: 'people' }, + ':scooter:': { uc_base: '1f6f4', uc_full: '1f6f4', shortnames: [], category: 'travel' }, + ':scorpion:': { uc_base: '1f982', uc_full: '1f982', shortnames: [], category: 'nature' }, + ':scream:': { uc_base: '1f631', uc_full: '1f631', shortnames: [], category: 'people' }, + ':scream_cat:': { uc_base: '1f640', uc_full: '1f640', shortnames: [], category: 'people' }, + ':screwdriver:': { uc_base: '1fa9b', uc_full: '1fa9b', shortnames: [], category: 'objects' }, + ':scroll:': { uc_base: '1f4dc', uc_full: '1f4dc', shortnames: [], category: 'objects' }, + ':seal:': { uc_base: '1f9ad', uc_full: '1f9ad', shortnames: [], category: 'nature' }, + ':seat:': { uc_base: '1f4ba', uc_full: '1f4ba', shortnames: [], category: 'travel' }, + ':second_place:': { uc_base: '1f948', uc_full: '1f948', shortnames: [':second_place_medal:'], category: 'activity' }, + ':see_no_evil:': { uc_base: '1f648', uc_full: '1f648', shortnames: [], category: 'nature' }, + ':seedling:': { uc_base: '1f331', uc_full: '1f331', shortnames: [], category: 'nature' }, + ':selfie:': { uc_base: '1f933', uc_full: '1f933', shortnames: [], category: 'people' }, + ':sewing_needle:': { uc_base: '1faa1', uc_full: '1faa1', shortnames: [], category: 'objects' }, + ':shallow_pan_of_food:': { uc_base: '1f958', uc_full: '1f958', shortnames: [':paella:'], category: 'food' }, + ':shark:': { uc_base: '1f988', uc_full: '1f988', shortnames: [], category: 'nature' }, + ':shaved_ice:': { uc_base: '1f367', uc_full: '1f367', shortnames: [], category: 'food' }, + ':sheep:': { uc_base: '1f411', uc_full: '1f411', shortnames: [], category: 'nature' }, + ':shell:': { uc_base: '1f41a', uc_full: '1f41a', shortnames: [], category: 'nature' }, + ':shield:': { uc_base: '1f6e1', uc_full: '1f6e1-fe0f', shortnames: [], category: 'objects' }, + ':ship:': { uc_base: '1f6a2', uc_full: '1f6a2', shortnames: [], category: 'travel' }, + ':shirt:': { uc_base: '1f455', uc_full: '1f455', shortnames: [], category: 'people' }, + ':shopping_bags:': { uc_base: '1f6cd', uc_full: '1f6cd-fe0f', shortnames: [], category: 'objects' }, + ':shopping_cart:': { uc_base: '1f6d2', uc_full: '1f6d2', shortnames: [':shopping_trolley:'], category: 'objects' }, + ':shorts:': { uc_base: '1fa73', uc_full: '1fa73', shortnames: [], category: 'people' }, + ':shower:': { uc_base: '1f6bf', uc_full: '1f6bf', shortnames: [], category: 'objects' }, + ':shrimp:': { uc_base: '1f990', uc_full: '1f990', shortnames: [], category: 'nature' }, + ':shushing_face:': { uc_base: '1f92b', uc_full: '1f92b', shortnames: [], category: 'people' }, + ':signal_strength:': { uc_base: '1f4f6', uc_full: '1f4f6', shortnames: [], category: 'symbols' }, + ':six_pointed_star:': { uc_base: '1f52f', uc_full: '1f52f', shortnames: [], category: 'symbols' }, + ':skateboard:': { uc_base: '1f6f9', uc_full: '1f6f9', shortnames: [], category: 'activity' }, + ':ski:': { uc_base: '1f3bf', uc_full: '1f3bf', shortnames: [], category: 'activity' }, + ':skull:': { uc_base: '1f480', uc_full: '1f480', shortnames: [':skeleton:'], category: 'people' }, + ':skunk:': { uc_base: '1f9a8', uc_full: '1f9a8', shortnames: [], category: 'nature' }, + ':sled:': { uc_base: '1f6f7', uc_full: '1f6f7', shortnames: [], category: 'activity' }, + ':sleeping:': { uc_base: '1f634', uc_full: '1f634', shortnames: [], category: 'people' }, + ':sleeping_accommodation:': { uc_base: '1f6cc', uc_full: '1f6cc', shortnames: [], category: 'objects' }, + ':sleepy:': { uc_base: '1f62a', uc_full: '1f62a', shortnames: [], category: 'people' }, + ':slight_frown:': { uc_base: '1f641', uc_full: '1f641', shortnames: [':slightly_frowning_face:'], category: 'people' }, + ':slight_smile:': { uc_base: '1f642', uc_full: '1f642', shortnames: [':slightly_smiling_face:'], category: 'people' }, + ':slot_machine:': { uc_base: '1f3b0', uc_full: '1f3b0', shortnames: [], category: 'activity' }, + ':sloth:': { uc_base: '1f9a5', uc_full: '1f9a5', shortnames: [], category: 'nature' }, + ':small_blue_diamond:': { uc_base: '1f539', uc_full: '1f539', shortnames: [], category: 'symbols' }, + ':small_orange_diamond:': { uc_base: '1f538', uc_full: '1f538', shortnames: [], category: 'symbols' }, + ':small_red_triangle:': { uc_base: '1f53a', uc_full: '1f53a', shortnames: [], category: 'symbols' }, + ':small_red_triangle_down:': { uc_base: '1f53b', uc_full: '1f53b', shortnames: [], category: 'symbols' }, + ':smile:': { uc_base: '1f604', uc_full: '1f604', shortnames: [], category: 'people' }, + ':smile_cat:': { uc_base: '1f638', uc_full: '1f638', shortnames: [], category: 'people' }, + ':smiley:': { uc_base: '1f603', uc_full: '1f603', shortnames: [], category: 'people' }, + ':smiley_cat:': { uc_base: '1f63a', uc_full: '1f63a', shortnames: [], category: 'people' }, + ':smiling_face_with_3_hearts:': { uc_base: '1f970', uc_full: '1f970', shortnames: [], category: 'people' }, + ':smiling_face_with_tear:': { uc_base: '1f972', uc_full: '1f972', shortnames: [], category: 'people' }, + ':smiling_imp:': { uc_base: '1f608', uc_full: '1f608', shortnames: [], category: 'people' }, + ':smirk:': { uc_base: '1f60f', uc_full: '1f60f', shortnames: [], category: 'people' }, + ':smirk_cat:': { uc_base: '1f63c', uc_full: '1f63c', shortnames: [], category: 'people' }, + ':smoking:': { uc_base: '1f6ac', uc_full: '1f6ac', shortnames: [], category: 'objects' }, + ':snail:': { uc_base: '1f40c', uc_full: '1f40c', shortnames: [], category: 'nature' }, + ':snake:': { uc_base: '1f40d', uc_full: '1f40d', shortnames: [], category: 'nature' }, + ':sneezing_face:': { uc_base: '1f927', uc_full: '1f927', shortnames: [':sneeze:'], category: 'people' }, + ':snowboarder:': { uc_base: '1f3c2', uc_full: '1f3c2', shortnames: [], category: 'activity' }, + ':soap:': { uc_base: '1f9fc', uc_full: '1f9fc', shortnames: [], category: 'objects' }, + ':sob:': { uc_base: '1f62d', uc_full: '1f62d', shortnames: [], category: 'people' }, + ':socks:': { uc_base: '1f9e6', uc_full: '1f9e6', shortnames: [], category: 'people' }, + ':softball:': { uc_base: '1f94e', uc_full: '1f94e', shortnames: [], category: 'activity' }, + ':soon:': { uc_base: '1f51c', uc_full: '1f51c', shortnames: [], category: 'symbols' }, + ':sos:': { uc_base: '1f198', uc_full: '1f198', shortnames: [], category: 'symbols' }, + ':sound:': { uc_base: '1f509', uc_full: '1f509', shortnames: [], category: 'symbols' }, + ':space_invader:': { uc_base: '1f47e', uc_full: '1f47e', shortnames: [], category: 'people' }, + ':spaghetti:': { uc_base: '1f35d', uc_full: '1f35d', shortnames: [], category: 'food' }, + ':sparkler:': { uc_base: '1f387', uc_full: '1f387', shortnames: [], category: 'travel' }, + ':sparkling_heart:': { uc_base: '1f496', uc_full: '1f496', shortnames: [], category: 'symbols' }, + ':speak_no_evil:': { uc_base: '1f64a', uc_full: '1f64a', shortnames: [], category: 'nature' }, + ':speaker:': { uc_base: '1f508', uc_full: '1f508', shortnames: [], category: 'symbols' }, + ':speaking_head:': { uc_base: '1f5e3', uc_full: '1f5e3-fe0f', shortnames: [':speaking_head_in_silhouette:'], category: 'people' }, + ':speech_balloon:': { uc_base: '1f4ac', uc_full: '1f4ac', shortnames: [], category: 'symbols' }, + ':speech_left:': { uc_base: '1f5e8', uc_full: '1f5e8-fe0f', shortnames: [':left_speech_bubble:'], category: 'symbols' }, + ':speedboat:': { uc_base: '1f6a4', uc_full: '1f6a4', shortnames: [], category: 'travel' }, + ':spider:': { uc_base: '1f577', uc_full: '1f577-fe0f', shortnames: [], category: 'nature' }, + ':spider_web:': { uc_base: '1f578', uc_full: '1f578-fe0f', shortnames: [], category: 'nature' }, + ':sponge:': { uc_base: '1f9fd', uc_full: '1f9fd', shortnames: [], category: 'objects' }, + ':spoon:': { uc_base: '1f944', uc_full: '1f944', shortnames: [], category: 'food' }, + ':squeeze_bottle:': { uc_base: '1f9f4', uc_full: '1f9f4', shortnames: [], category: 'objects' }, + ':squid:': { uc_base: '1f991', uc_full: '1f991', shortnames: [], category: 'nature' }, + ':stadium:': { uc_base: '1f3df', uc_full: '1f3df-fe0f', shortnames: [], category: 'travel' }, + ':star2:': { uc_base: '1f31f', uc_full: '1f31f', shortnames: [], category: 'nature' }, + ':star_struck:': { uc_base: '1f929', uc_full: '1f929', shortnames: [], category: 'people' }, + ':stars:': { uc_base: '1f320', uc_full: '1f320', shortnames: [], category: 'travel' }, + ':station:': { uc_base: '1f689', uc_full: '1f689', shortnames: [], category: 'travel' }, + ':statue_of_liberty:': { uc_base: '1f5fd', uc_full: '1f5fd', shortnames: [], category: 'travel' }, + ':steam_locomotive:': { uc_base: '1f682', uc_full: '1f682', shortnames: [], category: 'travel' }, + ':stethoscope:': { uc_base: '1fa7a', uc_full: '1fa7a', shortnames: [], category: 'objects' }, + ':stew:': { uc_base: '1f372', uc_full: '1f372', shortnames: [], category: 'food' }, + ':straight_ruler:': { uc_base: '1f4cf', uc_full: '1f4cf', shortnames: [], category: 'objects' }, + ':strawberry:': { uc_base: '1f353', uc_full: '1f353', shortnames: [], category: 'food' }, + ':stuck_out_tongue:': { uc_base: '1f61b', uc_full: '1f61b', shortnames: [], category: 'people' }, + ':stuck_out_tongue_closed_eyes:': { uc_base: '1f61d', uc_full: '1f61d', shortnames: [], category: 'people' }, + ':stuck_out_tongue_winking_eye:': { uc_base: '1f61c', uc_full: '1f61c', shortnames: [], category: 'people' }, + ':stuffed_flatbread:': { uc_base: '1f959', uc_full: '1f959', shortnames: [':stuffed_pita:'], category: 'food' }, + ':sun_with_face:': { uc_base: '1f31e', uc_full: '1f31e', shortnames: [], category: 'nature' }, + ':sunflower:': { uc_base: '1f33b', uc_full: '1f33b', shortnames: [], category: 'nature' }, + ':sunglasses:': { uc_base: '1f60e', uc_full: '1f60e', shortnames: [], category: 'people' }, + ':sunrise:': { uc_base: '1f305', uc_full: '1f305', shortnames: [], category: 'travel' }, + ':sunrise_over_mountains:': { uc_base: '1f304', uc_full: '1f304', shortnames: [], category: 'travel' }, + ':superhero:': { uc_base: '1f9b8', uc_full: '1f9b8', shortnames: [], category: 'people' }, + ':supervillain:': { uc_base: '1f9b9', uc_full: '1f9b9', shortnames: [], category: 'people' }, + ':sushi:': { uc_base: '1f363', uc_full: '1f363', shortnames: [], category: 'food' }, + ':suspension_railway:': { uc_base: '1f69f', uc_full: '1f69f', shortnames: [], category: 'travel' }, + ':swan:': { uc_base: '1f9a2', uc_full: '1f9a2', shortnames: [], category: 'nature' }, + ':sweat:': { uc_base: '1f613', uc_full: '1f613', shortnames: [], category: 'people' }, + ':sweat_drops:': { uc_base: '1f4a6', uc_full: '1f4a6', shortnames: [], category: 'nature' }, + ':sweat_smile:': { uc_base: '1f605', uc_full: '1f605', shortnames: [], category: 'people' }, + ':sweet_potato:': { uc_base: '1f360', uc_full: '1f360', shortnames: [], category: 'food' }, + ':symbols:': { uc_base: '1f523', uc_full: '1f523', shortnames: [], category: 'symbols' }, + ':synagogue:': { uc_base: '1f54d', uc_full: '1f54d', shortnames: [], category: 'travel' }, + ':syringe:': { uc_base: '1f489', uc_full: '1f489', shortnames: [], category: 'objects' }, + ':t_rex:': { uc_base: '1f996', uc_full: '1f996', shortnames: [], category: 'nature' }, + ':taco:': { uc_base: '1f32e', uc_full: '1f32e', shortnames: [], category: 'food' }, + ':tada:': { uc_base: '1f389', uc_full: '1f389', shortnames: [], category: 'objects' }, + ':takeout_box:': { uc_base: '1f961', uc_full: '1f961', shortnames: [], category: 'food' }, + ':tamale:': { uc_base: '1fad4', uc_full: '1fad4', shortnames: [], category: 'food' }, + ':tanabata_tree:': { uc_base: '1f38b', uc_full: '1f38b', shortnames: [], category: 'nature' }, + ':tangerine:': { uc_base: '1f34a', uc_full: '1f34a', shortnames: [], category: 'food' }, + ':taxi:': { uc_base: '1f695', uc_full: '1f695', shortnames: [], category: 'travel' }, + ':tea:': { uc_base: '1f375', uc_full: '1f375', shortnames: [], category: 'food' }, + ':teapot:': { uc_base: '1fad6', uc_full: '1fad6', shortnames: [], category: 'food' }, + ':teddy_bear:': { uc_base: '1f9f8', uc_full: '1f9f8', shortnames: [], category: 'objects' }, + ':telephone_receiver:': { uc_base: '1f4de', uc_full: '1f4de', shortnames: [], category: 'objects' }, + ':telescope:': { uc_base: '1f52d', uc_full: '1f52d', shortnames: [], category: 'objects' }, + ':tennis:': { uc_base: '1f3be', uc_full: '1f3be', shortnames: [], category: 'activity' }, + ':test_tube:': { uc_base: '1f9ea', uc_full: '1f9ea', shortnames: [], category: 'objects' }, + ':thermometer:': { uc_base: '1f321', uc_full: '1f321-fe0f', shortnames: [], category: 'objects' }, + ':thermometer_face:': { uc_base: '1f912', uc_full: '1f912', shortnames: [':face_with_thermometer:'], category: 'people' }, + ':thinking:': { uc_base: '1f914', uc_full: '1f914', shortnames: [':thinking_face:'], category: 'people' }, + ':third_place:': { uc_base: '1f949', uc_full: '1f949', shortnames: [':third_place_medal:'], category: 'activity' }, + ':thong_sandal:': { uc_base: '1fa74', uc_full: '1fa74', shortnames: [], category: 'people' }, + ':thought_balloon:': { uc_base: '1f4ad', uc_full: '1f4ad', shortnames: [], category: 'symbols' }, + ':thread:': { uc_base: '1f9f5', uc_full: '1f9f5', shortnames: [], category: 'people' }, + ':thumbsdown:': { uc_base: '1f44e', uc_full: '1f44e', shortnames: [':-1:', ':thumbdown:'], category: 'people' }, + ':thumbsup:': { uc_base: '1f44d', uc_full: '1f44d', shortnames: [':+1:', ':thumbup:'], category: 'people' }, + ':ticket:': { uc_base: '1f3ab', uc_full: '1f3ab', shortnames: [], category: 'activity' }, + ':tickets:': { uc_base: '1f39f', uc_full: '1f39f-fe0f', shortnames: [':admission_tickets:'], category: 'activity' }, + ':tiger2:': { uc_base: '1f405', uc_full: '1f405', shortnames: [], category: 'nature' }, + ':tiger:': { uc_base: '1f42f', uc_full: '1f42f', shortnames: [], category: 'nature' }, + ':tired_face:': { uc_base: '1f62b', uc_full: '1f62b', shortnames: [], category: 'people' }, + ':toilet:': { uc_base: '1f6bd', uc_full: '1f6bd', shortnames: [], category: 'objects' }, + ':tokyo_tower:': { uc_base: '1f5fc', uc_full: '1f5fc', shortnames: [], category: 'travel' }, + ':tomato:': { uc_base: '1f345', uc_full: '1f345', shortnames: [], category: 'food' }, + ':tone1:': { uc_base: '1f3fb', uc_full: '1f3fb', shortnames: [], category: 'modifier' }, + ':tone2:': { uc_base: '1f3fc', uc_full: '1f3fc', shortnames: [], category: 'modifier' }, + ':tone3:': { uc_base: '1f3fd', uc_full: '1f3fd', shortnames: [], category: 'modifier' }, + ':tone4:': { uc_base: '1f3fe', uc_full: '1f3fe', shortnames: [], category: 'modifier' }, + ':tone5:': { uc_base: '1f3ff', uc_full: '1f3ff', shortnames: [], category: 'modifier' }, + ':tongue:': { uc_base: '1f445', uc_full: '1f445', shortnames: [], category: 'people' }, + ':toolbox:': { uc_base: '1f9f0', uc_full: '1f9f0', shortnames: [], category: 'objects' }, + ':tools:': { uc_base: '1f6e0', uc_full: '1f6e0-fe0f', shortnames: [':hammer_and_wrench:'], category: 'objects' }, + ':tooth:': { uc_base: '1f9b7', uc_full: '1f9b7', shortnames: [], category: 'people' }, + ':toothbrush:': { uc_base: '1faa5', uc_full: '1faa5', shortnames: [], category: 'objects' }, + ':top:': { uc_base: '1f51d', uc_full: '1f51d', shortnames: [], category: 'symbols' }, + ':tophat:': { uc_base: '1f3a9', uc_full: '1f3a9', shortnames: [], category: 'people' }, + ':trackball:': { uc_base: '1f5b2', uc_full: '1f5b2-fe0f', shortnames: [], category: 'objects' }, + ':tractor:': { uc_base: '1f69c', uc_full: '1f69c', shortnames: [], category: 'travel' }, + ':traffic_light:': { uc_base: '1f6a5', uc_full: '1f6a5', shortnames: [], category: 'travel' }, + ':train2:': { uc_base: '1f686', uc_full: '1f686', shortnames: [], category: 'travel' }, + ':train:': { uc_base: '1f68b', uc_full: '1f68b', shortnames: [], category: 'travel' }, + ':tram:': { uc_base: '1f68a', uc_full: '1f68a', shortnames: [], category: 'travel' }, + ':triangular_flag_on_post:': { uc_base: '1f6a9', uc_full: '1f6a9', shortnames: [], category: 'flags' }, + ':triangular_ruler:': { uc_base: '1f4d0', uc_full: '1f4d0', shortnames: [], category: 'objects' }, + ':trident:': { uc_base: '1f531', uc_full: '1f531', shortnames: [], category: 'symbols' }, + ':triumph:': { uc_base: '1f624', uc_full: '1f624', shortnames: [], category: 'people' }, + ':trolleybus:': { uc_base: '1f68e', uc_full: '1f68e', shortnames: [], category: 'travel' }, + ':trophy:': { uc_base: '1f3c6', uc_full: '1f3c6', shortnames: [], category: 'activity' }, + ':tropical_drink:': { uc_base: '1f379', uc_full: '1f379', shortnames: [], category: 'food' }, + ':tropical_fish:': { uc_base: '1f420', uc_full: '1f420', shortnames: [], category: 'nature' }, + ':truck:': { uc_base: '1f69a', uc_full: '1f69a', shortnames: [], category: 'travel' }, + ':trumpet:': { uc_base: '1f3ba', uc_full: '1f3ba', shortnames: [], category: 'activity' }, + ':tulip:': { uc_base: '1f337', uc_full: '1f337', shortnames: [], category: 'nature' }, + ':tumbler_glass:': { uc_base: '1f943', uc_full: '1f943', shortnames: [':whisky:'], category: 'food' }, + ':turkey:': { uc_base: '1f983', uc_full: '1f983', shortnames: [], category: 'nature' }, + ':turtle:': { uc_base: '1f422', uc_full: '1f422', shortnames: [], category: 'nature' }, + ':tv:': { uc_base: '1f4fa', uc_full: '1f4fa', shortnames: [], category: 'objects' }, + ':twisted_rightwards_arrows:': { uc_base: '1f500', uc_full: '1f500', shortnames: [], category: 'symbols' }, + ':two_hearts:': { uc_base: '1f495', uc_full: '1f495', shortnames: [], category: 'symbols' }, + ':two_men_holding_hands:': { uc_base: '1f46c', uc_full: '1f46c', shortnames: [], category: 'people' }, + ':two_women_holding_hands:': { uc_base: '1f46d', uc_full: '1f46d', shortnames: [], category: 'people' }, + ':u5272:': { uc_base: '1f239', uc_full: '1f239', shortnames: [], category: 'symbols' }, + ':u5408:': { uc_base: '1f234', uc_full: '1f234', shortnames: [], category: 'symbols' }, + ':u55b6:': { uc_base: '1f23a', uc_full: '1f23a', shortnames: [], category: 'symbols' }, + ':u6307:': { uc_base: '1f22f', uc_full: '1f22f', shortnames: [], category: 'symbols' }, + ':u6708:': { uc_base: '1f237', uc_full: '1f237-fe0f', shortnames: [], category: 'symbols' }, + ':u6709:': { uc_base: '1f236', uc_full: '1f236', shortnames: [], category: 'symbols' }, + ':u6e80:': { uc_base: '1f235', uc_full: '1f235', shortnames: [], category: 'symbols' }, + ':u7121:': { uc_base: '1f21a', uc_full: '1f21a', shortnames: [], category: 'symbols' }, + ':u7533:': { uc_base: '1f238', uc_full: '1f238', shortnames: [], category: 'symbols' }, + ':u7981:': { uc_base: '1f232', uc_full: '1f232', shortnames: [], category: 'symbols' }, + ':u7a7a:': { uc_base: '1f233', uc_full: '1f233', shortnames: [], category: 'symbols' }, + ':unamused:': { uc_base: '1f612', uc_full: '1f612', shortnames: [], category: 'people' }, + ':underage:': { uc_base: '1f51e', uc_full: '1f51e', shortnames: [], category: 'symbols' }, + ':unicorn:': { uc_base: '1f984', uc_full: '1f984', shortnames: [':unicorn_face:'], category: 'nature' }, + ':unlock:': { uc_base: '1f513', uc_full: '1f513', shortnames: [], category: 'objects' }, + ':up:': { uc_base: '1f199', uc_full: '1f199', shortnames: [], category: 'symbols' }, + ':upside_down:': { uc_base: '1f643', uc_full: '1f643', shortnames: [':upside_down_face:'], category: 'people' }, + ':vampire:': { uc_base: '1f9db', uc_full: '1f9db', shortnames: [], category: 'people' }, + ':vertical_traffic_light:': { uc_base: '1f6a6', uc_full: '1f6a6', shortnames: [], category: 'travel' }, + ':vhs:': { uc_base: '1f4fc', uc_full: '1f4fc', shortnames: [], category: 'objects' }, + ':vibration_mode:': { uc_base: '1f4f3', uc_full: '1f4f3', shortnames: [], category: 'symbols' }, + ':video_camera:': { uc_base: '1f4f9', uc_full: '1f4f9', shortnames: [], category: 'objects' }, + ':video_game:': { uc_base: '1f3ae', uc_full: '1f3ae', shortnames: [], category: 'activity' }, + ':violin:': { uc_base: '1f3bb', uc_full: '1f3bb', shortnames: [], category: 'activity' }, + ':volcano:': { uc_base: '1f30b', uc_full: '1f30b', shortnames: [], category: 'travel' }, + ':volleyball:': { uc_base: '1f3d0', uc_full: '1f3d0', shortnames: [], category: 'activity' }, + ':vs:': { uc_base: '1f19a', uc_full: '1f19a', shortnames: [], category: 'symbols' }, + ':vulcan:': { + uc_base: '1f596', + uc_full: '1f596', + shortnames: [':raised_hand_with_part_between_middle_and_ring_fingers:'], + category: 'people', + }, + ':waffle:': { uc_base: '1f9c7', uc_full: '1f9c7', shortnames: [], category: 'food' }, + ':waning_crescent_moon:': { uc_base: '1f318', uc_full: '1f318', shortnames: [], category: 'nature' }, + ':waning_gibbous_moon:': { uc_base: '1f316', uc_full: '1f316', shortnames: [], category: 'nature' }, + ':wastebasket:': { uc_base: '1f5d1', uc_full: '1f5d1-fe0f', shortnames: [], category: 'objects' }, + ':water_buffalo:': { uc_base: '1f403', uc_full: '1f403', shortnames: [], category: 'nature' }, + ':watermelon:': { uc_base: '1f349', uc_full: '1f349', shortnames: [], category: 'food' }, + ':wave:': { uc_base: '1f44b', uc_full: '1f44b', shortnames: [], category: 'people' }, + ':waxing_crescent_moon:': { uc_base: '1f312', uc_full: '1f312', shortnames: [], category: 'nature' }, + ':waxing_gibbous_moon:': { uc_base: '1f314', uc_full: '1f314', shortnames: [], category: 'nature' }, + ':wc:': { uc_base: '1f6be', uc_full: '1f6be', shortnames: [], category: 'symbols' }, + ':weary:': { uc_base: '1f629', uc_full: '1f629', shortnames: [], category: 'people' }, + ':wedding:': { uc_base: '1f492', uc_full: '1f492', shortnames: [], category: 'travel' }, + ':whale2:': { uc_base: '1f40b', uc_full: '1f40b', shortnames: [], category: 'nature' }, + ':whale:': { uc_base: '1f433', uc_full: '1f433', shortnames: [], category: 'nature' }, + ':white_flower:': { uc_base: '1f4ae', uc_full: '1f4ae', shortnames: [], category: 'symbols' }, + ':white_haired:': { uc_base: '1f9b3', uc_full: '1f9b3', shortnames: [], category: 'people' }, + ':white_heart:': { uc_base: '1f90d', uc_full: '1f90d', shortnames: [], category: 'symbols' }, + ':white_square_button:': { uc_base: '1f533', uc_full: '1f533', shortnames: [], category: 'symbols' }, + ':white_sun_cloud:': { uc_base: '1f325', uc_full: '1f325-fe0f', shortnames: [':white_sun_behind_cloud:'], category: 'nature' }, + ':white_sun_rain_cloud:': { + uc_base: '1f326', + uc_full: '1f326-fe0f', + shortnames: [':white_sun_behind_cloud_with_rain:'], + category: 'nature', + }, + ':white_sun_small_cloud:': { + uc_base: '1f324', + uc_full: '1f324-fe0f', + shortnames: [':white_sun_with_small_cloud:'], + category: 'nature', + }, + ':wilted_rose:': { uc_base: '1f940', uc_full: '1f940', shortnames: [':wilted_flower:'], category: 'nature' }, + ':wind_blowing_face:': { uc_base: '1f32c', uc_full: '1f32c-fe0f', shortnames: [], category: 'nature' }, + ':wind_chime:': { uc_base: '1f390', uc_full: '1f390', shortnames: [], category: 'objects' }, + ':window:': { uc_base: '1fa9f', uc_full: '1fa9f', shortnames: [], category: 'objects' }, + ':wine_glass:': { uc_base: '1f377', uc_full: '1f377', shortnames: [], category: 'food' }, + ':wink:': { uc_base: '1f609', uc_full: '1f609', shortnames: [], category: 'people' }, + ':wolf:': { uc_base: '1f43a', uc_full: '1f43a', shortnames: [], category: 'nature' }, + ':woman:': { uc_base: '1f469', uc_full: '1f469', shortnames: [], category: 'people' }, + ':woman_with_headscarf:': { uc_base: '1f9d5', uc_full: '1f9d5', shortnames: [], category: 'people' }, + ':womans_clothes:': { uc_base: '1f45a', uc_full: '1f45a', shortnames: [], category: 'people' }, + ':womans_flat_shoe:': { uc_base: '1f97f', uc_full: '1f97f', shortnames: [], category: 'people' }, + ':womans_hat:': { uc_base: '1f452', uc_full: '1f452', shortnames: [], category: 'people' }, + ':womens:': { uc_base: '1f6ba', uc_full: '1f6ba', shortnames: [], category: 'symbols' }, + ':wood:': { uc_base: '1fab5', uc_full: '1fab5', shortnames: [], category: 'nature' }, + ':woozy_face:': { uc_base: '1f974', uc_full: '1f974', shortnames: [], category: 'people' }, + ':worm:': { uc_base: '1fab1', uc_full: '1fab1', shortnames: [], category: 'nature' }, + ':worried:': { uc_base: '1f61f', uc_full: '1f61f', shortnames: [], category: 'people' }, + ':wrench:': { uc_base: '1f527', uc_full: '1f527', shortnames: [], category: 'objects' }, + ':yarn:': { uc_base: '1f9f6', uc_full: '1f9f6', shortnames: [], category: 'people' }, + ':yawning_face:': { uc_base: '1f971', uc_full: '1f971', shortnames: [], category: 'people' }, + ':yellow_circle:': { uc_base: '1f7e1', uc_full: '1f7e1', shortnames: [], category: 'symbols' }, + ':yellow_heart:': { uc_base: '1f49b', uc_full: '1f49b', shortnames: [], category: 'symbols' }, + ':yellow_square:': { uc_base: '1f7e8', uc_full: '1f7e8', shortnames: [], category: 'symbols' }, + ':yen:': { uc_base: '1f4b4', uc_full: '1f4b4', shortnames: [], category: 'objects' }, + ':yo_yo:': { uc_base: '1fa80', uc_full: '1fa80', shortnames: [], category: 'activity' }, + ':yum:': { uc_base: '1f60b', uc_full: '1f60b', shortnames: [], category: 'people' }, + ':zany_face:': { uc_base: '1f92a', uc_full: '1f92a', shortnames: [], category: 'people' }, + ':zebra:': { uc_base: '1f993', uc_full: '1f993', shortnames: [], category: 'nature' }, + ':zipper_mouth:': { uc_base: '1f910', uc_full: '1f910', shortnames: [':zipper_mouth_face:'], category: 'people' }, + ':zombie:': { uc_base: '1f9df', uc_full: '1f9df', shortnames: [], category: 'people' }, + ':zzz:': { uc_base: '1f4a4', uc_full: '1f4a4', shortnames: [], category: 'symbols' }, + ':airplane:': { uc_base: '2708', uc_full: '2708-fe0f', shortnames: [], category: 'travel' }, + ':alarm_clock:': { uc_base: '23f0', uc_full: '23f0', shortnames: [], category: 'objects' }, + ':alembic:': { uc_base: '2697', uc_full: '2697-fe0f', shortnames: [], category: 'objects' }, + ':anchor:': { uc_base: '2693', uc_full: '2693', shortnames: [], category: 'travel' }, + ':aquarius:': { uc_base: '2652', uc_full: '2652', shortnames: [], category: 'symbols' }, + ':aries:': { uc_base: '2648', uc_full: '2648', shortnames: [], category: 'symbols' }, + ':arrow_backward:': { uc_base: '25c0', uc_full: '25c0-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_double_down:': { uc_base: '23ec', uc_full: '23ec', shortnames: [], category: 'symbols' }, + ':arrow_double_up:': { uc_base: '23eb', uc_full: '23eb', shortnames: [], category: 'symbols' }, + ':arrow_down:': { uc_base: '2b07', uc_full: '2b07-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_forward:': { uc_base: '25b6', uc_full: '25b6-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_heading_down:': { uc_base: '2935', uc_full: '2935-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_heading_up:': { uc_base: '2934', uc_full: '2934-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_left:': { uc_base: '2b05', uc_full: '2b05-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_lower_left:': { uc_base: '2199', uc_full: '2199-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_lower_right:': { uc_base: '2198', uc_full: '2198-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_right:': { uc_base: '27a1', uc_full: '27a1-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_right_hook:': { uc_base: '21aa', uc_full: '21aa-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_up:': { uc_base: '2b06', uc_full: '2b06-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_up_down:': { uc_base: '2195', uc_full: '2195-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_upper_left:': { uc_base: '2196', uc_full: '2196-fe0f', shortnames: [], category: 'symbols' }, + ':arrow_upper_right:': { uc_base: '2197', uc_full: '2197-fe0f', shortnames: [], category: 'symbols' }, + ':asterisk_symbol:': { uc_base: '002a', uc_full: '002a-fe0f', shortnames: [], category: 'symbols' }, + ':atom:': { uc_base: '269b', uc_full: '269b-fe0f', shortnames: [':atom_symbol:'], category: 'symbols' }, + ':ballot_box_with_check:': { uc_base: '2611', uc_full: '2611-fe0f', shortnames: [], category: 'symbols' }, + ':bangbang:': { uc_base: '203c', uc_full: '203c-fe0f', shortnames: [], category: 'symbols' }, + ':baseball:': { uc_base: '26be', uc_full: '26be', shortnames: [], category: 'activity' }, + ':beach_umbrella:': { uc_base: '26f1', uc_full: '26f1-fe0f', shortnames: [':umbrella_on_ground:'], category: 'travel' }, + ':biohazard:': { uc_base: '2623', uc_full: '2623-fe0f', shortnames: [':biohazard_sign:'], category: 'symbols' }, + ':black_circle:': { uc_base: '26ab', uc_full: '26ab', shortnames: [], category: 'symbols' }, + ':black_large_square:': { uc_base: '2b1b', uc_full: '2b1b', shortnames: [], category: 'symbols' }, + ':black_medium_small_square:': { uc_base: '25fe', uc_full: '25fe', shortnames: [], category: 'symbols' }, + ':black_medium_square:': { uc_base: '25fc', uc_full: '25fc-fe0f', shortnames: [], category: 'symbols' }, + ':black_nib:': { uc_base: '2712', uc_full: '2712-fe0f', shortnames: [], category: 'objects' }, + ':black_small_square:': { uc_base: '25aa', uc_full: '25aa-fe0f', shortnames: [], category: 'symbols' }, + ':cancer:': { uc_base: '264b', uc_full: '264b', shortnames: [], category: 'symbols' }, + ':capricorn:': { uc_base: '2651', uc_full: '2651', shortnames: [], category: 'symbols' }, + ':chains:': { uc_base: '26d3', uc_full: '26d3-fe0f', shortnames: [], category: 'objects' }, + ':chess_pawn:': { uc_base: '265f', uc_full: '265f-fe0f', shortnames: [], category: 'activity' }, + ':church:': { uc_base: '26ea', uc_full: '26ea', shortnames: [], category: 'travel' }, + ':cloud:': { uc_base: '2601', uc_full: '2601-fe0f', shortnames: [], category: 'nature' }, + ':clubs:': { uc_base: '2663', uc_full: '2663-fe0f', shortnames: [], category: 'symbols' }, + ':coffee:': { uc_base: '2615', uc_full: '2615', shortnames: [], category: 'food' }, + ':coffin:': { uc_base: '26b0', uc_full: '26b0-fe0f', shortnames: [], category: 'objects' }, + ':comet:': { uc_base: '2604', uc_full: '2604-fe0f', shortnames: [], category: 'nature' }, + ':congratulations:': { uc_base: '3297', uc_full: '3297-fe0f', shortnames: [], category: 'symbols' }, + ':copyright:': { uc_base: '00a9', uc_full: '00a9-fe0f', shortnames: [], category: 'symbols' }, + ':cross:': { uc_base: '271d', uc_full: '271d-fe0f', shortnames: [':latin_cross:'], category: 'symbols' }, + ':crossed_swords:': { uc_base: '2694', uc_full: '2694-fe0f', shortnames: [], category: 'objects' }, + ':curly_loop:': { uc_base: '27b0', uc_full: '27b0', shortnames: [], category: 'symbols' }, + ':diamonds:': { uc_base: '2666', uc_full: '2666-fe0f', shortnames: [], category: 'symbols' }, + ':digit_eight:': { uc_base: '0038', uc_full: '0038-fe0f', shortnames: [], category: 'symbols' }, + ':digit_five:': { uc_base: '0035', uc_full: '0035-fe0f', shortnames: [], category: 'symbols' }, + ':digit_four:': { uc_base: '0034', uc_full: '0034-fe0f', shortnames: [], category: 'symbols' }, + ':digit_nine:': { uc_base: '0039', uc_full: '0039-fe0f', shortnames: [], category: 'symbols' }, + ':digit_one:': { uc_base: '0031', uc_full: '0031-fe0f', shortnames: [], category: 'symbols' }, + ':digit_seven:': { uc_base: '0037', uc_full: '0037-fe0f', shortnames: [], category: 'symbols' }, + ':digit_six:': { uc_base: '0036', uc_full: '0036-fe0f', shortnames: [], category: 'symbols' }, + ':digit_three:': { uc_base: '0033', uc_full: '0033-fe0f', shortnames: [], category: 'symbols' }, + ':digit_two:': { uc_base: '0032', uc_full: '0032-fe0f', shortnames: [], category: 'symbols' }, + ':digit_zero:': { uc_base: '0030', uc_full: '0030-fe0f', shortnames: [], category: 'symbols' }, + ':eight_pointed_black_star:': { uc_base: '2734', uc_full: '2734-fe0f', shortnames: [], category: 'symbols' }, + ':eight_spoked_asterisk:': { uc_base: '2733', uc_full: '2733-fe0f', shortnames: [], category: 'symbols' }, + ':eject:': { uc_base: '23cf', uc_full: '23cf-fe0f', shortnames: [':eject_symbol:'], category: 'symbols' }, + ':envelope:': { uc_base: '2709', uc_full: '2709-fe0f', shortnames: [], category: 'objects' }, + ':exclamation:': { uc_base: '2757', uc_full: '2757', shortnames: [], category: 'symbols' }, + ':fast_forward:': { uc_base: '23e9', uc_full: '23e9', shortnames: [], category: 'symbols' }, + ':female_sign:': { uc_base: '2640', uc_full: '2640-fe0f', shortnames: [], category: 'symbols' }, + ':ferry:': { uc_base: '26f4', uc_full: '26f4-fe0f', shortnames: [], category: 'travel' }, + ':fist:': { uc_base: '270a', uc_full: '270a', shortnames: [], category: 'people' }, + ':fleur-de-lis:': { uc_base: '269c', uc_full: '269c-fe0f', shortnames: [], category: 'symbols' }, + ':fountain:': { uc_base: '26f2', uc_full: '26f2', shortnames: [], category: 'travel' }, + ':frowning2:': { uc_base: '2639', uc_full: '2639-fe0f', shortnames: [':white_frowning_face:'], category: 'people' }, + ':fuelpump:': { uc_base: '26fd', uc_full: '26fd', shortnames: [], category: 'travel' }, + ':gear:': { uc_base: '2699', uc_full: '2699-fe0f', shortnames: [], category: 'objects' }, + ':gemini:': { uc_base: '264a', uc_full: '264a', shortnames: [], category: 'symbols' }, + ':golf:': { uc_base: '26f3', uc_full: '26f3', shortnames: [], category: 'activity' }, + ':grey_exclamation:': { uc_base: '2755', uc_full: '2755', shortnames: [], category: 'symbols' }, + ':grey_question:': { uc_base: '2754', uc_full: '2754', shortnames: [], category: 'symbols' }, + ':hammer_pick:': { uc_base: '2692', uc_full: '2692-fe0f', shortnames: [':hammer_and_pick:'], category: 'objects' }, + ':heart:': { uc_base: '2764', uc_full: '2764-fe0f', shortnames: [], category: 'symbols' }, + ':heart_exclamation:': { + uc_base: '2763', + uc_full: '2763-fe0f', + shortnames: [':heavy_heart_exclamation_mark_ornament:'], + category: 'symbols', + }, + ':hearts:': { uc_base: '2665', uc_full: '2665-fe0f', shortnames: [], category: 'symbols' }, + ':heavy_check_mark:': { uc_base: '2714', uc_full: '2714-fe0f', shortnames: [], category: 'symbols' }, + ':heavy_division_sign:': { uc_base: '2797', uc_full: '2797', shortnames: [], category: 'symbols' }, + ':heavy_minus_sign:': { uc_base: '2796', uc_full: '2796', shortnames: [], category: 'symbols' }, + ':heavy_multiplication_x:': { uc_base: '2716', uc_full: '2716-fe0f', shortnames: [], category: 'symbols' }, + ':heavy_plus_sign:': { uc_base: '2795', uc_full: '2795', shortnames: [], category: 'symbols' }, + ':helmet_with_cross:': { uc_base: '26d1', uc_full: '26d1-fe0f', shortnames: [':helmet_with_white_cross:'], category: 'people' }, + ':hotsprings:': { uc_base: '2668', uc_full: '2668-fe0f', shortnames: [], category: 'symbols' }, + ':hourglass:': { uc_base: '231b', uc_full: '231b', shortnames: [], category: 'objects' }, + ':hourglass_flowing_sand:': { uc_base: '23f3', uc_full: '23f3', shortnames: [], category: 'objects' }, + ':ice_skate:': { uc_base: '26f8', uc_full: '26f8-fe0f', shortnames: [], category: 'activity' }, + ':infinity:': { uc_base: '267e', uc_full: '267e-fe0f', shortnames: [], category: 'symbols' }, + ':information_source:': { uc_base: '2139', uc_full: '2139-fe0f', shortnames: [], category: 'symbols' }, + ':interrobang:': { uc_base: '2049', uc_full: '2049-fe0f', shortnames: [], category: 'symbols' }, + ':keyboard:': { uc_base: '2328', uc_full: '2328-fe0f', shortnames: [], category: 'objects' }, + ':left_right_arrow:': { uc_base: '2194', uc_full: '2194-fe0f', shortnames: [], category: 'symbols' }, + ':leftwards_arrow_with_hook:': { uc_base: '21a9', uc_full: '21a9-fe0f', shortnames: [], category: 'symbols' }, + ':leo:': { uc_base: '264c', uc_full: '264c', shortnames: [], category: 'symbols' }, + ':libra:': { uc_base: '264e', uc_full: '264e', shortnames: [], category: 'symbols' }, + ':loop:': { uc_base: '27bf', uc_full: '27bf', shortnames: [], category: 'symbols' }, + ':m:': { uc_base: '24c2', uc_full: '24c2-fe0f', shortnames: [], category: 'symbols' }, + ':male_sign:': { uc_base: '2642', uc_full: '2642-fe0f', shortnames: [], category: 'symbols' }, + ':medical_symbol:': { uc_base: '2695', uc_full: '2695-fe0f', shortnames: [], category: 'symbols' }, + ':mountain:': { uc_base: '26f0', uc_full: '26f0-fe0f', shortnames: [], category: 'travel' }, + ':negative_squared_cross_mark:': { uc_base: '274e', uc_full: '274e', shortnames: [], category: 'symbols' }, + ':no_entry:': { uc_base: '26d4', uc_full: '26d4', shortnames: [], category: 'symbols' }, + ':o:': { uc_base: '2b55', uc_full: '2b55', shortnames: [], category: 'symbols' }, + ':ophiuchus:': { uc_base: '26ce', uc_full: '26ce', shortnames: [], category: 'symbols' }, + ':orthodox_cross:': { uc_base: '2626', uc_full: '2626-fe0f', shortnames: [], category: 'symbols' }, + ':part_alternation_mark:': { uc_base: '303d', uc_full: '303d-fe0f', shortnames: [], category: 'symbols' }, + ':partly_sunny:': { uc_base: '26c5', uc_full: '26c5', shortnames: [], category: 'nature' }, + ':pause_button:': { uc_base: '23f8', uc_full: '23f8-fe0f', shortnames: [':double_vertical_bar:'], category: 'symbols' }, + ':peace:': { uc_base: '262e', uc_full: '262e-fe0f', shortnames: [':peace_symbol:'], category: 'symbols' }, + ':pencil2:': { uc_base: '270f', uc_full: '270f-fe0f', shortnames: [], category: 'objects' }, + ':person_bouncing_ball:': { + uc_base: '26f9', + uc_full: '26f9', + shortnames: [':basketball_player:', ':person_with_ball:'], + category: 'activity', + }, + ':pick:': { uc_base: '26cf', uc_full: '26cf-fe0f', shortnames: [], category: 'objects' }, + ':pisces:': { uc_base: '2653', uc_full: '2653', shortnames: [], category: 'symbols' }, + ':play_pause:': { uc_base: '23ef', uc_full: '23ef-fe0f', shortnames: [], category: 'symbols' }, + ':point_up:': { uc_base: '261d', uc_full: '261d-fe0f', shortnames: [], category: 'people' }, + ':pound_symbol:': { uc_base: '0023', uc_full: '0023-fe0f', shortnames: [], category: 'symbols' }, + ':question:': { uc_base: '2753', uc_full: '2753', shortnames: [], category: 'symbols' }, + ':radioactive:': { uc_base: '2622', uc_full: '2622-fe0f', shortnames: [':radioactive_sign:'], category: 'symbols' }, + ':raised_hand:': { uc_base: '270b', uc_full: '270b', shortnames: [], category: 'people' }, + ':record_button:': { uc_base: '23fa', uc_full: '23fa-fe0f', shortnames: [], category: 'symbols' }, + ':recycle:': { uc_base: '267b', uc_full: '267b-fe0f', shortnames: [], category: 'symbols' }, + ':registered:': { uc_base: '00ae', uc_full: '00ae-fe0f', shortnames: [], category: 'symbols' }, + ':relaxed:': { uc_base: '263a', uc_full: '263a-fe0f', shortnames: [], category: 'people' }, + ':rewind:': { uc_base: '23ea', uc_full: '23ea', shortnames: [], category: 'symbols' }, + ':sagittarius:': { uc_base: '2650', uc_full: '2650', shortnames: [], category: 'symbols' }, + ':sailboat:': { uc_base: '26f5', uc_full: '26f5', shortnames: [], category: 'travel' }, + ':scales:': { uc_base: '2696', uc_full: '2696-fe0f', shortnames: [], category: 'objects' }, + ':scissors:': { uc_base: '2702', uc_full: '2702-fe0f', shortnames: [], category: 'objects' }, + ':scorpius:': { uc_base: '264f', uc_full: '264f', shortnames: [], category: 'symbols' }, + ':secret:': { uc_base: '3299', uc_full: '3299-fe0f', shortnames: [], category: 'symbols' }, + ':shamrock:': { uc_base: '2618', uc_full: '2618-fe0f', shortnames: [], category: 'nature' }, + ':shinto_shrine:': { uc_base: '26e9', uc_full: '26e9-fe0f', shortnames: [], category: 'travel' }, + ':skier:': { uc_base: '26f7', uc_full: '26f7-fe0f', shortnames: [], category: 'activity' }, + ':skull_crossbones:': { uc_base: '2620', uc_full: '2620-fe0f', shortnames: [':skull_and_crossbones:'], category: 'people' }, + ':snowflake:': { uc_base: '2744', uc_full: '2744-fe0f', shortnames: [], category: 'nature' }, + ':snowman2:': { uc_base: '2603', uc_full: '2603-fe0f', shortnames: [], category: 'nature' }, + ':snowman:': { uc_base: '26c4', uc_full: '26c4', shortnames: [], category: 'nature' }, + ':soccer:': { uc_base: '26bd', uc_full: '26bd', shortnames: [], category: 'activity' }, + ':spades:': { uc_base: '2660', uc_full: '2660-fe0f', shortnames: [], category: 'symbols' }, + ':sparkle:': { uc_base: '2747', uc_full: '2747-fe0f', shortnames: [], category: 'symbols' }, + ':sparkles:': { uc_base: '2728', uc_full: '2728', shortnames: [], category: 'nature' }, + ':star:': { uc_base: '2b50', uc_full: '2b50', shortnames: [], category: 'nature' }, + ':star_and_crescent:': { uc_base: '262a', uc_full: '262a-fe0f', shortnames: [], category: 'symbols' }, + ':star_of_david:': { uc_base: '2721', uc_full: '2721-fe0f', shortnames: [], category: 'symbols' }, + ':stop_button:': { uc_base: '23f9', uc_full: '23f9-fe0f', shortnames: [], category: 'symbols' }, + ':stopwatch:': { uc_base: '23f1', uc_full: '23f1-fe0f', shortnames: [], category: 'objects' }, + ':sunny:': { uc_base: '2600', uc_full: '2600-fe0f', shortnames: [], category: 'nature' }, + ':taurus:': { uc_base: '2649', uc_full: '2649', shortnames: [], category: 'symbols' }, + ':telephone:': { uc_base: '260e', uc_full: '260e-fe0f', shortnames: [], category: 'objects' }, + ':tent:': { uc_base: '26fa', uc_full: '26fa', shortnames: [], category: 'travel' }, + ':thunder_cloud_rain:': { uc_base: '26c8', uc_full: '26c8-fe0f', shortnames: [':thunder_cloud_and_rain:'], category: 'nature' }, + ':timer:': { uc_base: '23f2', uc_full: '23f2-fe0f', shortnames: [':timer_clock:'], category: 'objects' }, + ':tm:': { uc_base: '2122', uc_full: '2122-fe0f', shortnames: [], category: 'symbols' }, + ':track_next:': { uc_base: '23ed', uc_full: '23ed-fe0f', shortnames: [':next_track:'], category: 'symbols' }, + ':track_previous:': { uc_base: '23ee', uc_full: '23ee-fe0f', shortnames: [':previous_track:'], category: 'symbols' }, + ':transgender_symbol:': { uc_base: '26a7', uc_full: '26a7', shortnames: [], category: 'symbols' }, + ':umbrella2:': { uc_base: '2602', uc_full: '2602-fe0f', shortnames: [], category: 'nature' }, + ':umbrella:': { uc_base: '2614', uc_full: '2614', shortnames: [], category: 'nature' }, + ':urn:': { uc_base: '26b1', uc_full: '26b1-fe0f', shortnames: [':funeral_urn:'], category: 'objects' }, + ':v:': { uc_base: '270c', uc_full: '270c-fe0f', shortnames: [], category: 'people' }, + ':virgo:': { uc_base: '264d', uc_full: '264d', shortnames: [], category: 'symbols' }, + ':warning:': { uc_base: '26a0', uc_full: '26a0-fe0f', shortnames: [], category: 'symbols' }, + ':watch:': { uc_base: '231a', uc_full: '231a', shortnames: [], category: 'objects' }, + ':wavy_dash:': { uc_base: '3030', uc_full: '3030-fe0f', shortnames: [], category: 'symbols' }, + ':wheel_of_dharma:': { uc_base: '2638', uc_full: '2638-fe0f', shortnames: [], category: 'symbols' }, + ':wheelchair:': { uc_base: '267f', uc_full: '267f', shortnames: [], category: 'symbols' }, + ':white_check_mark:': { uc_base: '2705', uc_full: '2705', shortnames: [], category: 'symbols' }, + ':white_circle:': { uc_base: '26aa', uc_full: '26aa', shortnames: [], category: 'symbols' }, + ':white_large_square:': { uc_base: '2b1c', uc_full: '2b1c', shortnames: [], category: 'symbols' }, + ':white_medium_small_square:': { uc_base: '25fd', uc_full: '25fd', shortnames: [], category: 'symbols' }, + ':white_medium_square:': { uc_base: '25fb', uc_full: '25fb-fe0f', shortnames: [], category: 'symbols' }, + ':white_small_square:': { uc_base: '25ab', uc_full: '25ab-fe0f', shortnames: [], category: 'symbols' }, + ':writing_hand:': { uc_base: '270d', uc_full: '270d-fe0f', shortnames: [], category: 'people' }, + ':x:': { uc_base: '274c', uc_full: '274c', shortnames: [], category: 'symbols' }, + ':yin_yang:': { uc_base: '262f', uc_full: '262f-fe0f', shortnames: [], category: 'symbols' }, + ':zap:': { uc_base: '26a1', uc_full: '26a1', shortnames: [], category: 'nature' }, + }), + (ns.asciiList = { + '*\\0/*': '1f646', + '*\\O/*': '1f646', + '-___-': '1f611', + ":'-)": '1f602', + "':-)": '1f605', + "':-D": '1f605', + '>:-)': '1f606', + "':-(": '1f613', + '>:-(': '1f620', + ":'-(": '1f622', + 'O:-)': '1f607', + '0:-3': '1f607', + '0:-)': '1f607', + '0;^)': '1f607', + 'O;-)': '1f607', + '0;-)': '1f607', + 'O:-3': '1f607', + '-__-': '1f611', + ':-\xde': '1f61b', + '</3': '1f494', + ":')": '1f602', + ':-D': '1f603', + "':)": '1f605', + "'=)": '1f605', + "':D": '1f605', + "'=D": '1f605', + '>:)': '1f606', + '>;)': '1f606', + '>=)': '1f606', + ';-)': '1f609', + '*-)': '1f609', + ';-]': '1f609', + ';^)': '1f609', + "':(": '1f613', + "'=(": '1f613', + ':-*': '1f618', + ':^*': '1f618', + '>:P': '1f61c', + 'X-P': '1f61c', + '>:[': '1f61e', + ':-(': '1f61e', + ':-[': '1f61e', + '>:(': '1f620', + ":'(": '1f622', + ';-(': '1f622', + '>.<': '1f623', + '#-)': '1f635', + '%-)': '1f635', + 'X-)': '1f635', + '\\0/': '1f646', + '\\O/': '1f646', + '0:3': '1f607', + '0:)': '1f607', + 'O:)': '1f607', + 'O=)': '1f607', + 'O:3': '1f607', + 'B-)': '1f60e', + '8-)': '1f60e', + 'B-D': '1f60e', + '8-D': '1f60e', + '-_-': '1f611', + '>:\\': '1f615', + '>:/': '1f615', + ':-/': '1f615', + ':-.': '1f615', + ':-P': '1f61b', + ':\xde': '1f61b', + ':-b': '1f61b', + ':-O': '1f62e', + O_O: '1f62e', + '>:O': '1f62e', + ':-X': '1f636', + ':-#': '1f636', + ':-)': '1f642', + '(y)': '1f44d', + '<3': '2764-fe0f', + '=D': '1f603', + ';)': '1f609', + '*)': '1f609', + ';]': '1f609', + ';D': '1f609', + ':*': '1f618', + '=*': '1f618', + ':(': '1f61e', + ':[': '1f61e', + '=(': '1f61e', + ':@': '1f620', + ';(': '1f622', + 'D:': '1f628', + ':$': '1f633', + '=$': '1f633', + '#)': '1f635', + '%)': '1f635', + 'X)': '1f635', + 'B)': '1f60e', + '8)': '1f60e', + ':/': '1f615', + ':\\': '1f615', + '=/': '1f615', + '=\\': '1f615', + ':L': '1f615', + '=L': '1f615', + ':P': '1f61b', + '=P': '1f61b', + ':b': '1f61b', + ':O': '1f62e', + ':X': '1f636', + ':#': '1f636', + '=X': '1f636', + '=#': '1f636', + ':)': '1f642', + '=]': '1f642', + '=)': '1f642', + ':]': '1f642', + ':D': '1f604', + }), + (ns.asciiRegexp = + "(\\*\\\\0\\/\\*|\\*\\\\O\\/\\*|\\-___\\-|\\:'\\-\\)|'\\:\\-\\)|'\\:\\-D|\\>\\:\\-\\)|>\\:\\-\\)|'\\:\\-\\(|\\>\\:\\-\\(|>\\:\\-\\(|\\:'\\-\\(|O\\:\\-\\)|0\\:\\-3|0\\:\\-\\)|0;\\^\\)|O;\\-\\)|0;\\-\\)|O\\:\\-3|\\-__\\-|\\:\\-\xde|\\:\\-\xde|\\<\\/3|<\\/3|\\:'\\)|\\:\\-D|'\\:\\)|'\\=\\)|'\\:D|'\\=D|\\>\\:\\)|>\\:\\)|\\>;\\)|>;\\)|\\>\\=\\)|>\\=\\)|;\\-\\)|\\*\\-\\)|;\\-\\]|;\\^\\)|'\\:\\(|'\\=\\(|\\:\\-\\*|\\:\\^\\*|\\>\\:P|>\\:P|X\\-P|\\>\\:\\[|>\\:\\[|\\:\\-\\(|\\:\\-\\[|\\>\\:\\(|>\\:\\(|\\:'\\(|;\\-\\(|\\>\\.\\<|>\\.<|#\\-\\)|%\\-\\)|X\\-\\)|\\\\0\\/|\\\\O\\/|0\\:3|0\\:\\)|O\\:\\)|O\\=\\)|O\\:3|B\\-\\)|8\\-\\)|B\\-D|8\\-D|\\-_\\-|\\>\\:\\\\|>\\:\\\\|\\>\\:\\/|>\\:\\/|\\:\\-\\/|\\:\\-\\.|\\:\\-P|\\:\xde|\\:\xde|\\:\\-b|\\:\\-O|O_O|\\>\\:O|>\\:O|\\:\\-X|\\:\\-#|\\:\\-\\)|\\(y\\)|\\<3|<3|\\=D|;\\)|\\*\\)|;\\]|;D|\\:\\*|\\=\\*|\\:\\(|\\:\\[|\\=\\(|\\:@|;\\(|D\\:|\\:\\$|\\=\\$|#\\)|%\\)|X\\)|B\\)|8\\)|\\:\\/|\\:\\\\|\\=\\/|\\=\\\\|\\:L|\\=L|\\:P|\\=P|\\:b|\\:O|\\:X|\\:#|\\=X|\\=#|\\:\\)|\\=\\]|\\=\\)|\\:\\]|\\:D)"), + (ns.emojiVersion = '6.5'), + (ns.emojiSize = '32'), + (ns.blacklistChars = ''), + (ns.imagePathPNG = 'https://cdn.jsdelivr.net/joypixels/assets/' + ns.emojiVersion + '/png/unicode/'), + (ns.defaultPathPNG = ns.imagePathPNG), + (ns.fileExtension = '.png'), + (ns.imageTitleTag = !0), + (ns.sprites = !1), + (ns.unicodeAlt = !0), + (ns.ascii = !1), + (ns.riskyMatchAscii = !1), + (ns.regAscii = new RegExp( + '<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|((\\s|^)' + + ns.asciiRegexp + + '(?=\\s|$|[!,.?]))', + 'gi' + )), + (ns.regAsciiRisky = new RegExp( + '<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|(()' + ns.asciiRegexp + '())', + 'gi' + )), + (ns.regUnicode = new RegExp( + '<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|(?:[\u1f91D[\u1f3fB-\u1f3fF]\u200d\u1f9f1\u200d\u1f91D[\u1f3fB-\u1f3fF]])|(?:\ud83c\udff3)\ufe0f?\u200d?(?:\ud83c\udf08)|(?:\ud83d\udc41)\ufe0f?\u200d?(?:\ud83d\udde8)\ufe0f?|[#-9]\ufe0f?\u20e3|(?:(?:\ud83c\udff4)(?:\udb40[\udc60-\udcff]){1,6})|(?:\ud83c[\udde0-\uddff]){2}|(?:\ud83d[\udc68\udc69])\ufe0f?(?:\ud83c[\udffa-\udfff])?\u200d?(?:[\u2695\u2696\u2708]|\ud83c[\udf3e-\udfed]|\ud83d[\udcbb\udcbc\udd27\udd2c\ude80\ude92])|(?:\ud83d[\udc68\udc69]|\ud83e[\uddd0-\udddf])(?:\ud83c[\udffa-\udfff])?\u200d?[\u2640\u2642\u2695\u2696\u2708]?\ufe0f?|(?:(?:\u2764|\ud83d[\udc66-\udc69\udc8b])[\u200d\ufe0f]{0,2}){1,3}(?:\u2764|\ud83d[\udc66-\udc69\udc8b])|(?:(?:\u2764|\ud83d[\udc66-\udc69\udc8b])\ufe0f?){2,4}|(?:\ud83d[\udc68\udc69\udc6e\udc71-\udc87\udd75\ude45-\ude4e]|\ud83e[\udd26\udd37]|\ud83c[\udfc3-\udfcc]|\ud83e[\udd38-\udd3e]|\ud83d[\udea3-\udeb6]|\u26f9|\ud83d\udc6f)\ufe0f?(?:\ud83c[\udffb-\udfff])?\u200d?[\u2640\u2642]?\ufe0f?|(?:[\u261d\u26f9\u270a-\u270d]|\ud83c[\udf85-\udfcc]|\ud83d[\udc42-\udcaa\udd74-\udd96\ude45-\ude4f\udea3-\udecc]|\ud83e[\udd18-\udd3e])\ufe0f?(?:\ud83c[\udffb-\udfff])|(?:[\u2194-\u2199\u21a9-\u21aa]\ufe0f?|[#*]|[\u3030\u303d]\ufe0f?|(?:\ud83c[\udd70-\udd71]|\ud83c\udd8e|\ud83c[\udd91-\udd9a])\ufe0f?|\u24c2\ufe0f?|[\u3297\u3299]\ufe0f?|(?:\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|\ud83c[\ude32-\ude3a]|\ud83c[\ude50-\ude51])\ufe0f?|[\u203c\u2049]\ufe0f?|[\u25aa-\u25ab\u25b6\u25c0\u25fb-\u25fe]\ufe0f?|[\xa9\xae]\ufe0f?|[\u2122\u2139]\ufe0f?|\ud83c\udc04\ufe0f?|[\u2b05-\u2b07\u2b1b-\u2b1c\u2b50\u2b55]\ufe0f?|[\u231a-\u231b\u2328\u23cf\u23e9-\u23f3\u23f8-\u23fa]\ufe0f?|\ud83c\udccf|[\u2934\u2935]\ufe0f?)|[\u2700-\u27bf]\ufe0f?|[\ud800-\udbff][\udc00-\udfff]\ufe0f?|[\u2600-\u26ff]\ufe0f?|[0-9]\ufe0f', + 'g' + )), + (ns.convert = function (unicode) { + if (unicode.indexOf('-') > -1) { + for (var parts = [], s = unicode.split('-'), i = 0; i < s.length; i++) { + var part = parseInt(s[i], 16); + if (part >= 65536 && 1114111 >= part) { + var hi = Math.floor((part - 65536) / 1024) + 55296, + lo = ((part - 65536) % 1024) + 56320; + part = String.fromCharCode(hi) + String.fromCharCode(lo); + } else part = String.fromCharCode(part); + parts.push(part); + } + return parts.join(''); + } + var s = parseInt(unicode, 16); + if (s >= 65536 && 1114111 >= s) { + var hi = Math.floor((s - 65536) / 1024) + 55296, + lo = ((s - 65536) % 1024) + 56320; + return String.fromCharCode(hi) + String.fromCharCode(lo); + } + return String.fromCharCode(s); + }), + (ns.shortnameLookup = []), + (ns.altShortNames = []), + (ns.unicodeCharRegexCached = null); + var emoji, + tmpShortNames = []; + for (emoji in ns.emojiList) + if (ns.emojiList.hasOwnProperty(emoji) || '' === emoji) { + tmpShortNames.push(emoji.replace(/[+]/g, '\\$&')); + var cp = ns.convert(ns.emojiList[emoji].uc_full), + i = 0; + for (ns.shortnameLookup[cp] = emoji.replace(/[+]/g, '\\$&'), i = 0; i < ns.emojiList[emoji].shortnames.length; i++) + tmpShortNames.push(ns.emojiList[emoji].shortnames[i].replace(/[+]/g, '\\$&')), + (ns.altShortNames[ns.emojiList[emoji].shortnames[i]] = emoji); + } + (ns.shortnames = tmpShortNames.join('|')), + (ns.regShortNames = new RegExp( + '<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|(' + ns.shortnames + ')', + 'gi' + )), + (ns.init = function () { + ns.unicodeCharRegex(); + }), + (ns.toImage = function (str) { + return (str = ns.toShort(str)), (str = ns.shortnameToImage(str)); + }), + (ns.unicodeToImage = function (str) { + return str; + }), + (ns.unifyUnicode = function (str) { + return (str = ns.toShort(str)), (str = ns.shortnameToUnicode(str)); + }), + (ns.shortnameToAscii = function (str) { + var unicode, + unicodeToAscii = ns.objectFlip(ns.asciiList); + return (str = str.replace(ns.regShortNames, function (shortname) { + return 'undefined' != typeof shortname && '' !== shortname && shortname in ns.emojiList + ? ((unicode = ns.emojiList[shortname].uc_full), + 'undefined' != typeof unicodeToAscii[unicode] ? unicodeToAscii[unicode] : shortname) + : shortname; + })); + }), + (ns.shortnameToUnicode = function (str) { + var unicode, fname; + if ( + ((str = str.replace(ns.regShortNames, function (shortname) { + if ('undefined' == typeof shortname || '' === shortname) return shortname; + if (!(shortname in ns.emojiList)) { + if (!(shortname in ns.altShortNames)) return shortname; + shortname = ns.altShortNames[shortname]; + } + return (unicode = ns.emojiList[shortname].uc_full.toUpperCase()), (fname = ns.emojiList[shortname].uc_base), ns.convert(unicode); + })), + ns.ascii) + ) { + var asciiRX = ns.riskyMatchAscii ? ns.regAsciiRisky : ns.regAscii; + str = str.replace(asciiRX, function (entire, m1, m2, m3) { + return 'undefined' != typeof m3 && '' !== m3 && ns.unescapeHTML(m3) in ns.asciiList + ? ((m3 = ns.unescapeHTML(m3)), (unicode = ns.asciiList[m3].toUpperCase()), m2 + ns.convert(unicode)) + : entire; + }); + } + return str; + }), + (ns.shortnameToImage = function (str) { + var replaceWith, shortname, unicode, fname, alt, category, title, size, ePath; + if ( + ((str = str.replace(ns.regShortNames, function (shortname) { + if ('undefined' == typeof shortname || '' === shortname) return shortname; + if (!(shortname in ns.emojiList)) { + if (!(shortname in ns.altShortNames)) return shortname; + shortname = ns.altShortNames[shortname]; + } + return ( + (unicode = ns.emojiList[shortname].uc_full), + (fname = ns.emojiList[shortname].uc_base), + (category = fname.indexOf('-1f3f') >= 0 ? 'diversity' : ns.emojiList[shortname].category), + (title = ns.imageTitleTag ? 'title="' + shortname + '"' : ''), + (size = '32' == ns.spriteSize || '64' == ns.spriteSize ? ns.spriteSize : '32'), + (ePath = ns.defaultPathPNG !== ns.imagePathPNG ? ns.imagePathPNG : ns.defaultPathPNG + ns.emojiSize + '/'), + (alt = ns.unicodeAlt ? ns.convert(unicode.toUpperCase()) : shortname), + (replaceWith = ns.sprites + ? '<span class="joypixels joypixels-' + size + '-' + category + ' _' + fname + '" ' + title + '>' + alt + '</span>' + : '<img class="joypixels" alt="' + alt + '" ' + title + ' src="' + ePath + fname + ns.fileExtension + '"/>') + ); + })), + ns.ascii) + ) { + var asciiRX = ns.riskyMatchAscii ? ns.regAsciiRisky : ns.regAscii; + str = str.replace(asciiRX, function (entire, m1, m2, m3) { + if ('undefined' == typeof m3 || '' === m3 || !(ns.unescapeHTML(m3) in ns.asciiList)) return entire; + (m3 = ns.unescapeHTML(m3)), (unicode = ns.asciiList[m3]); + var mappedUnicode = ns.mapUnicodeToShort(); + return ( + (shortname = mappedUnicode[unicode]), + (category = unicode.indexOf('-1f3f') >= 0 ? 'diversity' : ns.emojiList[shortname].category), + (title = ns.imageTitleTag ? 'title="' + ns.escapeHTML(m3) + '"' : ''), + (size = '32' == ns.spriteSize || '64' == ns.spriteSize ? ns.spriteSize : '32'), + (ePath = ns.defaultPathPNG !== ns.imagePathPNG ? ns.imagePathPNG : ns.defaultPathPNG + ns.emojiSize + '/'), + (alt = ns.unicodeAlt ? ns.convert(unicode.toUpperCase()) : ns.escapeHTML(m3)), + (unicode = unicode.replace('-fe0f', '')), + (replaceWith = ns.sprites + ? m2 + '<span class="joypixels joypixels-' + size + '-' + category + ' _' + unicode + '" ' + title + '>' + alt + '</span>' + : m2 + '<img class="joypixels" alt="' + alt + '" ' + title + ' src="' + ePath + unicode + ns.fileExtension + '"/>') + ); + }); + } + return str; + }), + (ns.toShort = function (str) { + var find = ns.unicodeCharRegex(); + return (str = ns.replaceAll(str, find)); + }), + (ns.escapeHTML = function (string) { + var escaped = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; + return string.replace(/[&<>"']/g, function (match) { + return escaped[match]; + }); + }), + (ns.unescapeHTML = function (string) { + var unescaped = { + '&': '&', + '&': '&', + '&': '&', + '<': '<', + '<': '<', + '<': '<', + '>': '>', + '>': '>', + '>': '>', + '"': '"', + '"': '"', + '"': '"', + ''': "'", + ''': "'", + ''': "'", + }; + return string.replace(/&(?:amp|#38|#x26|lt|#60|#x3C|gt|#62|#x3E|apos|#39|#x27|quot|#34|#x22);/gi, function (match) { + return unescaped[match]; + }); + }), + (ns.shortnameConversionMap = function () { + var emoji, + map = []; + for (emoji in ns.emojiList) + ns.emojiList.hasOwnProperty(emoji) && '' !== emoji && (map[ns.convert(ns.emojiList[emoji].uc_full)] = emoji); + return map; + }), + (ns.unicodeCharRegex = function () { + if (!ns.unicodeCharRegexCached) { + var map = []; + for (emoji in ns.emojiList) ns.emojiList.hasOwnProperty(emoji) && '' !== emoji && map.push(ns.convert(ns.emojiList[emoji].uc_full)); + ns.unicodeCharRegexCached = map.join('|'); + } + return ns.unicodeCharRegexCached; + }), + (ns.mapEmojiList = function (addToMapStorage) { + for (var shortname in ns.emojiList) + if (ns.emojiList.hasOwnProperty(shortname)) { + var unicode = ns.emojiList[shortname].uc_full; + addToMapStorage(unicode, shortname); + } + }), + (ns.mapUnicodeToShort = function () { + return ( + ns.memMapShortToUnicode || + ((ns.memMapShortToUnicode = {}), + ns.mapEmojiList(function (unicode, shortname) { + ns.memMapShortToUnicode[unicode] = shortname; + })), + ns.memMapShortToUnicode + ); + }), + (ns.memorizeReplacement = function () { + if (!ns.unicodeReplacementRegEx || !ns.memMapShortToUnicodeCharacters) { + var unicodeList = []; + (ns.memMapShortToUnicodeCharacters = {}), + ns.mapEmojiList(function (unicode, shortname) { + var emojiCharacter = ns.convert(unicode); + (ns.memMapShortToUnicodeCharacters[emojiCharacter] = shortname), unicodeList.push(emojiCharacter); + }), + (ns.unicodeReplacementRegEx = unicodeList.join('|')); + } + }), + (ns.mapUnicodeCharactersToShort = function () { + return ns.memorizeReplacement(), ns.memMapShortToUnicodeCharacters; + }), + (ns.objectFlip = function (obj) { + var key, + tmp_obj = {}; + for (key in obj) obj.hasOwnProperty(key) && (tmp_obj[obj[key]] = key); + return tmp_obj; + }), + (ns.escapeRegExp = function (string) { + return string.replace(/[-[\]{}()*+?.,;:&\\^$#\s]/g, '\\$&'); + }), + (ns.replaceAll = function (string, find) { + var escapedFind = ns.escapeRegExp(find), + search = new RegExp( + '<object[^>]*>.*?</object>|<span[^>]*>.*?</span>|<(?:object|embed|svg|img|div|span|p|a)[^>]*>|(' + escapedFind + ')', + 'gi' + ), + replace = function (entire, m1) { + return 'undefined' == typeof m1 || '' === m1 ? entire : ns.shortnameLookup[m1]; + }; + return string.replace(search, replace); + }); +})((this.joypixels = this.joypixels || {})), + 'object' == typeof module && (module.exports = this.joypixels); diff --git a/src/main/webapp/content/js/duplicate/katex.min.js b/src/main/webapp/content/js/duplicate/katex.min.js index 4df7e1722c77d3e751aebc86a2affca085f16d78..f07b1d30eb631c44f263c23cc8edae7bd6d01d0c 100644 --- a/src/main/webapp/content/js/duplicate/katex.min.js +++ b/src/main/webapp/content/js/duplicate/katex.min.js @@ -1 +1,9572 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.katex=e():t.katex=e()}("undefined"!=typeof self?self:this,function(){return function(t){var e={};function r(a){if(e[a])return e[a].exports;var n=e[a]={i:a,l:!1,exports:{}};return t[a].call(n.exports,n,n.exports,r),n.l=!0,n.exports}return r.m=t,r.c=e,r.d=function(t,e,a){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:a})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var a=Object.create(null);if(r.r(a),Object.defineProperty(a,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var n in t)r.d(a,n,function(e){return t[e]}.bind(null,n));return a},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=1)}([function(t,e,r){},function(t,e,r){"use strict";r.r(e);r(0);var a=function(){function t(t,e,r){this.lexer=void 0,this.start=void 0,this.end=void 0,this.lexer=t,this.start=e,this.end=r}return t.range=function(e,r){return r?e&&e.loc&&r.loc&&e.loc.lexer===r.loc.lexer?new t(e.loc.lexer,e.loc.start,r.loc.end):null:e&&e.loc},t}(),n=function(){function t(t,e){this.text=void 0,this.loc=void 0,this.noexpand=void 0,this.treatAsRelax=void 0,this.text=t,this.loc=e}return t.prototype.range=function(e,r){return new t(r,a.range(this,e))},t}(),i=function t(e,r){this.position=void 0;var a,n="KaTeX parse error: "+e,i=r&&r.loc;if(i&&i.start<=i.end){var o=i.lexer.input;a=i.start;var s=i.end;a===o.length?n+=" at end of input: ":n+=" at position "+(a+1)+": ";var l=o.slice(a,s).replace(/[^]/g,"$&\u0332");n+=(a>15?"\u2026"+o.slice(a-15,a):o.slice(0,a))+l+(s+15<o.length?o.slice(s,s+15)+"\u2026":o.slice(s))}var h=new Error(n);return h.name="ParseError",h.__proto__=t.prototype,h.position=a,h};i.prototype.__proto__=Error.prototype;var o=i,s=/([A-Z])/g,l={"&":"&",">":">","<":"<",'"':""","'":"'"},h=/[&><"']/g;var m=function t(e){return"ordgroup"===e.type?1===e.body.length?t(e.body[0]):e:"color"===e.type?1===e.body.length?t(e.body[0]):e:"font"===e.type?t(e.body):e},c={contains:function(t,e){return-1!==t.indexOf(e)},deflt:function(t,e){return void 0===t?e:t},escape:function(t){return String(t).replace(h,function(t){return l[t]})},hyphenate:function(t){return t.replace(s,"-$1").toLowerCase()},getBaseElem:m,isCharacterBox:function(t){var e=m(t);return"mathord"===e.type||"textord"===e.type||"atom"===e.type},protocolFromUrl:function(t){var e=/^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(t);return null!=e?e[1]:"_relative"}},u=function(){function t(t){this.displayMode=void 0,this.output=void 0,this.leqno=void 0,this.fleqn=void 0,this.throwOnError=void 0,this.errorColor=void 0,this.macros=void 0,this.minRuleThickness=void 0,this.colorIsTextColor=void 0,this.strict=void 0,this.trust=void 0,this.maxSize=void 0,this.maxExpand=void 0,this.globalGroup=void 0,t=t||{},this.displayMode=c.deflt(t.displayMode,!1),this.output=c.deflt(t.output,"htmlAndMathml"),this.leqno=c.deflt(t.leqno,!1),this.fleqn=c.deflt(t.fleqn,!1),this.throwOnError=c.deflt(t.throwOnError,!0),this.errorColor=c.deflt(t.errorColor,"#cc0000"),this.macros=t.macros||{},this.minRuleThickness=Math.max(0,c.deflt(t.minRuleThickness,0)),this.colorIsTextColor=c.deflt(t.colorIsTextColor,!1),this.strict=c.deflt(t.strict,"warn"),this.trust=c.deflt(t.trust,!1),this.maxSize=Math.max(0,c.deflt(t.maxSize,1/0)),this.maxExpand=Math.max(0,c.deflt(t.maxExpand,1e3)),this.globalGroup=c.deflt(t.globalGroup,!1)}var e=t.prototype;return e.reportNonstrict=function(t,e,r){var a=this.strict;if("function"==typeof a&&(a=a(t,e,r)),a&&"ignore"!==a){if(!0===a||"error"===a)throw new o("LaTeX-incompatible input and strict mode is set to 'error': "+e+" ["+t+"]",r);"warn"===a?"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+e+" ["+t+"]"):"undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+e+" ["+t+"]")}},e.useStrictBehavior=function(t,e,r){var a=this.strict;if("function"==typeof a)try{a=a(t,e,r)}catch(t){a="error"}return!(!a||"ignore"===a)&&(!0===a||"error"===a||("warn"===a?("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to 'warn': "+e+" ["+t+"]"),!1):("undefined"!=typeof console&&console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '"+a+"': "+e+" ["+t+"]"),!1)))},e.isTrusted=function(t){t.url&&!t.protocol&&(t.protocol=c.protocolFromUrl(t.url));var e="function"==typeof this.trust?this.trust(t):this.trust;return Boolean(e)},t}(),p=function(){function t(t,e,r){this.id=void 0,this.size=void 0,this.cramped=void 0,this.id=t,this.size=e,this.cramped=r}var e=t.prototype;return e.sup=function(){return d[f[this.id]]},e.sub=function(){return d[g[this.id]]},e.fracNum=function(){return d[x[this.id]]},e.fracDen=function(){return d[v[this.id]]},e.cramp=function(){return d[b[this.id]]},e.text=function(){return d[y[this.id]]},e.isTight=function(){return this.size>=2},t}(),d=[new p(0,0,!1),new p(1,0,!0),new p(2,1,!1),new p(3,1,!0),new p(4,2,!1),new p(5,2,!0),new p(6,3,!1),new p(7,3,!0)],f=[4,5,4,5,6,7,6,7],g=[5,5,5,5,7,7,7,7],x=[2,3,4,5,6,7,6,7],v=[3,3,5,5,7,7,7,7],b=[1,1,3,3,5,5,7,7],y=[0,1,2,3,2,3,2,3],w={DISPLAY:d[0],TEXT:d[2],SCRIPT:d[4],SCRIPTSCRIPT:d[6]},k=[{name:"latin",blocks:[[256,591],[768,879]]},{name:"cyrillic",blocks:[[1024,1279]]},{name:"brahmic",blocks:[[2304,4255]]},{name:"georgian",blocks:[[4256,4351]]},{name:"cjk",blocks:[[12288,12543],[19968,40879],[65280,65376]]},{name:"hangul",blocks:[[44032,55215]]}];var S=[];function M(t){for(var e=0;e<S.length;e+=2)if(t>=S[e]&&t<=S[e+1])return!0;return!1}k.forEach(function(t){return t.blocks.forEach(function(t){return S.push.apply(S,t)})});var z={leftParenInner:"M291 0 H417 V300 H291 z",rightParenInner:"M457 0 H583 V300 H457 z",doubleleftarrow:"M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z",doublerightarrow:"M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z",leftarrow:"M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z",leftbrace:"M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z",leftbraceunder:"M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z",leftgroup:"M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z",leftgroupunder:"M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z",leftharpoon:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z",leftharpoonplus:"M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z",leftharpoondown:"M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z",leftharpoondownplus:"M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z",lefthook:"M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z",leftlinesegment:"M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z",leftmapsto:"M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z",leftToFrom:"M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z",longequal:"M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z",midbrace:"M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z",midbraceunder:"M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z",oiintSize1:"M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z",oiintSize2:"M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z",oiiintSize1:"M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z",oiiintSize2:"M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z",rightarrow:"M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z",rightbrace:"M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z",rightbraceunder:"M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z",rightgroup:"M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z",rightgroupunder:"M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z",rightharpoon:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z",rightharpoonplus:"M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z",rightharpoondown:"M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z",rightharpoondownplus:"M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z",righthook:"M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z",rightlinesegment:"M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z",rightToFrom:"M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z",twoheadleftarrow:"M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z",twoheadrightarrow:"M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z",tilde1:"M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z",tilde2:"M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z",tilde3:"M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z",tilde4:"M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z",vec:"M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z",widehat1:"M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z",widehat2:"M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat3:"M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widehat4:"M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z",widecheck1:"M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z",widecheck2:"M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck3:"M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",widecheck4:"M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z",baraboveleftarrow:"M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z",rightarrowabovebar:"M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z",baraboveshortleftharpoon:"M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z",rightharpoonaboveshortbar:"M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z",shortbaraboveleftharpoon:"M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z",shortrightharpoonabovebar:"M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z"},A=function(){function t(t){this.children=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.children=t,this.classes=[],this.height=0,this.depth=0,this.maxFontSize=0,this.style={}}var e=t.prototype;return e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){for(var t=document.createDocumentFragment(),e=0;e<this.children.length;e++)t.appendChild(this.children[e].toNode());return t},e.toMarkup=function(){for(var t="",e=0;e<this.children.length;e++)t+=this.children[e].toMarkup();return t},e.toText=function(){var t=function(t){return t.toText()};return this.children.map(t).join("")},t}(),T=function(t){return t.filter(function(t){return t}).join(" ")},B=function(t,e,r){if(this.classes=t||[],this.attributes={},this.height=0,this.depth=0,this.maxFontSize=0,this.style=r||{},e){e.style.isTight()&&this.classes.push("mtight");var a=e.getColor();a&&(this.style.color=a)}},C=function(t){var e=document.createElement(t);for(var r in e.className=T(this.classes),this.style)this.style.hasOwnProperty(r)&&(e.style[r]=this.style[r]);for(var a in this.attributes)this.attributes.hasOwnProperty(a)&&e.setAttribute(a,this.attributes[a]);for(var n=0;n<this.children.length;n++)e.appendChild(this.children[n].toNode());return e},q=function(t){var e="<"+t;this.classes.length&&(e+=' class="'+c.escape(T(this.classes))+'"');var r="";for(var a in this.style)this.style.hasOwnProperty(a)&&(r+=c.hyphenate(a)+":"+this.style[a]+";");for(var n in r&&(e+=' style="'+c.escape(r)+'"'),this.attributes)this.attributes.hasOwnProperty(n)&&(e+=" "+n+'="'+c.escape(this.attributes[n])+'"');e+=">";for(var i=0;i<this.children.length;i++)e+=this.children[i].toMarkup();return e+="</"+t+">"},N=function(){function t(t,e,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.width=void 0,this.maxFontSize=void 0,this.style=void 0,B.call(this,t,r,a),this.children=e||[]}var e=t.prototype;return e.setAttribute=function(t,e){this.attributes[t]=e},e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){return C.call(this,"span")},e.toMarkup=function(){return q.call(this,"span")},t}(),I=function(){function t(t,e,r,a){this.children=void 0,this.attributes=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,B.call(this,e,a),this.children=r||[],this.setAttribute("href",t)}var e=t.prototype;return e.setAttribute=function(t,e){this.attributes[t]=e},e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){return C.call(this,"a")},e.toMarkup=function(){return q.call(this,"a")},t}(),O=function(){function t(t,e,r){this.src=void 0,this.alt=void 0,this.classes=void 0,this.height=void 0,this.depth=void 0,this.maxFontSize=void 0,this.style=void 0,this.alt=e,this.src=t,this.classes=["mord"],this.style=r}var e=t.prototype;return e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){var t=document.createElement("img");for(var e in t.src=this.src,t.alt=this.alt,t.className="mord",this.style)this.style.hasOwnProperty(e)&&(t.style[e]=this.style[e]);return t},e.toMarkup=function(){var t="<img src='"+this.src+" 'alt='"+this.alt+"' ",e="";for(var r in this.style)this.style.hasOwnProperty(r)&&(e+=c.hyphenate(r)+":"+this.style[r]+";");return e&&(t+=' style="'+c.escape(e)+'"'),t+="'/>"},t}(),R={"\xee":"\u0131\u0302","\xef":"\u0131\u0308","\xed":"\u0131\u0301","\xec":"\u0131\u0300"},E=function(){function t(t,e,r,a,n,i,o,s){this.text=void 0,this.height=void 0,this.depth=void 0,this.italic=void 0,this.skew=void 0,this.width=void 0,this.maxFontSize=void 0,this.classes=void 0,this.style=void 0,this.text=t,this.height=e||0,this.depth=r||0,this.italic=a||0,this.skew=n||0,this.width=i||0,this.classes=o||[],this.style=s||{},this.maxFontSize=0;var l=function(t){for(var e=0;e<k.length;e++)for(var r=k[e],a=0;a<r.blocks.length;a++){var n=r.blocks[a];if(t>=n[0]&&t<=n[1])return r.name}return null}(this.text.charCodeAt(0));l&&this.classes.push(l+"_fallback"),/[\xee\xef\xed\xec]/.test(this.text)&&(this.text=R[this.text])}var e=t.prototype;return e.hasClass=function(t){return c.contains(this.classes,t)},e.toNode=function(){var t=document.createTextNode(this.text),e=null;for(var r in this.italic>0&&((e=document.createElement("span")).style.marginRight=this.italic+"em"),this.classes.length>0&&((e=e||document.createElement("span")).className=T(this.classes)),this.style)this.style.hasOwnProperty(r)&&((e=e||document.createElement("span")).style[r]=this.style[r]);return e?(e.appendChild(t),e):t},e.toMarkup=function(){var t=!1,e="<span";this.classes.length&&(t=!0,e+=' class="',e+=c.escape(T(this.classes)),e+='"');var r="";for(var a in this.italic>0&&(r+="margin-right:"+this.italic+"em;"),this.style)this.style.hasOwnProperty(a)&&(r+=c.hyphenate(a)+":"+this.style[a]+";");r&&(t=!0,e+=' style="'+c.escape(r)+'"');var n=c.escape(this.text);return t?(e+=">",e+=n,e+="</span>"):n},t}(),L=function(){function t(t,e){this.children=void 0,this.attributes=void 0,this.children=t||[],this.attributes=e||{}}var e=t.prototype;return e.toNode=function(){var t=document.createElementNS("http://www.w3.org/2000/svg","svg");for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&t.setAttribute(e,this.attributes[e]);for(var r=0;r<this.children.length;r++)t.appendChild(this.children[r].toNode());return t},e.toMarkup=function(){var t="<svg";for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&(t+=" "+e+"='"+this.attributes[e]+"'");t+=">";for(var r=0;r<this.children.length;r++)t+=this.children[r].toMarkup();return t+="</svg>"},t}(),P=function(){function t(t,e){this.pathName=void 0,this.alternate=void 0,this.pathName=t,this.alternate=e}var e=t.prototype;return e.toNode=function(){var t=document.createElementNS("http://www.w3.org/2000/svg","path");return this.alternate?t.setAttribute("d",this.alternate):t.setAttribute("d",z[this.pathName]),t},e.toMarkup=function(){return this.alternate?"<path d='"+this.alternate+"'/>":"<path d='"+z[this.pathName]+"'/>"},t}(),D=function(){function t(t){this.attributes=void 0,this.attributes=t||{}}var e=t.prototype;return e.toNode=function(){var t=document.createElementNS("http://www.w3.org/2000/svg","line");for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&t.setAttribute(e,this.attributes[e]);return t},e.toMarkup=function(){var t="<line";for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&(t+=" "+e+"='"+this.attributes[e]+"'");return t+="/>"},t}();function H(t){if(t instanceof E)return t;throw new Error("Expected symbolNode but got "+String(t)+".")}var F={"AMS-Regular":{32:[0,0,0,0,.25],65:[0,.68889,0,0,.72222],66:[0,.68889,0,0,.66667],67:[0,.68889,0,0,.72222],68:[0,.68889,0,0,.72222],69:[0,.68889,0,0,.66667],70:[0,.68889,0,0,.61111],71:[0,.68889,0,0,.77778],72:[0,.68889,0,0,.77778],73:[0,.68889,0,0,.38889],74:[.16667,.68889,0,0,.5],75:[0,.68889,0,0,.77778],76:[0,.68889,0,0,.66667],77:[0,.68889,0,0,.94445],78:[0,.68889,0,0,.72222],79:[.16667,.68889,0,0,.77778],80:[0,.68889,0,0,.61111],81:[.16667,.68889,0,0,.77778],82:[0,.68889,0,0,.72222],83:[0,.68889,0,0,.55556],84:[0,.68889,0,0,.66667],85:[0,.68889,0,0,.72222],86:[0,.68889,0,0,.72222],87:[0,.68889,0,0,1],88:[0,.68889,0,0,.72222],89:[0,.68889,0,0,.72222],90:[0,.68889,0,0,.66667],107:[0,.68889,0,0,.55556],160:[0,0,0,0,.25],165:[0,.675,.025,0,.75],174:[.15559,.69224,0,0,.94666],240:[0,.68889,0,0,.55556],295:[0,.68889,0,0,.54028],710:[0,.825,0,0,2.33334],732:[0,.9,0,0,2.33334],770:[0,.825,0,0,2.33334],771:[0,.9,0,0,2.33334],989:[.08167,.58167,0,0,.77778],1008:[0,.43056,.04028,0,.66667],8245:[0,.54986,0,0,.275],8463:[0,.68889,0,0,.54028],8487:[0,.68889,0,0,.72222],8498:[0,.68889,0,0,.55556],8502:[0,.68889,0,0,.66667],8503:[0,.68889,0,0,.44445],8504:[0,.68889,0,0,.66667],8513:[0,.68889,0,0,.63889],8592:[-.03598,.46402,0,0,.5],8594:[-.03598,.46402,0,0,.5],8602:[-.13313,.36687,0,0,1],8603:[-.13313,.36687,0,0,1],8606:[.01354,.52239,0,0,1],8608:[.01354,.52239,0,0,1],8610:[.01354,.52239,0,0,1.11111],8611:[.01354,.52239,0,0,1.11111],8619:[0,.54986,0,0,1],8620:[0,.54986,0,0,1],8621:[-.13313,.37788,0,0,1.38889],8622:[-.13313,.36687,0,0,1],8624:[0,.69224,0,0,.5],8625:[0,.69224,0,0,.5],8630:[0,.43056,0,0,1],8631:[0,.43056,0,0,1],8634:[.08198,.58198,0,0,.77778],8635:[.08198,.58198,0,0,.77778],8638:[.19444,.69224,0,0,.41667],8639:[.19444,.69224,0,0,.41667],8642:[.19444,.69224,0,0,.41667],8643:[.19444,.69224,0,0,.41667],8644:[.1808,.675,0,0,1],8646:[.1808,.675,0,0,1],8647:[.1808,.675,0,0,1],8648:[.19444,.69224,0,0,.83334],8649:[.1808,.675,0,0,1],8650:[.19444,.69224,0,0,.83334],8651:[.01354,.52239,0,0,1],8652:[.01354,.52239,0,0,1],8653:[-.13313,.36687,0,0,1],8654:[-.13313,.36687,0,0,1],8655:[-.13313,.36687,0,0,1],8666:[.13667,.63667,0,0,1],8667:[.13667,.63667,0,0,1],8669:[-.13313,.37788,0,0,1],8672:[-.064,.437,0,0,1.334],8674:[-.064,.437,0,0,1.334],8705:[0,.825,0,0,.5],8708:[0,.68889,0,0,.55556],8709:[.08167,.58167,0,0,.77778],8717:[0,.43056,0,0,.42917],8722:[-.03598,.46402,0,0,.5],8724:[.08198,.69224,0,0,.77778],8726:[.08167,.58167,0,0,.77778],8733:[0,.69224,0,0,.77778],8736:[0,.69224,0,0,.72222],8737:[0,.69224,0,0,.72222],8738:[.03517,.52239,0,0,.72222],8739:[.08167,.58167,0,0,.22222],8740:[.25142,.74111,0,0,.27778],8741:[.08167,.58167,0,0,.38889],8742:[.25142,.74111,0,0,.5],8756:[0,.69224,0,0,.66667],8757:[0,.69224,0,0,.66667],8764:[-.13313,.36687,0,0,.77778],8765:[-.13313,.37788,0,0,.77778],8769:[-.13313,.36687,0,0,.77778],8770:[-.03625,.46375,0,0,.77778],8774:[.30274,.79383,0,0,.77778],8776:[-.01688,.48312,0,0,.77778],8778:[.08167,.58167,0,0,.77778],8782:[.06062,.54986,0,0,.77778],8783:[.06062,.54986,0,0,.77778],8785:[.08198,.58198,0,0,.77778],8786:[.08198,.58198,0,0,.77778],8787:[.08198,.58198,0,0,.77778],8790:[0,.69224,0,0,.77778],8791:[.22958,.72958,0,0,.77778],8796:[.08198,.91667,0,0,.77778],8806:[.25583,.75583,0,0,.77778],8807:[.25583,.75583,0,0,.77778],8808:[.25142,.75726,0,0,.77778],8809:[.25142,.75726,0,0,.77778],8812:[.25583,.75583,0,0,.5],8814:[.20576,.70576,0,0,.77778],8815:[.20576,.70576,0,0,.77778],8816:[.30274,.79383,0,0,.77778],8817:[.30274,.79383,0,0,.77778],8818:[.22958,.72958,0,0,.77778],8819:[.22958,.72958,0,0,.77778],8822:[.1808,.675,0,0,.77778],8823:[.1808,.675,0,0,.77778],8828:[.13667,.63667,0,0,.77778],8829:[.13667,.63667,0,0,.77778],8830:[.22958,.72958,0,0,.77778],8831:[.22958,.72958,0,0,.77778],8832:[.20576,.70576,0,0,.77778],8833:[.20576,.70576,0,0,.77778],8840:[.30274,.79383,0,0,.77778],8841:[.30274,.79383,0,0,.77778],8842:[.13597,.63597,0,0,.77778],8843:[.13597,.63597,0,0,.77778],8847:[.03517,.54986,0,0,.77778],8848:[.03517,.54986,0,0,.77778],8858:[.08198,.58198,0,0,.77778],8859:[.08198,.58198,0,0,.77778],8861:[.08198,.58198,0,0,.77778],8862:[0,.675,0,0,.77778],8863:[0,.675,0,0,.77778],8864:[0,.675,0,0,.77778],8865:[0,.675,0,0,.77778],8872:[0,.69224,0,0,.61111],8873:[0,.69224,0,0,.72222],8874:[0,.69224,0,0,.88889],8876:[0,.68889,0,0,.61111],8877:[0,.68889,0,0,.61111],8878:[0,.68889,0,0,.72222],8879:[0,.68889,0,0,.72222],8882:[.03517,.54986,0,0,.77778],8883:[.03517,.54986,0,0,.77778],8884:[.13667,.63667,0,0,.77778],8885:[.13667,.63667,0,0,.77778],8888:[0,.54986,0,0,1.11111],8890:[.19444,.43056,0,0,.55556],8891:[.19444,.69224,0,0,.61111],8892:[.19444,.69224,0,0,.61111],8901:[0,.54986,0,0,.27778],8903:[.08167,.58167,0,0,.77778],8905:[.08167,.58167,0,0,.77778],8906:[.08167,.58167,0,0,.77778],8907:[0,.69224,0,0,.77778],8908:[0,.69224,0,0,.77778],8909:[-.03598,.46402,0,0,.77778],8910:[0,.54986,0,0,.76042],8911:[0,.54986,0,0,.76042],8912:[.03517,.54986,0,0,.77778],8913:[.03517,.54986,0,0,.77778],8914:[0,.54986,0,0,.66667],8915:[0,.54986,0,0,.66667],8916:[0,.69224,0,0,.66667],8918:[.0391,.5391,0,0,.77778],8919:[.0391,.5391,0,0,.77778],8920:[.03517,.54986,0,0,1.33334],8921:[.03517,.54986,0,0,1.33334],8922:[.38569,.88569,0,0,.77778],8923:[.38569,.88569,0,0,.77778],8926:[.13667,.63667,0,0,.77778],8927:[.13667,.63667,0,0,.77778],8928:[.30274,.79383,0,0,.77778],8929:[.30274,.79383,0,0,.77778],8934:[.23222,.74111,0,0,.77778],8935:[.23222,.74111,0,0,.77778],8936:[.23222,.74111,0,0,.77778],8937:[.23222,.74111,0,0,.77778],8938:[.20576,.70576,0,0,.77778],8939:[.20576,.70576,0,0,.77778],8940:[.30274,.79383,0,0,.77778],8941:[.30274,.79383,0,0,.77778],8994:[.19444,.69224,0,0,.77778],8995:[.19444,.69224,0,0,.77778],9416:[.15559,.69224,0,0,.90222],9484:[0,.69224,0,0,.5],9488:[0,.69224,0,0,.5],9492:[0,.37788,0,0,.5],9496:[0,.37788,0,0,.5],9585:[.19444,.68889,0,0,.88889],9586:[.19444,.74111,0,0,.88889],9632:[0,.675,0,0,.77778],9633:[0,.675,0,0,.77778],9650:[0,.54986,0,0,.72222],9651:[0,.54986,0,0,.72222],9654:[.03517,.54986,0,0,.77778],9660:[0,.54986,0,0,.72222],9661:[0,.54986,0,0,.72222],9664:[.03517,.54986,0,0,.77778],9674:[.11111,.69224,0,0,.66667],9733:[.19444,.69224,0,0,.94445],10003:[0,.69224,0,0,.83334],10016:[0,.69224,0,0,.83334],10731:[.11111,.69224,0,0,.66667],10846:[.19444,.75583,0,0,.61111],10877:[.13667,.63667,0,0,.77778],10878:[.13667,.63667,0,0,.77778],10885:[.25583,.75583,0,0,.77778],10886:[.25583,.75583,0,0,.77778],10887:[.13597,.63597,0,0,.77778],10888:[.13597,.63597,0,0,.77778],10889:[.26167,.75726,0,0,.77778],10890:[.26167,.75726,0,0,.77778],10891:[.48256,.98256,0,0,.77778],10892:[.48256,.98256,0,0,.77778],10901:[.13667,.63667,0,0,.77778],10902:[.13667,.63667,0,0,.77778],10933:[.25142,.75726,0,0,.77778],10934:[.25142,.75726,0,0,.77778],10935:[.26167,.75726,0,0,.77778],10936:[.26167,.75726,0,0,.77778],10937:[.26167,.75726,0,0,.77778],10938:[.26167,.75726,0,0,.77778],10949:[.25583,.75583,0,0,.77778],10950:[.25583,.75583,0,0,.77778],10955:[.28481,.79383,0,0,.77778],10956:[.28481,.79383,0,0,.77778],57350:[.08167,.58167,0,0,.22222],57351:[.08167,.58167,0,0,.38889],57352:[.08167,.58167,0,0,.77778],57353:[0,.43056,.04028,0,.66667],57356:[.25142,.75726,0,0,.77778],57357:[.25142,.75726,0,0,.77778],57358:[.41951,.91951,0,0,.77778],57359:[.30274,.79383,0,0,.77778],57360:[.30274,.79383,0,0,.77778],57361:[.41951,.91951,0,0,.77778],57366:[.25142,.75726,0,0,.77778],57367:[.25142,.75726,0,0,.77778],57368:[.25142,.75726,0,0,.77778],57369:[.25142,.75726,0,0,.77778],57370:[.13597,.63597,0,0,.77778],57371:[.13597,.63597,0,0,.77778]},"Caligraphic-Regular":{32:[0,0,0,0,.25],65:[0,.68333,0,.19445,.79847],66:[0,.68333,.03041,.13889,.65681],67:[0,.68333,.05834,.13889,.52653],68:[0,.68333,.02778,.08334,.77139],69:[0,.68333,.08944,.11111,.52778],70:[0,.68333,.09931,.11111,.71875],71:[.09722,.68333,.0593,.11111,.59487],72:[0,.68333,.00965,.11111,.84452],73:[0,.68333,.07382,0,.54452],74:[.09722,.68333,.18472,.16667,.67778],75:[0,.68333,.01445,.05556,.76195],76:[0,.68333,0,.13889,.68972],77:[0,.68333,0,.13889,1.2009],78:[0,.68333,.14736,.08334,.82049],79:[0,.68333,.02778,.11111,.79611],80:[0,.68333,.08222,.08334,.69556],81:[.09722,.68333,0,.11111,.81667],82:[0,.68333,0,.08334,.8475],83:[0,.68333,.075,.13889,.60556],84:[0,.68333,.25417,0,.54464],85:[0,.68333,.09931,.08334,.62583],86:[0,.68333,.08222,0,.61278],87:[0,.68333,.08222,.08334,.98778],88:[0,.68333,.14643,.13889,.7133],89:[.09722,.68333,.08222,.08334,.66834],90:[0,.68333,.07944,.13889,.72473],160:[0,0,0,0,.25]},"Fraktur-Regular":{32:[0,0,0,0,.25],33:[0,.69141,0,0,.29574],34:[0,.69141,0,0,.21471],38:[0,.69141,0,0,.73786],39:[0,.69141,0,0,.21201],40:[.24982,.74947,0,0,.38865],41:[.24982,.74947,0,0,.38865],42:[0,.62119,0,0,.27764],43:[.08319,.58283,0,0,.75623],44:[0,.10803,0,0,.27764],45:[.08319,.58283,0,0,.75623],46:[0,.10803,0,0,.27764],47:[.24982,.74947,0,0,.50181],48:[0,.47534,0,0,.50181],49:[0,.47534,0,0,.50181],50:[0,.47534,0,0,.50181],51:[.18906,.47534,0,0,.50181],52:[.18906,.47534,0,0,.50181],53:[.18906,.47534,0,0,.50181],54:[0,.69141,0,0,.50181],55:[.18906,.47534,0,0,.50181],56:[0,.69141,0,0,.50181],57:[.18906,.47534,0,0,.50181],58:[0,.47534,0,0,.21606],59:[.12604,.47534,0,0,.21606],61:[-.13099,.36866,0,0,.75623],63:[0,.69141,0,0,.36245],65:[0,.69141,0,0,.7176],66:[0,.69141,0,0,.88397],67:[0,.69141,0,0,.61254],68:[0,.69141,0,0,.83158],69:[0,.69141,0,0,.66278],70:[.12604,.69141,0,0,.61119],71:[0,.69141,0,0,.78539],72:[.06302,.69141,0,0,.7203],73:[0,.69141,0,0,.55448],74:[.12604,.69141,0,0,.55231],75:[0,.69141,0,0,.66845],76:[0,.69141,0,0,.66602],77:[0,.69141,0,0,1.04953],78:[0,.69141,0,0,.83212],79:[0,.69141,0,0,.82699],80:[.18906,.69141,0,0,.82753],81:[.03781,.69141,0,0,.82699],82:[0,.69141,0,0,.82807],83:[0,.69141,0,0,.82861],84:[0,.69141,0,0,.66899],85:[0,.69141,0,0,.64576],86:[0,.69141,0,0,.83131],87:[0,.69141,0,0,1.04602],88:[0,.69141,0,0,.71922],89:[.18906,.69141,0,0,.83293],90:[.12604,.69141,0,0,.60201],91:[.24982,.74947,0,0,.27764],93:[.24982,.74947,0,0,.27764],94:[0,.69141,0,0,.49965],97:[0,.47534,0,0,.50046],98:[0,.69141,0,0,.51315],99:[0,.47534,0,0,.38946],100:[0,.62119,0,0,.49857],101:[0,.47534,0,0,.40053],102:[.18906,.69141,0,0,.32626],103:[.18906,.47534,0,0,.5037],104:[.18906,.69141,0,0,.52126],105:[0,.69141,0,0,.27899],106:[0,.69141,0,0,.28088],107:[0,.69141,0,0,.38946],108:[0,.69141,0,0,.27953],109:[0,.47534,0,0,.76676],110:[0,.47534,0,0,.52666],111:[0,.47534,0,0,.48885],112:[.18906,.52396,0,0,.50046],113:[.18906,.47534,0,0,.48912],114:[0,.47534,0,0,.38919],115:[0,.47534,0,0,.44266],116:[0,.62119,0,0,.33301],117:[0,.47534,0,0,.5172],118:[0,.52396,0,0,.5118],119:[0,.52396,0,0,.77351],120:[.18906,.47534,0,0,.38865],121:[.18906,.47534,0,0,.49884],122:[.18906,.47534,0,0,.39054],160:[0,0,0,0,.25],8216:[0,.69141,0,0,.21471],8217:[0,.69141,0,0,.21471],58112:[0,.62119,0,0,.49749],58113:[0,.62119,0,0,.4983],58114:[.18906,.69141,0,0,.33328],58115:[.18906,.69141,0,0,.32923],58116:[.18906,.47534,0,0,.50343],58117:[0,.69141,0,0,.33301],58118:[0,.62119,0,0,.33409],58119:[0,.47534,0,0,.50073]},"Main-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.35],34:[0,.69444,0,0,.60278],35:[.19444,.69444,0,0,.95833],36:[.05556,.75,0,0,.575],37:[.05556,.75,0,0,.95833],38:[0,.69444,0,0,.89444],39:[0,.69444,0,0,.31944],40:[.25,.75,0,0,.44722],41:[.25,.75,0,0,.44722],42:[0,.75,0,0,.575],43:[.13333,.63333,0,0,.89444],44:[.19444,.15556,0,0,.31944],45:[0,.44444,0,0,.38333],46:[0,.15556,0,0,.31944],47:[.25,.75,0,0,.575],48:[0,.64444,0,0,.575],49:[0,.64444,0,0,.575],50:[0,.64444,0,0,.575],51:[0,.64444,0,0,.575],52:[0,.64444,0,0,.575],53:[0,.64444,0,0,.575],54:[0,.64444,0,0,.575],55:[0,.64444,0,0,.575],56:[0,.64444,0,0,.575],57:[0,.64444,0,0,.575],58:[0,.44444,0,0,.31944],59:[.19444,.44444,0,0,.31944],60:[.08556,.58556,0,0,.89444],61:[-.10889,.39111,0,0,.89444],62:[.08556,.58556,0,0,.89444],63:[0,.69444,0,0,.54305],64:[0,.69444,0,0,.89444],65:[0,.68611,0,0,.86944],66:[0,.68611,0,0,.81805],67:[0,.68611,0,0,.83055],68:[0,.68611,0,0,.88194],69:[0,.68611,0,0,.75555],70:[0,.68611,0,0,.72361],71:[0,.68611,0,0,.90416],72:[0,.68611,0,0,.9],73:[0,.68611,0,0,.43611],74:[0,.68611,0,0,.59444],75:[0,.68611,0,0,.90138],76:[0,.68611,0,0,.69166],77:[0,.68611,0,0,1.09166],78:[0,.68611,0,0,.9],79:[0,.68611,0,0,.86388],80:[0,.68611,0,0,.78611],81:[.19444,.68611,0,0,.86388],82:[0,.68611,0,0,.8625],83:[0,.68611,0,0,.63889],84:[0,.68611,0,0,.8],85:[0,.68611,0,0,.88472],86:[0,.68611,.01597,0,.86944],87:[0,.68611,.01597,0,1.18888],88:[0,.68611,0,0,.86944],89:[0,.68611,.02875,0,.86944],90:[0,.68611,0,0,.70277],91:[.25,.75,0,0,.31944],92:[.25,.75,0,0,.575],93:[.25,.75,0,0,.31944],94:[0,.69444,0,0,.575],95:[.31,.13444,.03194,0,.575],97:[0,.44444,0,0,.55902],98:[0,.69444,0,0,.63889],99:[0,.44444,0,0,.51111],100:[0,.69444,0,0,.63889],101:[0,.44444,0,0,.52708],102:[0,.69444,.10903,0,.35139],103:[.19444,.44444,.01597,0,.575],104:[0,.69444,0,0,.63889],105:[0,.69444,0,0,.31944],106:[.19444,.69444,0,0,.35139],107:[0,.69444,0,0,.60694],108:[0,.69444,0,0,.31944],109:[0,.44444,0,0,.95833],110:[0,.44444,0,0,.63889],111:[0,.44444,0,0,.575],112:[.19444,.44444,0,0,.63889],113:[.19444,.44444,0,0,.60694],114:[0,.44444,0,0,.47361],115:[0,.44444,0,0,.45361],116:[0,.63492,0,0,.44722],117:[0,.44444,0,0,.63889],118:[0,.44444,.01597,0,.60694],119:[0,.44444,.01597,0,.83055],120:[0,.44444,0,0,.60694],121:[.19444,.44444,.01597,0,.60694],122:[0,.44444,0,0,.51111],123:[.25,.75,0,0,.575],124:[.25,.75,0,0,.31944],125:[.25,.75,0,0,.575],126:[.35,.34444,0,0,.575],160:[0,0,0,0,.25],163:[0,.69444,0,0,.86853],168:[0,.69444,0,0,.575],172:[0,.44444,0,0,.76666],176:[0,.69444,0,0,.86944],177:[.13333,.63333,0,0,.89444],184:[.17014,0,0,0,.51111],198:[0,.68611,0,0,1.04166],215:[.13333,.63333,0,0,.89444],216:[.04861,.73472,0,0,.89444],223:[0,.69444,0,0,.59722],230:[0,.44444,0,0,.83055],247:[.13333,.63333,0,0,.89444],248:[.09722,.54167,0,0,.575],305:[0,.44444,0,0,.31944],338:[0,.68611,0,0,1.16944],339:[0,.44444,0,0,.89444],567:[.19444,.44444,0,0,.35139],710:[0,.69444,0,0,.575],711:[0,.63194,0,0,.575],713:[0,.59611,0,0,.575],714:[0,.69444,0,0,.575],715:[0,.69444,0,0,.575],728:[0,.69444,0,0,.575],729:[0,.69444,0,0,.31944],730:[0,.69444,0,0,.86944],732:[0,.69444,0,0,.575],733:[0,.69444,0,0,.575],915:[0,.68611,0,0,.69166],916:[0,.68611,0,0,.95833],920:[0,.68611,0,0,.89444],923:[0,.68611,0,0,.80555],926:[0,.68611,0,0,.76666],928:[0,.68611,0,0,.9],931:[0,.68611,0,0,.83055],933:[0,.68611,0,0,.89444],934:[0,.68611,0,0,.83055],936:[0,.68611,0,0,.89444],937:[0,.68611,0,0,.83055],8211:[0,.44444,.03194,0,.575],8212:[0,.44444,.03194,0,1.14999],8216:[0,.69444,0,0,.31944],8217:[0,.69444,0,0,.31944],8220:[0,.69444,0,0,.60278],8221:[0,.69444,0,0,.60278],8224:[.19444,.69444,0,0,.51111],8225:[.19444,.69444,0,0,.51111],8242:[0,.55556,0,0,.34444],8407:[0,.72444,.15486,0,.575],8463:[0,.69444,0,0,.66759],8465:[0,.69444,0,0,.83055],8467:[0,.69444,0,0,.47361],8472:[.19444,.44444,0,0,.74027],8476:[0,.69444,0,0,.83055],8501:[0,.69444,0,0,.70277],8592:[-.10889,.39111,0,0,1.14999],8593:[.19444,.69444,0,0,.575],8594:[-.10889,.39111,0,0,1.14999],8595:[.19444,.69444,0,0,.575],8596:[-.10889,.39111,0,0,1.14999],8597:[.25,.75,0,0,.575],8598:[.19444,.69444,0,0,1.14999],8599:[.19444,.69444,0,0,1.14999],8600:[.19444,.69444,0,0,1.14999],8601:[.19444,.69444,0,0,1.14999],8636:[-.10889,.39111,0,0,1.14999],8637:[-.10889,.39111,0,0,1.14999],8640:[-.10889,.39111,0,0,1.14999],8641:[-.10889,.39111,0,0,1.14999],8656:[-.10889,.39111,0,0,1.14999],8657:[.19444,.69444,0,0,.70277],8658:[-.10889,.39111,0,0,1.14999],8659:[.19444,.69444,0,0,.70277],8660:[-.10889,.39111,0,0,1.14999],8661:[.25,.75,0,0,.70277],8704:[0,.69444,0,0,.63889],8706:[0,.69444,.06389,0,.62847],8707:[0,.69444,0,0,.63889],8709:[.05556,.75,0,0,.575],8711:[0,.68611,0,0,.95833],8712:[.08556,.58556,0,0,.76666],8715:[.08556,.58556,0,0,.76666],8722:[.13333,.63333,0,0,.89444],8723:[.13333,.63333,0,0,.89444],8725:[.25,.75,0,0,.575],8726:[.25,.75,0,0,.575],8727:[-.02778,.47222,0,0,.575],8728:[-.02639,.47361,0,0,.575],8729:[-.02639,.47361,0,0,.575],8730:[.18,.82,0,0,.95833],8733:[0,.44444,0,0,.89444],8734:[0,.44444,0,0,1.14999],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.31944],8741:[.25,.75,0,0,.575],8743:[0,.55556,0,0,.76666],8744:[0,.55556,0,0,.76666],8745:[0,.55556,0,0,.76666],8746:[0,.55556,0,0,.76666],8747:[.19444,.69444,.12778,0,.56875],8764:[-.10889,.39111,0,0,.89444],8768:[.19444,.69444,0,0,.31944],8771:[.00222,.50222,0,0,.89444],8776:[.02444,.52444,0,0,.89444],8781:[.00222,.50222,0,0,.89444],8801:[.00222,.50222,0,0,.89444],8804:[.19667,.69667,0,0,.89444],8805:[.19667,.69667,0,0,.89444],8810:[.08556,.58556,0,0,1.14999],8811:[.08556,.58556,0,0,1.14999],8826:[.08556,.58556,0,0,.89444],8827:[.08556,.58556,0,0,.89444],8834:[.08556,.58556,0,0,.89444],8835:[.08556,.58556,0,0,.89444],8838:[.19667,.69667,0,0,.89444],8839:[.19667,.69667,0,0,.89444],8846:[0,.55556,0,0,.76666],8849:[.19667,.69667,0,0,.89444],8850:[.19667,.69667,0,0,.89444],8851:[0,.55556,0,0,.76666],8852:[0,.55556,0,0,.76666],8853:[.13333,.63333,0,0,.89444],8854:[.13333,.63333,0,0,.89444],8855:[.13333,.63333,0,0,.89444],8856:[.13333,.63333,0,0,.89444],8857:[.13333,.63333,0,0,.89444],8866:[0,.69444,0,0,.70277],8867:[0,.69444,0,0,.70277],8868:[0,.69444,0,0,.89444],8869:[0,.69444,0,0,.89444],8900:[-.02639,.47361,0,0,.575],8901:[-.02639,.47361,0,0,.31944],8902:[-.02778,.47222,0,0,.575],8968:[.25,.75,0,0,.51111],8969:[.25,.75,0,0,.51111],8970:[.25,.75,0,0,.51111],8971:[.25,.75,0,0,.51111],8994:[-.13889,.36111,0,0,1.14999],8995:[-.13889,.36111,0,0,1.14999],9651:[.19444,.69444,0,0,1.02222],9657:[-.02778,.47222,0,0,.575],9661:[.19444,.69444,0,0,1.02222],9667:[-.02778,.47222,0,0,.575],9711:[.19444,.69444,0,0,1.14999],9824:[.12963,.69444,0,0,.89444],9825:[.12963,.69444,0,0,.89444],9826:[.12963,.69444,0,0,.89444],9827:[.12963,.69444,0,0,.89444],9837:[0,.75,0,0,.44722],9838:[.19444,.69444,0,0,.44722],9839:[.19444,.69444,0,0,.44722],10216:[.25,.75,0,0,.44722],10217:[.25,.75,0,0,.44722],10815:[0,.68611,0,0,.9],10927:[.19667,.69667,0,0,.89444],10928:[.19667,.69667,0,0,.89444],57376:[.19444,.69444,0,0,0]},"Main-BoldItalic":{32:[0,0,0,0,.25],33:[0,.69444,.11417,0,.38611],34:[0,.69444,.07939,0,.62055],35:[.19444,.69444,.06833,0,.94444],37:[.05556,.75,.12861,0,.94444],38:[0,.69444,.08528,0,.88555],39:[0,.69444,.12945,0,.35555],40:[.25,.75,.15806,0,.47333],41:[.25,.75,.03306,0,.47333],42:[0,.75,.14333,0,.59111],43:[.10333,.60333,.03306,0,.88555],44:[.19444,.14722,0,0,.35555],45:[0,.44444,.02611,0,.41444],46:[0,.14722,0,0,.35555],47:[.25,.75,.15806,0,.59111],48:[0,.64444,.13167,0,.59111],49:[0,.64444,.13167,0,.59111],50:[0,.64444,.13167,0,.59111],51:[0,.64444,.13167,0,.59111],52:[.19444,.64444,.13167,0,.59111],53:[0,.64444,.13167,0,.59111],54:[0,.64444,.13167,0,.59111],55:[.19444,.64444,.13167,0,.59111],56:[0,.64444,.13167,0,.59111],57:[0,.64444,.13167,0,.59111],58:[0,.44444,.06695,0,.35555],59:[.19444,.44444,.06695,0,.35555],61:[-.10889,.39111,.06833,0,.88555],63:[0,.69444,.11472,0,.59111],64:[0,.69444,.09208,0,.88555],65:[0,.68611,0,0,.86555],66:[0,.68611,.0992,0,.81666],67:[0,.68611,.14208,0,.82666],68:[0,.68611,.09062,0,.87555],69:[0,.68611,.11431,0,.75666],70:[0,.68611,.12903,0,.72722],71:[0,.68611,.07347,0,.89527],72:[0,.68611,.17208,0,.8961],73:[0,.68611,.15681,0,.47166],74:[0,.68611,.145,0,.61055],75:[0,.68611,.14208,0,.89499],76:[0,.68611,0,0,.69777],77:[0,.68611,.17208,0,1.07277],78:[0,.68611,.17208,0,.8961],79:[0,.68611,.09062,0,.85499],80:[0,.68611,.0992,0,.78721],81:[.19444,.68611,.09062,0,.85499],82:[0,.68611,.02559,0,.85944],83:[0,.68611,.11264,0,.64999],84:[0,.68611,.12903,0,.7961],85:[0,.68611,.17208,0,.88083],86:[0,.68611,.18625,0,.86555],87:[0,.68611,.18625,0,1.15999],88:[0,.68611,.15681,0,.86555],89:[0,.68611,.19803,0,.86555],90:[0,.68611,.14208,0,.70888],91:[.25,.75,.1875,0,.35611],93:[.25,.75,.09972,0,.35611],94:[0,.69444,.06709,0,.59111],95:[.31,.13444,.09811,0,.59111],97:[0,.44444,.09426,0,.59111],98:[0,.69444,.07861,0,.53222],99:[0,.44444,.05222,0,.53222],100:[0,.69444,.10861,0,.59111],101:[0,.44444,.085,0,.53222],102:[.19444,.69444,.21778,0,.4],103:[.19444,.44444,.105,0,.53222],104:[0,.69444,.09426,0,.59111],105:[0,.69326,.11387,0,.35555],106:[.19444,.69326,.1672,0,.35555],107:[0,.69444,.11111,0,.53222],108:[0,.69444,.10861,0,.29666],109:[0,.44444,.09426,0,.94444],110:[0,.44444,.09426,0,.64999],111:[0,.44444,.07861,0,.59111],112:[.19444,.44444,.07861,0,.59111],113:[.19444,.44444,.105,0,.53222],114:[0,.44444,.11111,0,.50167],115:[0,.44444,.08167,0,.48694],116:[0,.63492,.09639,0,.385],117:[0,.44444,.09426,0,.62055],118:[0,.44444,.11111,0,.53222],119:[0,.44444,.11111,0,.76777],120:[0,.44444,.12583,0,.56055],121:[.19444,.44444,.105,0,.56166],122:[0,.44444,.13889,0,.49055],126:[.35,.34444,.11472,0,.59111],160:[0,0,0,0,.25],168:[0,.69444,.11473,0,.59111],176:[0,.69444,0,0,.94888],184:[.17014,0,0,0,.53222],198:[0,.68611,.11431,0,1.02277],216:[.04861,.73472,.09062,0,.88555],223:[.19444,.69444,.09736,0,.665],230:[0,.44444,.085,0,.82666],248:[.09722,.54167,.09458,0,.59111],305:[0,.44444,.09426,0,.35555],338:[0,.68611,.11431,0,1.14054],339:[0,.44444,.085,0,.82666],567:[.19444,.44444,.04611,0,.385],710:[0,.69444,.06709,0,.59111],711:[0,.63194,.08271,0,.59111],713:[0,.59444,.10444,0,.59111],714:[0,.69444,.08528,0,.59111],715:[0,.69444,0,0,.59111],728:[0,.69444,.10333,0,.59111],729:[0,.69444,.12945,0,.35555],730:[0,.69444,0,0,.94888],732:[0,.69444,.11472,0,.59111],733:[0,.69444,.11472,0,.59111],915:[0,.68611,.12903,0,.69777],916:[0,.68611,0,0,.94444],920:[0,.68611,.09062,0,.88555],923:[0,.68611,0,0,.80666],926:[0,.68611,.15092,0,.76777],928:[0,.68611,.17208,0,.8961],931:[0,.68611,.11431,0,.82666],933:[0,.68611,.10778,0,.88555],934:[0,.68611,.05632,0,.82666],936:[0,.68611,.10778,0,.88555],937:[0,.68611,.0992,0,.82666],8211:[0,.44444,.09811,0,.59111],8212:[0,.44444,.09811,0,1.18221],8216:[0,.69444,.12945,0,.35555],8217:[0,.69444,.12945,0,.35555],8220:[0,.69444,.16772,0,.62055],8221:[0,.69444,.07939,0,.62055]},"Main-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.12417,0,.30667],34:[0,.69444,.06961,0,.51444],35:[.19444,.69444,.06616,0,.81777],37:[.05556,.75,.13639,0,.81777],38:[0,.69444,.09694,0,.76666],39:[0,.69444,.12417,0,.30667],40:[.25,.75,.16194,0,.40889],41:[.25,.75,.03694,0,.40889],42:[0,.75,.14917,0,.51111],43:[.05667,.56167,.03694,0,.76666],44:[.19444,.10556,0,0,.30667],45:[0,.43056,.02826,0,.35778],46:[0,.10556,0,0,.30667],47:[.25,.75,.16194,0,.51111],48:[0,.64444,.13556,0,.51111],49:[0,.64444,.13556,0,.51111],50:[0,.64444,.13556,0,.51111],51:[0,.64444,.13556,0,.51111],52:[.19444,.64444,.13556,0,.51111],53:[0,.64444,.13556,0,.51111],54:[0,.64444,.13556,0,.51111],55:[.19444,.64444,.13556,0,.51111],56:[0,.64444,.13556,0,.51111],57:[0,.64444,.13556,0,.51111],58:[0,.43056,.0582,0,.30667],59:[.19444,.43056,.0582,0,.30667],61:[-.13313,.36687,.06616,0,.76666],63:[0,.69444,.1225,0,.51111],64:[0,.69444,.09597,0,.76666],65:[0,.68333,0,0,.74333],66:[0,.68333,.10257,0,.70389],67:[0,.68333,.14528,0,.71555],68:[0,.68333,.09403,0,.755],69:[0,.68333,.12028,0,.67833],70:[0,.68333,.13305,0,.65277],71:[0,.68333,.08722,0,.77361],72:[0,.68333,.16389,0,.74333],73:[0,.68333,.15806,0,.38555],74:[0,.68333,.14028,0,.525],75:[0,.68333,.14528,0,.76888],76:[0,.68333,0,0,.62722],77:[0,.68333,.16389,0,.89666],78:[0,.68333,.16389,0,.74333],79:[0,.68333,.09403,0,.76666],80:[0,.68333,.10257,0,.67833],81:[.19444,.68333,.09403,0,.76666],82:[0,.68333,.03868,0,.72944],83:[0,.68333,.11972,0,.56222],84:[0,.68333,.13305,0,.71555],85:[0,.68333,.16389,0,.74333],86:[0,.68333,.18361,0,.74333],87:[0,.68333,.18361,0,.99888],88:[0,.68333,.15806,0,.74333],89:[0,.68333,.19383,0,.74333],90:[0,.68333,.14528,0,.61333],91:[.25,.75,.1875,0,.30667],93:[.25,.75,.10528,0,.30667],94:[0,.69444,.06646,0,.51111],95:[.31,.12056,.09208,0,.51111],97:[0,.43056,.07671,0,.51111],98:[0,.69444,.06312,0,.46],99:[0,.43056,.05653,0,.46],100:[0,.69444,.10333,0,.51111],101:[0,.43056,.07514,0,.46],102:[.19444,.69444,.21194,0,.30667],103:[.19444,.43056,.08847,0,.46],104:[0,.69444,.07671,0,.51111],105:[0,.65536,.1019,0,.30667],106:[.19444,.65536,.14467,0,.30667],107:[0,.69444,.10764,0,.46],108:[0,.69444,.10333,0,.25555],109:[0,.43056,.07671,0,.81777],110:[0,.43056,.07671,0,.56222],111:[0,.43056,.06312,0,.51111],112:[.19444,.43056,.06312,0,.51111],113:[.19444,.43056,.08847,0,.46],114:[0,.43056,.10764,0,.42166],115:[0,.43056,.08208,0,.40889],116:[0,.61508,.09486,0,.33222],117:[0,.43056,.07671,0,.53666],118:[0,.43056,.10764,0,.46],119:[0,.43056,.10764,0,.66444],120:[0,.43056,.12042,0,.46389],121:[.19444,.43056,.08847,0,.48555],122:[0,.43056,.12292,0,.40889],126:[.35,.31786,.11585,0,.51111],160:[0,0,0,0,.25],168:[0,.66786,.10474,0,.51111],176:[0,.69444,0,0,.83129],184:[.17014,0,0,0,.46],198:[0,.68333,.12028,0,.88277],216:[.04861,.73194,.09403,0,.76666],223:[.19444,.69444,.10514,0,.53666],230:[0,.43056,.07514,0,.71555],248:[.09722,.52778,.09194,0,.51111],338:[0,.68333,.12028,0,.98499],339:[0,.43056,.07514,0,.71555],710:[0,.69444,.06646,0,.51111],711:[0,.62847,.08295,0,.51111],713:[0,.56167,.10333,0,.51111],714:[0,.69444,.09694,0,.51111],715:[0,.69444,0,0,.51111],728:[0,.69444,.10806,0,.51111],729:[0,.66786,.11752,0,.30667],730:[0,.69444,0,0,.83129],732:[0,.66786,.11585,0,.51111],733:[0,.69444,.1225,0,.51111],915:[0,.68333,.13305,0,.62722],916:[0,.68333,0,0,.81777],920:[0,.68333,.09403,0,.76666],923:[0,.68333,0,0,.69222],926:[0,.68333,.15294,0,.66444],928:[0,.68333,.16389,0,.74333],931:[0,.68333,.12028,0,.71555],933:[0,.68333,.11111,0,.76666],934:[0,.68333,.05986,0,.71555],936:[0,.68333,.11111,0,.76666],937:[0,.68333,.10257,0,.71555],8211:[0,.43056,.09208,0,.51111],8212:[0,.43056,.09208,0,1.02222],8216:[0,.69444,.12417,0,.30667],8217:[0,.69444,.12417,0,.30667],8220:[0,.69444,.1685,0,.51444],8221:[0,.69444,.06961,0,.51444],8463:[0,.68889,0,0,.54028]},"Main-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.27778],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.77778],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.19444,.10556,0,0,.27778],45:[0,.43056,0,0,.33333],46:[0,.10556,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.64444,0,0,.5],49:[0,.64444,0,0,.5],50:[0,.64444,0,0,.5],51:[0,.64444,0,0,.5],52:[0,.64444,0,0,.5],53:[0,.64444,0,0,.5],54:[0,.64444,0,0,.5],55:[0,.64444,0,0,.5],56:[0,.64444,0,0,.5],57:[0,.64444,0,0,.5],58:[0,.43056,0,0,.27778],59:[.19444,.43056,0,0,.27778],60:[.0391,.5391,0,0,.77778],61:[-.13313,.36687,0,0,.77778],62:[.0391,.5391,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.77778],65:[0,.68333,0,0,.75],66:[0,.68333,0,0,.70834],67:[0,.68333,0,0,.72222],68:[0,.68333,0,0,.76389],69:[0,.68333,0,0,.68056],70:[0,.68333,0,0,.65278],71:[0,.68333,0,0,.78472],72:[0,.68333,0,0,.75],73:[0,.68333,0,0,.36111],74:[0,.68333,0,0,.51389],75:[0,.68333,0,0,.77778],76:[0,.68333,0,0,.625],77:[0,.68333,0,0,.91667],78:[0,.68333,0,0,.75],79:[0,.68333,0,0,.77778],80:[0,.68333,0,0,.68056],81:[.19444,.68333,0,0,.77778],82:[0,.68333,0,0,.73611],83:[0,.68333,0,0,.55556],84:[0,.68333,0,0,.72222],85:[0,.68333,0,0,.75],86:[0,.68333,.01389,0,.75],87:[0,.68333,.01389,0,1.02778],88:[0,.68333,0,0,.75],89:[0,.68333,.025,0,.75],90:[0,.68333,0,0,.61111],91:[.25,.75,0,0,.27778],92:[.25,.75,0,0,.5],93:[.25,.75,0,0,.27778],94:[0,.69444,0,0,.5],95:[.31,.12056,.02778,0,.5],97:[0,.43056,0,0,.5],98:[0,.69444,0,0,.55556],99:[0,.43056,0,0,.44445],100:[0,.69444,0,0,.55556],101:[0,.43056,0,0,.44445],102:[0,.69444,.07778,0,.30556],103:[.19444,.43056,.01389,0,.5],104:[0,.69444,0,0,.55556],105:[0,.66786,0,0,.27778],106:[.19444,.66786,0,0,.30556],107:[0,.69444,0,0,.52778],108:[0,.69444,0,0,.27778],109:[0,.43056,0,0,.83334],110:[0,.43056,0,0,.55556],111:[0,.43056,0,0,.5],112:[.19444,.43056,0,0,.55556],113:[.19444,.43056,0,0,.52778],114:[0,.43056,0,0,.39167],115:[0,.43056,0,0,.39445],116:[0,.61508,0,0,.38889],117:[0,.43056,0,0,.55556],118:[0,.43056,.01389,0,.52778],119:[0,.43056,.01389,0,.72222],120:[0,.43056,0,0,.52778],121:[.19444,.43056,.01389,0,.52778],122:[0,.43056,0,0,.44445],123:[.25,.75,0,0,.5],124:[.25,.75,0,0,.27778],125:[.25,.75,0,0,.5],126:[.35,.31786,0,0,.5],160:[0,0,0,0,.25],163:[0,.69444,0,0,.76909],167:[.19444,.69444,0,0,.44445],168:[0,.66786,0,0,.5],172:[0,.43056,0,0,.66667],176:[0,.69444,0,0,.75],177:[.08333,.58333,0,0,.77778],182:[.19444,.69444,0,0,.61111],184:[.17014,0,0,0,.44445],198:[0,.68333,0,0,.90278],215:[.08333,.58333,0,0,.77778],216:[.04861,.73194,0,0,.77778],223:[0,.69444,0,0,.5],230:[0,.43056,0,0,.72222],247:[.08333,.58333,0,0,.77778],248:[.09722,.52778,0,0,.5],305:[0,.43056,0,0,.27778],338:[0,.68333,0,0,1.01389],339:[0,.43056,0,0,.77778],567:[.19444,.43056,0,0,.30556],710:[0,.69444,0,0,.5],711:[0,.62847,0,0,.5],713:[0,.56778,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.66786,0,0,.27778],730:[0,.69444,0,0,.75],732:[0,.66786,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.68333,0,0,.625],916:[0,.68333,0,0,.83334],920:[0,.68333,0,0,.77778],923:[0,.68333,0,0,.69445],926:[0,.68333,0,0,.66667],928:[0,.68333,0,0,.75],931:[0,.68333,0,0,.72222],933:[0,.68333,0,0,.77778],934:[0,.68333,0,0,.72222],936:[0,.68333,0,0,.77778],937:[0,.68333,0,0,.72222],8211:[0,.43056,.02778,0,.5],8212:[0,.43056,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5],8224:[.19444,.69444,0,0,.44445],8225:[.19444,.69444,0,0,.44445],8230:[0,.12,0,0,1.172],8242:[0,.55556,0,0,.275],8407:[0,.71444,.15382,0,.5],8463:[0,.68889,0,0,.54028],8465:[0,.69444,0,0,.72222],8467:[0,.69444,0,.11111,.41667],8472:[.19444,.43056,0,.11111,.63646],8476:[0,.69444,0,0,.72222],8501:[0,.69444,0,0,.61111],8592:[-.13313,.36687,0,0,1],8593:[.19444,.69444,0,0,.5],8594:[-.13313,.36687,0,0,1],8595:[.19444,.69444,0,0,.5],8596:[-.13313,.36687,0,0,1],8597:[.25,.75,0,0,.5],8598:[.19444,.69444,0,0,1],8599:[.19444,.69444,0,0,1],8600:[.19444,.69444,0,0,1],8601:[.19444,.69444,0,0,1],8614:[.011,.511,0,0,1],8617:[.011,.511,0,0,1.126],8618:[.011,.511,0,0,1.126],8636:[-.13313,.36687,0,0,1],8637:[-.13313,.36687,0,0,1],8640:[-.13313,.36687,0,0,1],8641:[-.13313,.36687,0,0,1],8652:[.011,.671,0,0,1],8656:[-.13313,.36687,0,0,1],8657:[.19444,.69444,0,0,.61111],8658:[-.13313,.36687,0,0,1],8659:[.19444,.69444,0,0,.61111],8660:[-.13313,.36687,0,0,1],8661:[.25,.75,0,0,.61111],8704:[0,.69444,0,0,.55556],8706:[0,.69444,.05556,.08334,.5309],8707:[0,.69444,0,0,.55556],8709:[.05556,.75,0,0,.5],8711:[0,.68333,0,0,.83334],8712:[.0391,.5391,0,0,.66667],8715:[.0391,.5391,0,0,.66667],8722:[.08333,.58333,0,0,.77778],8723:[.08333,.58333,0,0,.77778],8725:[.25,.75,0,0,.5],8726:[.25,.75,0,0,.5],8727:[-.03472,.46528,0,0,.5],8728:[-.05555,.44445,0,0,.5],8729:[-.05555,.44445,0,0,.5],8730:[.2,.8,0,0,.83334],8733:[0,.43056,0,0,.77778],8734:[0,.43056,0,0,1],8736:[0,.69224,0,0,.72222],8739:[.25,.75,0,0,.27778],8741:[.25,.75,0,0,.5],8743:[0,.55556,0,0,.66667],8744:[0,.55556,0,0,.66667],8745:[0,.55556,0,0,.66667],8746:[0,.55556,0,0,.66667],8747:[.19444,.69444,.11111,0,.41667],8764:[-.13313,.36687,0,0,.77778],8768:[.19444,.69444,0,0,.27778],8771:[-.03625,.46375,0,0,.77778],8773:[-.022,.589,0,0,1],8776:[-.01688,.48312,0,0,.77778],8781:[-.03625,.46375,0,0,.77778],8784:[-.133,.67,0,0,.778],8801:[-.03625,.46375,0,0,.77778],8804:[.13597,.63597,0,0,.77778],8805:[.13597,.63597,0,0,.77778],8810:[.0391,.5391,0,0,1],8811:[.0391,.5391,0,0,1],8826:[.0391,.5391,0,0,.77778],8827:[.0391,.5391,0,0,.77778],8834:[.0391,.5391,0,0,.77778],8835:[.0391,.5391,0,0,.77778],8838:[.13597,.63597,0,0,.77778],8839:[.13597,.63597,0,0,.77778],8846:[0,.55556,0,0,.66667],8849:[.13597,.63597,0,0,.77778],8850:[.13597,.63597,0,0,.77778],8851:[0,.55556,0,0,.66667],8852:[0,.55556,0,0,.66667],8853:[.08333,.58333,0,0,.77778],8854:[.08333,.58333,0,0,.77778],8855:[.08333,.58333,0,0,.77778],8856:[.08333,.58333,0,0,.77778],8857:[.08333,.58333,0,0,.77778],8866:[0,.69444,0,0,.61111],8867:[0,.69444,0,0,.61111],8868:[0,.69444,0,0,.77778],8869:[0,.69444,0,0,.77778],8872:[.249,.75,0,0,.867],8900:[-.05555,.44445,0,0,.5],8901:[-.05555,.44445,0,0,.27778],8902:[-.03472,.46528,0,0,.5],8904:[.005,.505,0,0,.9],8942:[.03,.9,0,0,.278],8943:[-.19,.31,0,0,1.172],8945:[-.1,.82,0,0,1.282],8968:[.25,.75,0,0,.44445],8969:[.25,.75,0,0,.44445],8970:[.25,.75,0,0,.44445],8971:[.25,.75,0,0,.44445],8994:[-.14236,.35764,0,0,1],8995:[-.14236,.35764,0,0,1],9136:[.244,.744,0,0,.412],9137:[.244,.744,0,0,.412],9651:[.19444,.69444,0,0,.88889],9657:[-.03472,.46528,0,0,.5],9661:[.19444,.69444,0,0,.88889],9667:[-.03472,.46528,0,0,.5],9711:[.19444,.69444,0,0,1],9824:[.12963,.69444,0,0,.77778],9825:[.12963,.69444,0,0,.77778],9826:[.12963,.69444,0,0,.77778],9827:[.12963,.69444,0,0,.77778],9837:[0,.75,0,0,.38889],9838:[.19444,.69444,0,0,.38889],9839:[.19444,.69444,0,0,.38889],10216:[.25,.75,0,0,.38889],10217:[.25,.75,0,0,.38889],10222:[.244,.744,0,0,.412],10223:[.244,.744,0,0,.412],10229:[.011,.511,0,0,1.609],10230:[.011,.511,0,0,1.638],10231:[.011,.511,0,0,1.859],10232:[.024,.525,0,0,1.609],10233:[.024,.525,0,0,1.638],10234:[.024,.525,0,0,1.858],10236:[.011,.511,0,0,1.638],10815:[0,.68333,0,0,.75],10927:[.13597,.63597,0,0,.77778],10928:[.13597,.63597,0,0,.77778],57376:[.19444,.69444,0,0,0]},"Math-BoldItalic":{32:[0,0,0,0,.25],48:[0,.44444,0,0,.575],49:[0,.44444,0,0,.575],50:[0,.44444,0,0,.575],51:[.19444,.44444,0,0,.575],52:[.19444,.44444,0,0,.575],53:[.19444,.44444,0,0,.575],54:[0,.64444,0,0,.575],55:[.19444,.44444,0,0,.575],56:[0,.64444,0,0,.575],57:[.19444,.44444,0,0,.575],65:[0,.68611,0,0,.86944],66:[0,.68611,.04835,0,.8664],67:[0,.68611,.06979,0,.81694],68:[0,.68611,.03194,0,.93812],69:[0,.68611,.05451,0,.81007],70:[0,.68611,.15972,0,.68889],71:[0,.68611,0,0,.88673],72:[0,.68611,.08229,0,.98229],73:[0,.68611,.07778,0,.51111],74:[0,.68611,.10069,0,.63125],75:[0,.68611,.06979,0,.97118],76:[0,.68611,0,0,.75555],77:[0,.68611,.11424,0,1.14201],78:[0,.68611,.11424,0,.95034],79:[0,.68611,.03194,0,.83666],80:[0,.68611,.15972,0,.72309],81:[.19444,.68611,0,0,.86861],82:[0,.68611,.00421,0,.87235],83:[0,.68611,.05382,0,.69271],84:[0,.68611,.15972,0,.63663],85:[0,.68611,.11424,0,.80027],86:[0,.68611,.25555,0,.67778],87:[0,.68611,.15972,0,1.09305],88:[0,.68611,.07778,0,.94722],89:[0,.68611,.25555,0,.67458],90:[0,.68611,.06979,0,.77257],97:[0,.44444,0,0,.63287],98:[0,.69444,0,0,.52083],99:[0,.44444,0,0,.51342],100:[0,.69444,0,0,.60972],101:[0,.44444,0,0,.55361],102:[.19444,.69444,.11042,0,.56806],103:[.19444,.44444,.03704,0,.5449],104:[0,.69444,0,0,.66759],105:[0,.69326,0,0,.4048],106:[.19444,.69326,.0622,0,.47083],107:[0,.69444,.01852,0,.6037],108:[0,.69444,.0088,0,.34815],109:[0,.44444,0,0,1.0324],110:[0,.44444,0,0,.71296],111:[0,.44444,0,0,.58472],112:[.19444,.44444,0,0,.60092],113:[.19444,.44444,.03704,0,.54213],114:[0,.44444,.03194,0,.5287],115:[0,.44444,0,0,.53125],116:[0,.63492,0,0,.41528],117:[0,.44444,0,0,.68102],118:[0,.44444,.03704,0,.56666],119:[0,.44444,.02778,0,.83148],120:[0,.44444,0,0,.65903],121:[.19444,.44444,.03704,0,.59028],122:[0,.44444,.04213,0,.55509],160:[0,0,0,0,.25],915:[0,.68611,.15972,0,.65694],916:[0,.68611,0,0,.95833],920:[0,.68611,.03194,0,.86722],923:[0,.68611,0,0,.80555],926:[0,.68611,.07458,0,.84125],928:[0,.68611,.08229,0,.98229],931:[0,.68611,.05451,0,.88507],933:[0,.68611,.15972,0,.67083],934:[0,.68611,0,0,.76666],936:[0,.68611,.11653,0,.71402],937:[0,.68611,.04835,0,.8789],945:[0,.44444,0,0,.76064],946:[.19444,.69444,.03403,0,.65972],947:[.19444,.44444,.06389,0,.59003],948:[0,.69444,.03819,0,.52222],949:[0,.44444,0,0,.52882],950:[.19444,.69444,.06215,0,.50833],951:[.19444,.44444,.03704,0,.6],952:[0,.69444,.03194,0,.5618],953:[0,.44444,0,0,.41204],954:[0,.44444,0,0,.66759],955:[0,.69444,0,0,.67083],956:[.19444,.44444,0,0,.70787],957:[0,.44444,.06898,0,.57685],958:[.19444,.69444,.03021,0,.50833],959:[0,.44444,0,0,.58472],960:[0,.44444,.03704,0,.68241],961:[.19444,.44444,0,0,.6118],962:[.09722,.44444,.07917,0,.42361],963:[0,.44444,.03704,0,.68588],964:[0,.44444,.13472,0,.52083],965:[0,.44444,.03704,0,.63055],966:[.19444,.44444,0,0,.74722],967:[.19444,.44444,0,0,.71805],968:[.19444,.69444,.03704,0,.75833],969:[0,.44444,.03704,0,.71782],977:[0,.69444,0,0,.69155],981:[.19444,.69444,0,0,.7125],982:[0,.44444,.03194,0,.975],1009:[.19444,.44444,0,0,.6118],1013:[0,.44444,0,0,.48333],57649:[0,.44444,0,0,.39352],57911:[.19444,.44444,0,0,.43889]},"Math-Italic":{32:[0,0,0,0,.25],48:[0,.43056,0,0,.5],49:[0,.43056,0,0,.5],50:[0,.43056,0,0,.5],51:[.19444,.43056,0,0,.5],52:[.19444,.43056,0,0,.5],53:[.19444,.43056,0,0,.5],54:[0,.64444,0,0,.5],55:[.19444,.43056,0,0,.5],56:[0,.64444,0,0,.5],57:[.19444,.43056,0,0,.5],65:[0,.68333,0,.13889,.75],66:[0,.68333,.05017,.08334,.75851],67:[0,.68333,.07153,.08334,.71472],68:[0,.68333,.02778,.05556,.82792],69:[0,.68333,.05764,.08334,.7382],70:[0,.68333,.13889,.08334,.64306],71:[0,.68333,0,.08334,.78625],72:[0,.68333,.08125,.05556,.83125],73:[0,.68333,.07847,.11111,.43958],74:[0,.68333,.09618,.16667,.55451],75:[0,.68333,.07153,.05556,.84931],76:[0,.68333,0,.02778,.68056],77:[0,.68333,.10903,.08334,.97014],78:[0,.68333,.10903,.08334,.80347],79:[0,.68333,.02778,.08334,.76278],80:[0,.68333,.13889,.08334,.64201],81:[.19444,.68333,0,.08334,.79056],82:[0,.68333,.00773,.08334,.75929],83:[0,.68333,.05764,.08334,.6132],84:[0,.68333,.13889,.08334,.58438],85:[0,.68333,.10903,.02778,.68278],86:[0,.68333,.22222,0,.58333],87:[0,.68333,.13889,0,.94445],88:[0,.68333,.07847,.08334,.82847],89:[0,.68333,.22222,0,.58056],90:[0,.68333,.07153,.08334,.68264],97:[0,.43056,0,0,.52859],98:[0,.69444,0,0,.42917],99:[0,.43056,0,.05556,.43276],100:[0,.69444,0,.16667,.52049],101:[0,.43056,0,.05556,.46563],102:[.19444,.69444,.10764,.16667,.48959],103:[.19444,.43056,.03588,.02778,.47697],104:[0,.69444,0,0,.57616],105:[0,.65952,0,0,.34451],106:[.19444,.65952,.05724,0,.41181],107:[0,.69444,.03148,0,.5206],108:[0,.69444,.01968,.08334,.29838],109:[0,.43056,0,0,.87801],110:[0,.43056,0,0,.60023],111:[0,.43056,0,.05556,.48472],112:[.19444,.43056,0,.08334,.50313],113:[.19444,.43056,.03588,.08334,.44641],114:[0,.43056,.02778,.05556,.45116],115:[0,.43056,0,.05556,.46875],116:[0,.61508,0,.08334,.36111],117:[0,.43056,0,.02778,.57246],118:[0,.43056,.03588,.02778,.48472],119:[0,.43056,.02691,.08334,.71592],120:[0,.43056,0,.02778,.57153],121:[.19444,.43056,.03588,.05556,.49028],122:[0,.43056,.04398,.05556,.46505],160:[0,0,0,0,.25],915:[0,.68333,.13889,.08334,.61528],916:[0,.68333,0,.16667,.83334],920:[0,.68333,.02778,.08334,.76278],923:[0,.68333,0,.16667,.69445],926:[0,.68333,.07569,.08334,.74236],928:[0,.68333,.08125,.05556,.83125],931:[0,.68333,.05764,.08334,.77986],933:[0,.68333,.13889,.05556,.58333],934:[0,.68333,0,.08334,.66667],936:[0,.68333,.11,.05556,.61222],937:[0,.68333,.05017,.08334,.7724],945:[0,.43056,.0037,.02778,.6397],946:[.19444,.69444,.05278,.08334,.56563],947:[.19444,.43056,.05556,0,.51773],948:[0,.69444,.03785,.05556,.44444],949:[0,.43056,0,.08334,.46632],950:[.19444,.69444,.07378,.08334,.4375],951:[.19444,.43056,.03588,.05556,.49653],952:[0,.69444,.02778,.08334,.46944],953:[0,.43056,0,.05556,.35394],954:[0,.43056,0,0,.57616],955:[0,.69444,0,0,.58334],956:[.19444,.43056,0,.02778,.60255],957:[0,.43056,.06366,.02778,.49398],958:[.19444,.69444,.04601,.11111,.4375],959:[0,.43056,0,.05556,.48472],960:[0,.43056,.03588,0,.57003],961:[.19444,.43056,0,.08334,.51702],962:[.09722,.43056,.07986,.08334,.36285],963:[0,.43056,.03588,0,.57141],964:[0,.43056,.1132,.02778,.43715],965:[0,.43056,.03588,.02778,.54028],966:[.19444,.43056,0,.08334,.65417],967:[.19444,.43056,0,.05556,.62569],968:[.19444,.69444,.03588,.11111,.65139],969:[0,.43056,.03588,0,.62245],977:[0,.69444,0,.08334,.59144],981:[.19444,.69444,0,.08334,.59583],982:[0,.43056,.02778,0,.82813],1009:[.19444,.43056,0,.08334,.51702],1013:[0,.43056,0,.05556,.4059],57649:[0,.43056,0,.02778,.32246],57911:[.19444,.43056,0,.08334,.38403]},"SansSerif-Bold":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.36667],34:[0,.69444,0,0,.55834],35:[.19444,.69444,0,0,.91667],36:[.05556,.75,0,0,.55],37:[.05556,.75,0,0,1.02912],38:[0,.69444,0,0,.83056],39:[0,.69444,0,0,.30556],40:[.25,.75,0,0,.42778],41:[.25,.75,0,0,.42778],42:[0,.75,0,0,.55],43:[.11667,.61667,0,0,.85556],44:[.10556,.13056,0,0,.30556],45:[0,.45833,0,0,.36667],46:[0,.13056,0,0,.30556],47:[.25,.75,0,0,.55],48:[0,.69444,0,0,.55],49:[0,.69444,0,0,.55],50:[0,.69444,0,0,.55],51:[0,.69444,0,0,.55],52:[0,.69444,0,0,.55],53:[0,.69444,0,0,.55],54:[0,.69444,0,0,.55],55:[0,.69444,0,0,.55],56:[0,.69444,0,0,.55],57:[0,.69444,0,0,.55],58:[0,.45833,0,0,.30556],59:[.10556,.45833,0,0,.30556],61:[-.09375,.40625,0,0,.85556],63:[0,.69444,0,0,.51945],64:[0,.69444,0,0,.73334],65:[0,.69444,0,0,.73334],66:[0,.69444,0,0,.73334],67:[0,.69444,0,0,.70278],68:[0,.69444,0,0,.79445],69:[0,.69444,0,0,.64167],70:[0,.69444,0,0,.61111],71:[0,.69444,0,0,.73334],72:[0,.69444,0,0,.79445],73:[0,.69444,0,0,.33056],74:[0,.69444,0,0,.51945],75:[0,.69444,0,0,.76389],76:[0,.69444,0,0,.58056],77:[0,.69444,0,0,.97778],78:[0,.69444,0,0,.79445],79:[0,.69444,0,0,.79445],80:[0,.69444,0,0,.70278],81:[.10556,.69444,0,0,.79445],82:[0,.69444,0,0,.70278],83:[0,.69444,0,0,.61111],84:[0,.69444,0,0,.73334],85:[0,.69444,0,0,.76389],86:[0,.69444,.01528,0,.73334],87:[0,.69444,.01528,0,1.03889],88:[0,.69444,0,0,.73334],89:[0,.69444,.0275,0,.73334],90:[0,.69444,0,0,.67223],91:[.25,.75,0,0,.34306],93:[.25,.75,0,0,.34306],94:[0,.69444,0,0,.55],95:[.35,.10833,.03056,0,.55],97:[0,.45833,0,0,.525],98:[0,.69444,0,0,.56111],99:[0,.45833,0,0,.48889],100:[0,.69444,0,0,.56111],101:[0,.45833,0,0,.51111],102:[0,.69444,.07639,0,.33611],103:[.19444,.45833,.01528,0,.55],104:[0,.69444,0,0,.56111],105:[0,.69444,0,0,.25556],106:[.19444,.69444,0,0,.28611],107:[0,.69444,0,0,.53056],108:[0,.69444,0,0,.25556],109:[0,.45833,0,0,.86667],110:[0,.45833,0,0,.56111],111:[0,.45833,0,0,.55],112:[.19444,.45833,0,0,.56111],113:[.19444,.45833,0,0,.56111],114:[0,.45833,.01528,0,.37222],115:[0,.45833,0,0,.42167],116:[0,.58929,0,0,.40417],117:[0,.45833,0,0,.56111],118:[0,.45833,.01528,0,.5],119:[0,.45833,.01528,0,.74445],120:[0,.45833,0,0,.5],121:[.19444,.45833,.01528,0,.5],122:[0,.45833,0,0,.47639],126:[.35,.34444,0,0,.55],160:[0,0,0,0,.25],168:[0,.69444,0,0,.55],176:[0,.69444,0,0,.73334],180:[0,.69444,0,0,.55],184:[.17014,0,0,0,.48889],305:[0,.45833,0,0,.25556],567:[.19444,.45833,0,0,.28611],710:[0,.69444,0,0,.55],711:[0,.63542,0,0,.55],713:[0,.63778,0,0,.55],728:[0,.69444,0,0,.55],729:[0,.69444,0,0,.30556],730:[0,.69444,0,0,.73334],732:[0,.69444,0,0,.55],733:[0,.69444,0,0,.55],915:[0,.69444,0,0,.58056],916:[0,.69444,0,0,.91667],920:[0,.69444,0,0,.85556],923:[0,.69444,0,0,.67223],926:[0,.69444,0,0,.73334],928:[0,.69444,0,0,.79445],931:[0,.69444,0,0,.79445],933:[0,.69444,0,0,.85556],934:[0,.69444,0,0,.79445],936:[0,.69444,0,0,.85556],937:[0,.69444,0,0,.79445],8211:[0,.45833,.03056,0,.55],8212:[0,.45833,.03056,0,1.10001],8216:[0,.69444,0,0,.30556],8217:[0,.69444,0,0,.30556],8220:[0,.69444,0,0,.55834],8221:[0,.69444,0,0,.55834]},"SansSerif-Italic":{32:[0,0,0,0,.25],33:[0,.69444,.05733,0,.31945],34:[0,.69444,.00316,0,.5],35:[.19444,.69444,.05087,0,.83334],36:[.05556,.75,.11156,0,.5],37:[.05556,.75,.03126,0,.83334],38:[0,.69444,.03058,0,.75834],39:[0,.69444,.07816,0,.27778],40:[.25,.75,.13164,0,.38889],41:[.25,.75,.02536,0,.38889],42:[0,.75,.11775,0,.5],43:[.08333,.58333,.02536,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,.01946,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,.13164,0,.5],48:[0,.65556,.11156,0,.5],49:[0,.65556,.11156,0,.5],50:[0,.65556,.11156,0,.5],51:[0,.65556,.11156,0,.5],52:[0,.65556,.11156,0,.5],53:[0,.65556,.11156,0,.5],54:[0,.65556,.11156,0,.5],55:[0,.65556,.11156,0,.5],56:[0,.65556,.11156,0,.5],57:[0,.65556,.11156,0,.5],58:[0,.44444,.02502,0,.27778],59:[.125,.44444,.02502,0,.27778],61:[-.13,.37,.05087,0,.77778],63:[0,.69444,.11809,0,.47222],64:[0,.69444,.07555,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,.08293,0,.66667],67:[0,.69444,.11983,0,.63889],68:[0,.69444,.07555,0,.72223],69:[0,.69444,.11983,0,.59722],70:[0,.69444,.13372,0,.56945],71:[0,.69444,.11983,0,.66667],72:[0,.69444,.08094,0,.70834],73:[0,.69444,.13372,0,.27778],74:[0,.69444,.08094,0,.47222],75:[0,.69444,.11983,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,.08094,0,.875],78:[0,.69444,.08094,0,.70834],79:[0,.69444,.07555,0,.73611],80:[0,.69444,.08293,0,.63889],81:[.125,.69444,.07555,0,.73611],82:[0,.69444,.08293,0,.64584],83:[0,.69444,.09205,0,.55556],84:[0,.69444,.13372,0,.68056],85:[0,.69444,.08094,0,.6875],86:[0,.69444,.1615,0,.66667],87:[0,.69444,.1615,0,.94445],88:[0,.69444,.13372,0,.66667],89:[0,.69444,.17261,0,.66667],90:[0,.69444,.11983,0,.61111],91:[.25,.75,.15942,0,.28889],93:[.25,.75,.08719,0,.28889],94:[0,.69444,.0799,0,.5],95:[.35,.09444,.08616,0,.5],97:[0,.44444,.00981,0,.48056],98:[0,.69444,.03057,0,.51667],99:[0,.44444,.08336,0,.44445],100:[0,.69444,.09483,0,.51667],101:[0,.44444,.06778,0,.44445],102:[0,.69444,.21705,0,.30556],103:[.19444,.44444,.10836,0,.5],104:[0,.69444,.01778,0,.51667],105:[0,.67937,.09718,0,.23889],106:[.19444,.67937,.09162,0,.26667],107:[0,.69444,.08336,0,.48889],108:[0,.69444,.09483,0,.23889],109:[0,.44444,.01778,0,.79445],110:[0,.44444,.01778,0,.51667],111:[0,.44444,.06613,0,.5],112:[.19444,.44444,.0389,0,.51667],113:[.19444,.44444,.04169,0,.51667],114:[0,.44444,.10836,0,.34167],115:[0,.44444,.0778,0,.38333],116:[0,.57143,.07225,0,.36111],117:[0,.44444,.04169,0,.51667],118:[0,.44444,.10836,0,.46111],119:[0,.44444,.10836,0,.68334],120:[0,.44444,.09169,0,.46111],121:[.19444,.44444,.10836,0,.46111],122:[0,.44444,.08752,0,.43472],126:[.35,.32659,.08826,0,.5],160:[0,0,0,0,.25],168:[0,.67937,.06385,0,.5],176:[0,.69444,0,0,.73752],184:[.17014,0,0,0,.44445],305:[0,.44444,.04169,0,.23889],567:[.19444,.44444,.04169,0,.26667],710:[0,.69444,.0799,0,.5],711:[0,.63194,.08432,0,.5],713:[0,.60889,.08776,0,.5],714:[0,.69444,.09205,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,.09483,0,.5],729:[0,.67937,.07774,0,.27778],730:[0,.69444,0,0,.73752],732:[0,.67659,.08826,0,.5],733:[0,.69444,.09205,0,.5],915:[0,.69444,.13372,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,.07555,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,.12816,0,.66667],928:[0,.69444,.08094,0,.70834],931:[0,.69444,.11983,0,.72222],933:[0,.69444,.09031,0,.77778],934:[0,.69444,.04603,0,.72222],936:[0,.69444,.09031,0,.77778],937:[0,.69444,.08293,0,.72222],8211:[0,.44444,.08616,0,.5],8212:[0,.44444,.08616,0,1],8216:[0,.69444,.07816,0,.27778],8217:[0,.69444,.07816,0,.27778],8220:[0,.69444,.14205,0,.5],8221:[0,.69444,.00316,0,.5]},"SansSerif-Regular":{32:[0,0,0,0,.25],33:[0,.69444,0,0,.31945],34:[0,.69444,0,0,.5],35:[.19444,.69444,0,0,.83334],36:[.05556,.75,0,0,.5],37:[.05556,.75,0,0,.83334],38:[0,.69444,0,0,.75834],39:[0,.69444,0,0,.27778],40:[.25,.75,0,0,.38889],41:[.25,.75,0,0,.38889],42:[0,.75,0,0,.5],43:[.08333,.58333,0,0,.77778],44:[.125,.08333,0,0,.27778],45:[0,.44444,0,0,.33333],46:[0,.08333,0,0,.27778],47:[.25,.75,0,0,.5],48:[0,.65556,0,0,.5],49:[0,.65556,0,0,.5],50:[0,.65556,0,0,.5],51:[0,.65556,0,0,.5],52:[0,.65556,0,0,.5],53:[0,.65556,0,0,.5],54:[0,.65556,0,0,.5],55:[0,.65556,0,0,.5],56:[0,.65556,0,0,.5],57:[0,.65556,0,0,.5],58:[0,.44444,0,0,.27778],59:[.125,.44444,0,0,.27778],61:[-.13,.37,0,0,.77778],63:[0,.69444,0,0,.47222],64:[0,.69444,0,0,.66667],65:[0,.69444,0,0,.66667],66:[0,.69444,0,0,.66667],67:[0,.69444,0,0,.63889],68:[0,.69444,0,0,.72223],69:[0,.69444,0,0,.59722],70:[0,.69444,0,0,.56945],71:[0,.69444,0,0,.66667],72:[0,.69444,0,0,.70834],73:[0,.69444,0,0,.27778],74:[0,.69444,0,0,.47222],75:[0,.69444,0,0,.69445],76:[0,.69444,0,0,.54167],77:[0,.69444,0,0,.875],78:[0,.69444,0,0,.70834],79:[0,.69444,0,0,.73611],80:[0,.69444,0,0,.63889],81:[.125,.69444,0,0,.73611],82:[0,.69444,0,0,.64584],83:[0,.69444,0,0,.55556],84:[0,.69444,0,0,.68056],85:[0,.69444,0,0,.6875],86:[0,.69444,.01389,0,.66667],87:[0,.69444,.01389,0,.94445],88:[0,.69444,0,0,.66667],89:[0,.69444,.025,0,.66667],90:[0,.69444,0,0,.61111],91:[.25,.75,0,0,.28889],93:[.25,.75,0,0,.28889],94:[0,.69444,0,0,.5],95:[.35,.09444,.02778,0,.5],97:[0,.44444,0,0,.48056],98:[0,.69444,0,0,.51667],99:[0,.44444,0,0,.44445],100:[0,.69444,0,0,.51667],101:[0,.44444,0,0,.44445],102:[0,.69444,.06944,0,.30556],103:[.19444,.44444,.01389,0,.5],104:[0,.69444,0,0,.51667],105:[0,.67937,0,0,.23889],106:[.19444,.67937,0,0,.26667],107:[0,.69444,0,0,.48889],108:[0,.69444,0,0,.23889],109:[0,.44444,0,0,.79445],110:[0,.44444,0,0,.51667],111:[0,.44444,0,0,.5],112:[.19444,.44444,0,0,.51667],113:[.19444,.44444,0,0,.51667],114:[0,.44444,.01389,0,.34167],115:[0,.44444,0,0,.38333],116:[0,.57143,0,0,.36111],117:[0,.44444,0,0,.51667],118:[0,.44444,.01389,0,.46111],119:[0,.44444,.01389,0,.68334],120:[0,.44444,0,0,.46111],121:[.19444,.44444,.01389,0,.46111],122:[0,.44444,0,0,.43472],126:[.35,.32659,0,0,.5],160:[0,0,0,0,.25],168:[0,.67937,0,0,.5],176:[0,.69444,0,0,.66667],184:[.17014,0,0,0,.44445],305:[0,.44444,0,0,.23889],567:[.19444,.44444,0,0,.26667],710:[0,.69444,0,0,.5],711:[0,.63194,0,0,.5],713:[0,.60889,0,0,.5],714:[0,.69444,0,0,.5],715:[0,.69444,0,0,.5],728:[0,.69444,0,0,.5],729:[0,.67937,0,0,.27778],730:[0,.69444,0,0,.66667],732:[0,.67659,0,0,.5],733:[0,.69444,0,0,.5],915:[0,.69444,0,0,.54167],916:[0,.69444,0,0,.83334],920:[0,.69444,0,0,.77778],923:[0,.69444,0,0,.61111],926:[0,.69444,0,0,.66667],928:[0,.69444,0,0,.70834],931:[0,.69444,0,0,.72222],933:[0,.69444,0,0,.77778],934:[0,.69444,0,0,.72222],936:[0,.69444,0,0,.77778],937:[0,.69444,0,0,.72222],8211:[0,.44444,.02778,0,.5],8212:[0,.44444,.02778,0,1],8216:[0,.69444,0,0,.27778],8217:[0,.69444,0,0,.27778],8220:[0,.69444,0,0,.5],8221:[0,.69444,0,0,.5]},"Script-Regular":{32:[0,0,0,0,.25],65:[0,.7,.22925,0,.80253],66:[0,.7,.04087,0,.90757],67:[0,.7,.1689,0,.66619],68:[0,.7,.09371,0,.77443],69:[0,.7,.18583,0,.56162],70:[0,.7,.13634,0,.89544],71:[0,.7,.17322,0,.60961],72:[0,.7,.29694,0,.96919],73:[0,.7,.19189,0,.80907],74:[.27778,.7,.19189,0,1.05159],75:[0,.7,.31259,0,.91364],76:[0,.7,.19189,0,.87373],77:[0,.7,.15981,0,1.08031],78:[0,.7,.3525,0,.9015],79:[0,.7,.08078,0,.73787],80:[0,.7,.08078,0,1.01262],81:[0,.7,.03305,0,.88282],82:[0,.7,.06259,0,.85],83:[0,.7,.19189,0,.86767],84:[0,.7,.29087,0,.74697],85:[0,.7,.25815,0,.79996],86:[0,.7,.27523,0,.62204],87:[0,.7,.27523,0,.80532],88:[0,.7,.26006,0,.94445],89:[0,.7,.2939,0,.70961],90:[0,.7,.24037,0,.8212],160:[0,0,0,0,.25]},"Size1-Regular":{32:[0,0,0,0,.25],40:[.35001,.85,0,0,.45834],41:[.35001,.85,0,0,.45834],47:[.35001,.85,0,0,.57778],91:[.35001,.85,0,0,.41667],92:[.35001,.85,0,0,.57778],93:[.35001,.85,0,0,.41667],123:[.35001,.85,0,0,.58334],125:[.35001,.85,0,0,.58334],160:[0,0,0,0,.25],710:[0,.72222,0,0,.55556],732:[0,.72222,0,0,.55556],770:[0,.72222,0,0,.55556],771:[0,.72222,0,0,.55556],8214:[-99e-5,.601,0,0,.77778],8593:[1e-5,.6,0,0,.66667],8595:[1e-5,.6,0,0,.66667],8657:[1e-5,.6,0,0,.77778],8659:[1e-5,.6,0,0,.77778],8719:[.25001,.75,0,0,.94445],8720:[.25001,.75,0,0,.94445],8721:[.25001,.75,0,0,1.05556],8730:[.35001,.85,0,0,1],8739:[-.00599,.606,0,0,.33333],8741:[-.00599,.606,0,0,.55556],8747:[.30612,.805,.19445,0,.47222],8748:[.306,.805,.19445,0,.47222],8749:[.306,.805,.19445,0,.47222],8750:[.30612,.805,.19445,0,.47222],8896:[.25001,.75,0,0,.83334],8897:[.25001,.75,0,0,.83334],8898:[.25001,.75,0,0,.83334],8899:[.25001,.75,0,0,.83334],8968:[.35001,.85,0,0,.47222],8969:[.35001,.85,0,0,.47222],8970:[.35001,.85,0,0,.47222],8971:[.35001,.85,0,0,.47222],9168:[-99e-5,.601,0,0,.66667],10216:[.35001,.85,0,0,.47222],10217:[.35001,.85,0,0,.47222],10752:[.25001,.75,0,0,1.11111],10753:[.25001,.75,0,0,1.11111],10754:[.25001,.75,0,0,1.11111],10756:[.25001,.75,0,0,.83334],10758:[.25001,.75,0,0,.83334]},"Size2-Regular":{32:[0,0,0,0,.25],40:[.65002,1.15,0,0,.59722],41:[.65002,1.15,0,0,.59722],47:[.65002,1.15,0,0,.81111],91:[.65002,1.15,0,0,.47222],92:[.65002,1.15,0,0,.81111],93:[.65002,1.15,0,0,.47222],123:[.65002,1.15,0,0,.66667],125:[.65002,1.15,0,0,.66667],160:[0,0,0,0,.25],710:[0,.75,0,0,1],732:[0,.75,0,0,1],770:[0,.75,0,0,1],771:[0,.75,0,0,1],8719:[.55001,1.05,0,0,1.27778],8720:[.55001,1.05,0,0,1.27778],8721:[.55001,1.05,0,0,1.44445],8730:[.65002,1.15,0,0,1],8747:[.86225,1.36,.44445,0,.55556],8748:[.862,1.36,.44445,0,.55556],8749:[.862,1.36,.44445,0,.55556],8750:[.86225,1.36,.44445,0,.55556],8896:[.55001,1.05,0,0,1.11111],8897:[.55001,1.05,0,0,1.11111],8898:[.55001,1.05,0,0,1.11111],8899:[.55001,1.05,0,0,1.11111],8968:[.65002,1.15,0,0,.52778],8969:[.65002,1.15,0,0,.52778],8970:[.65002,1.15,0,0,.52778],8971:[.65002,1.15,0,0,.52778],10216:[.65002,1.15,0,0,.61111],10217:[.65002,1.15,0,0,.61111],10752:[.55001,1.05,0,0,1.51112],10753:[.55001,1.05,0,0,1.51112],10754:[.55001,1.05,0,0,1.51112],10756:[.55001,1.05,0,0,1.11111],10758:[.55001,1.05,0,0,1.11111]},"Size3-Regular":{32:[0,0,0,0,.25],40:[.95003,1.45,0,0,.73611],41:[.95003,1.45,0,0,.73611],47:[.95003,1.45,0,0,1.04445],91:[.95003,1.45,0,0,.52778],92:[.95003,1.45,0,0,1.04445],93:[.95003,1.45,0,0,.52778],123:[.95003,1.45,0,0,.75],125:[.95003,1.45,0,0,.75],160:[0,0,0,0,.25],710:[0,.75,0,0,1.44445],732:[0,.75,0,0,1.44445],770:[0,.75,0,0,1.44445],771:[0,.75,0,0,1.44445],8730:[.95003,1.45,0,0,1],8968:[.95003,1.45,0,0,.58334],8969:[.95003,1.45,0,0,.58334],8970:[.95003,1.45,0,0,.58334],8971:[.95003,1.45,0,0,.58334],10216:[.95003,1.45,0,0,.75],10217:[.95003,1.45,0,0,.75]},"Size4-Regular":{32:[0,0,0,0,.25],40:[1.25003,1.75,0,0,.79167],41:[1.25003,1.75,0,0,.79167],47:[1.25003,1.75,0,0,1.27778],91:[1.25003,1.75,0,0,.58334],92:[1.25003,1.75,0,0,1.27778],93:[1.25003,1.75,0,0,.58334],123:[1.25003,1.75,0,0,.80556],125:[1.25003,1.75,0,0,.80556],160:[0,0,0,0,.25],710:[0,.825,0,0,1.8889],732:[0,.825,0,0,1.8889],770:[0,.825,0,0,1.8889],771:[0,.825,0,0,1.8889],8730:[1.25003,1.75,0,0,1],8968:[1.25003,1.75,0,0,.63889],8969:[1.25003,1.75,0,0,.63889],8970:[1.25003,1.75,0,0,.63889],8971:[1.25003,1.75,0,0,.63889],9115:[.64502,1.155,0,0,.875],9116:[1e-5,.6,0,0,.875],9117:[.64502,1.155,0,0,.875],9118:[.64502,1.155,0,0,.875],9119:[1e-5,.6,0,0,.875],9120:[.64502,1.155,0,0,.875],9121:[.64502,1.155,0,0,.66667],9122:[-99e-5,.601,0,0,.66667],9123:[.64502,1.155,0,0,.66667],9124:[.64502,1.155,0,0,.66667],9125:[-99e-5,.601,0,0,.66667],9126:[.64502,1.155,0,0,.66667],9127:[1e-5,.9,0,0,.88889],9128:[.65002,1.15,0,0,.88889],9129:[.90001,0,0,0,.88889],9130:[0,.3,0,0,.88889],9131:[1e-5,.9,0,0,.88889],9132:[.65002,1.15,0,0,.88889],9133:[.90001,0,0,0,.88889],9143:[.88502,.915,0,0,1.05556],10216:[1.25003,1.75,0,0,.80556],10217:[1.25003,1.75,0,0,.80556],57344:[-.00499,.605,0,0,1.05556],57345:[-.00499,.605,0,0,1.05556],57680:[0,.12,0,0,.45],57681:[0,.12,0,0,.45],57682:[0,.12,0,0,.45],57683:[0,.12,0,0,.45]},"Typewriter-Regular":{32:[0,0,0,0,.525],33:[0,.61111,0,0,.525],34:[0,.61111,0,0,.525],35:[0,.61111,0,0,.525],36:[.08333,.69444,0,0,.525],37:[.08333,.69444,0,0,.525],38:[0,.61111,0,0,.525],39:[0,.61111,0,0,.525],40:[.08333,.69444,0,0,.525],41:[.08333,.69444,0,0,.525],42:[0,.52083,0,0,.525],43:[-.08056,.53055,0,0,.525],44:[.13889,.125,0,0,.525],45:[-.08056,.53055,0,0,.525],46:[0,.125,0,0,.525],47:[.08333,.69444,0,0,.525],48:[0,.61111,0,0,.525],49:[0,.61111,0,0,.525],50:[0,.61111,0,0,.525],51:[0,.61111,0,0,.525],52:[0,.61111,0,0,.525],53:[0,.61111,0,0,.525],54:[0,.61111,0,0,.525],55:[0,.61111,0,0,.525],56:[0,.61111,0,0,.525],57:[0,.61111,0,0,.525],58:[0,.43056,0,0,.525],59:[.13889,.43056,0,0,.525],60:[-.05556,.55556,0,0,.525],61:[-.19549,.41562,0,0,.525],62:[-.05556,.55556,0,0,.525],63:[0,.61111,0,0,.525],64:[0,.61111,0,0,.525],65:[0,.61111,0,0,.525],66:[0,.61111,0,0,.525],67:[0,.61111,0,0,.525],68:[0,.61111,0,0,.525],69:[0,.61111,0,0,.525],70:[0,.61111,0,0,.525],71:[0,.61111,0,0,.525],72:[0,.61111,0,0,.525],73:[0,.61111,0,0,.525],74:[0,.61111,0,0,.525],75:[0,.61111,0,0,.525],76:[0,.61111,0,0,.525],77:[0,.61111,0,0,.525],78:[0,.61111,0,0,.525],79:[0,.61111,0,0,.525],80:[0,.61111,0,0,.525],81:[.13889,.61111,0,0,.525],82:[0,.61111,0,0,.525],83:[0,.61111,0,0,.525],84:[0,.61111,0,0,.525],85:[0,.61111,0,0,.525],86:[0,.61111,0,0,.525],87:[0,.61111,0,0,.525],88:[0,.61111,0,0,.525],89:[0,.61111,0,0,.525],90:[0,.61111,0,0,.525],91:[.08333,.69444,0,0,.525],92:[.08333,.69444,0,0,.525],93:[.08333,.69444,0,0,.525],94:[0,.61111,0,0,.525],95:[.09514,0,0,0,.525],96:[0,.61111,0,0,.525],97:[0,.43056,0,0,.525],98:[0,.61111,0,0,.525],99:[0,.43056,0,0,.525],100:[0,.61111,0,0,.525],101:[0,.43056,0,0,.525],102:[0,.61111,0,0,.525],103:[.22222,.43056,0,0,.525],104:[0,.61111,0,0,.525],105:[0,.61111,0,0,.525],106:[.22222,.61111,0,0,.525],107:[0,.61111,0,0,.525],108:[0,.61111,0,0,.525],109:[0,.43056,0,0,.525],110:[0,.43056,0,0,.525],111:[0,.43056,0,0,.525],112:[.22222,.43056,0,0,.525],113:[.22222,.43056,0,0,.525],114:[0,.43056,0,0,.525],115:[0,.43056,0,0,.525],116:[0,.55358,0,0,.525],117:[0,.43056,0,0,.525],118:[0,.43056,0,0,.525],119:[0,.43056,0,0,.525],120:[0,.43056,0,0,.525],121:[.22222,.43056,0,0,.525],122:[0,.43056,0,0,.525],123:[.08333,.69444,0,0,.525],124:[.08333,.69444,0,0,.525],125:[.08333,.69444,0,0,.525],126:[0,.61111,0,0,.525],127:[0,.61111,0,0,.525],160:[0,0,0,0,.525],176:[0,.61111,0,0,.525],184:[.19445,0,0,0,.525],305:[0,.43056,0,0,.525],567:[.22222,.43056,0,0,.525],711:[0,.56597,0,0,.525],713:[0,.56555,0,0,.525],714:[0,.61111,0,0,.525],715:[0,.61111,0,0,.525],728:[0,.61111,0,0,.525],730:[0,.61111,0,0,.525],770:[0,.61111,0,0,.525],771:[0,.61111,0,0,.525],776:[0,.61111,0,0,.525],915:[0,.61111,0,0,.525],916:[0,.61111,0,0,.525],920:[0,.61111,0,0,.525],923:[0,.61111,0,0,.525],926:[0,.61111,0,0,.525],928:[0,.61111,0,0,.525],931:[0,.61111,0,0,.525],933:[0,.61111,0,0,.525],934:[0,.61111,0,0,.525],936:[0,.61111,0,0,.525],937:[0,.61111,0,0,.525],8216:[0,.61111,0,0,.525],8217:[0,.61111,0,0,.525],8242:[0,.61111,0,0,.525],9251:[.11111,.21944,0,0,.525]}},V={slant:[.25,.25,.25],space:[0,0,0],stretch:[0,0,0],shrink:[0,0,0],xHeight:[.431,.431,.431],quad:[1,1.171,1.472],extraSpace:[0,0,0],num1:[.677,.732,.925],num2:[.394,.384,.387],num3:[.444,.471,.504],denom1:[.686,.752,1.025],denom2:[.345,.344,.532],sup1:[.413,.503,.504],sup2:[.363,.431,.404],sup3:[.289,.286,.294],sub1:[.15,.143,.2],sub2:[.247,.286,.4],supDrop:[.386,.353,.494],subDrop:[.05,.071,.1],delim1:[2.39,1.7,1.98],delim2:[1.01,1.157,1.42],axisHeight:[.25,.25,.25],defaultRuleThickness:[.04,.049,.049],bigOpSpacing1:[.111,.111,.111],bigOpSpacing2:[.166,.166,.166],bigOpSpacing3:[.2,.2,.2],bigOpSpacing4:[.6,.611,.611],bigOpSpacing5:[.1,.143,.143],sqrtRuleThickness:[.04,.04,.04],ptPerEm:[10,10,10],doubleRuleSep:[.2,.2,.2],arrayRuleWidth:[.04,.04,.04],fboxsep:[.3,.3,.3],fboxrule:[.04,.04,.04]},U={"\xc5":"A","\xc7":"C","\xd0":"D","\xde":"o","\xe5":"a","\xe7":"c","\xf0":"d","\xfe":"o","\u0410":"A","\u0411":"B","\u0412":"B","\u0413":"F","\u0414":"A","\u0415":"E","\u0416":"K","\u0417":"3","\u0418":"N","\u0419":"N","\u041a":"K","\u041b":"N","\u041c":"M","\u041d":"H","\u041e":"O","\u041f":"N","\u0420":"P","\u0421":"C","\u0422":"T","\u0423":"y","\u0424":"O","\u0425":"X","\u0426":"U","\u0427":"h","\u0428":"W","\u0429":"W","\u042a":"B","\u042b":"X","\u042c":"B","\u042d":"3","\u042e":"X","\u042f":"R","\u0430":"a","\u0431":"b","\u0432":"a","\u0433":"r","\u0434":"y","\u0435":"e","\u0436":"m","\u0437":"e","\u0438":"n","\u0439":"n","\u043a":"n","\u043b":"n","\u043c":"m","\u043d":"n","\u043e":"o","\u043f":"n","\u0440":"p","\u0441":"c","\u0442":"o","\u0443":"y","\u0444":"b","\u0445":"x","\u0446":"n","\u0447":"n","\u0448":"w","\u0449":"w","\u044a":"a","\u044b":"m","\u044c":"a","\u044d":"e","\u044e":"m","\u044f":"r"};function G(t,e,r){if(!F[e])throw new Error("Font metrics not found for font: "+e+".");var a=t.charCodeAt(0),n=F[e][a];if(!n&&t[0]in U&&(a=U[t[0]].charCodeAt(0),n=F[e][a]),n||"text"!==r||M(a)&&(n=F[e][77]),n)return{depth:n[0],height:n[1],italic:n[2],skew:n[3],width:n[4]}}var Y={};var W={bin:1,close:1,inner:1,open:1,punct:1,rel:1},X={"accent-token":1,mathord:1,"op-token":1,spacing:1,textord:1},_={math:{},text:{}},j=_;function $(t,e,r,a,n,i){_[t][n]={font:e,group:r,replace:a},i&&a&&(_[t][a]=_[t][n])}var Z="main",K="ams",J="bin",Q="mathord",tt="op-token",et="rel";$("math",Z,et,"\u2261","\\equiv",!0),$("math",Z,et,"\u227a","\\prec",!0),$("math",Z,et,"\u227b","\\succ",!0),$("math",Z,et,"\u223c","\\sim",!0),$("math",Z,et,"\u22a5","\\perp"),$("math",Z,et,"\u2aaf","\\preceq",!0),$("math",Z,et,"\u2ab0","\\succeq",!0),$("math",Z,et,"\u2243","\\simeq",!0),$("math",Z,et,"\u2223","\\mid",!0),$("math",Z,et,"\u226a","\\ll",!0),$("math",Z,et,"\u226b","\\gg",!0),$("math",Z,et,"\u224d","\\asymp",!0),$("math",Z,et,"\u2225","\\parallel"),$("math",Z,et,"\u22c8","\\bowtie",!0),$("math",Z,et,"\u2323","\\smile",!0),$("math",Z,et,"\u2291","\\sqsubseteq",!0),$("math",Z,et,"\u2292","\\sqsupseteq",!0),$("math",Z,et,"\u2250","\\doteq",!0),$("math",Z,et,"\u2322","\\frown",!0),$("math",Z,et,"\u220b","\\ni",!0),$("math",Z,et,"\u221d","\\propto",!0),$("math",Z,et,"\u22a2","\\vdash",!0),$("math",Z,et,"\u22a3","\\dashv",!0),$("math",Z,et,"\u220b","\\owns"),$("math",Z,"punct",".","\\ldotp"),$("math",Z,"punct","\u22c5","\\cdotp"),$("math",Z,"textord","#","\\#"),$("text",Z,"textord","#","\\#"),$("math",Z,"textord","&","\\&"),$("text",Z,"textord","&","\\&"),$("math",Z,"textord","\u2135","\\aleph",!0),$("math",Z,"textord","\u2200","\\forall",!0),$("math",Z,"textord","\u210f","\\hbar",!0),$("math",Z,"textord","\u2203","\\exists",!0),$("math",Z,"textord","\u2207","\\nabla",!0),$("math",Z,"textord","\u266d","\\flat",!0),$("math",Z,"textord","\u2113","\\ell",!0),$("math",Z,"textord","\u266e","\\natural",!0),$("math",Z,"textord","\u2663","\\clubsuit",!0),$("math",Z,"textord","\u2118","\\wp",!0),$("math",Z,"textord","\u266f","\\sharp",!0),$("math",Z,"textord","\u2662","\\diamondsuit",!0),$("math",Z,"textord","\u211c","\\Re",!0),$("math",Z,"textord","\u2661","\\heartsuit",!0),$("math",Z,"textord","\u2111","\\Im",!0),$("math",Z,"textord","\u2660","\\spadesuit",!0),$("text",Z,"textord","\xa7","\\S",!0),$("text",Z,"textord","\xb6","\\P",!0),$("math",Z,"textord","\u2020","\\dag"),$("text",Z,"textord","\u2020","\\dag"),$("text",Z,"textord","\u2020","\\textdagger"),$("math",Z,"textord","\u2021","\\ddag"),$("text",Z,"textord","\u2021","\\ddag"),$("text",Z,"textord","\u2021","\\textdaggerdbl"),$("math",Z,"close","\u23b1","\\rmoustache",!0),$("math",Z,"open","\u23b0","\\lmoustache",!0),$("math",Z,"close","\u27ef","\\rgroup",!0),$("math",Z,"open","\u27ee","\\lgroup",!0),$("math",Z,J,"\u2213","\\mp",!0),$("math",Z,J,"\u2296","\\ominus",!0),$("math",Z,J,"\u228e","\\uplus",!0),$("math",Z,J,"\u2293","\\sqcap",!0),$("math",Z,J,"\u2217","\\ast"),$("math",Z,J,"\u2294","\\sqcup",!0),$("math",Z,J,"\u25ef","\\bigcirc"),$("math",Z,J,"\u2219","\\bullet"),$("math",Z,J,"\u2021","\\ddagger"),$("math",Z,J,"\u2240","\\wr",!0),$("math",Z,J,"\u2a3f","\\amalg"),$("math",Z,J,"&","\\And"),$("math",Z,et,"\u27f5","\\longleftarrow",!0),$("math",Z,et,"\u21d0","\\Leftarrow",!0),$("math",Z,et,"\u27f8","\\Longleftarrow",!0),$("math",Z,et,"\u27f6","\\longrightarrow",!0),$("math",Z,et,"\u21d2","\\Rightarrow",!0),$("math",Z,et,"\u27f9","\\Longrightarrow",!0),$("math",Z,et,"\u2194","\\leftrightarrow",!0),$("math",Z,et,"\u27f7","\\longleftrightarrow",!0),$("math",Z,et,"\u21d4","\\Leftrightarrow",!0),$("math",Z,et,"\u27fa","\\Longleftrightarrow",!0),$("math",Z,et,"\u21a6","\\mapsto",!0),$("math",Z,et,"\u27fc","\\longmapsto",!0),$("math",Z,et,"\u2197","\\nearrow",!0),$("math",Z,et,"\u21a9","\\hookleftarrow",!0),$("math",Z,et,"\u21aa","\\hookrightarrow",!0),$("math",Z,et,"\u2198","\\searrow",!0),$("math",Z,et,"\u21bc","\\leftharpoonup",!0),$("math",Z,et,"\u21c0","\\rightharpoonup",!0),$("math",Z,et,"\u2199","\\swarrow",!0),$("math",Z,et,"\u21bd","\\leftharpoondown",!0),$("math",Z,et,"\u21c1","\\rightharpoondown",!0),$("math",Z,et,"\u2196","\\nwarrow",!0),$("math",Z,et,"\u21cc","\\rightleftharpoons",!0),$("math",K,et,"\u226e","\\nless",!0),$("math",K,et,"\ue010","\\@nleqslant"),$("math",K,et,"\ue011","\\@nleqq"),$("math",K,et,"\u2a87","\\lneq",!0),$("math",K,et,"\u2268","\\lneqq",!0),$("math",K,et,"\ue00c","\\@lvertneqq"),$("math",K,et,"\u22e6","\\lnsim",!0),$("math",K,et,"\u2a89","\\lnapprox",!0),$("math",K,et,"\u2280","\\nprec",!0),$("math",K,et,"\u22e0","\\npreceq",!0),$("math",K,et,"\u22e8","\\precnsim",!0),$("math",K,et,"\u2ab9","\\precnapprox",!0),$("math",K,et,"\u2241","\\nsim",!0),$("math",K,et,"\ue006","\\@nshortmid"),$("math",K,et,"\u2224","\\nmid",!0),$("math",K,et,"\u22ac","\\nvdash",!0),$("math",K,et,"\u22ad","\\nvDash",!0),$("math",K,et,"\u22ea","\\ntriangleleft"),$("math",K,et,"\u22ec","\\ntrianglelefteq",!0),$("math",K,et,"\u228a","\\subsetneq",!0),$("math",K,et,"\ue01a","\\@varsubsetneq"),$("math",K,et,"\u2acb","\\subsetneqq",!0),$("math",K,et,"\ue017","\\@varsubsetneqq"),$("math",K,et,"\u226f","\\ngtr",!0),$("math",K,et,"\ue00f","\\@ngeqslant"),$("math",K,et,"\ue00e","\\@ngeqq"),$("math",K,et,"\u2a88","\\gneq",!0),$("math",K,et,"\u2269","\\gneqq",!0),$("math",K,et,"\ue00d","\\@gvertneqq"),$("math",K,et,"\u22e7","\\gnsim",!0),$("math",K,et,"\u2a8a","\\gnapprox",!0),$("math",K,et,"\u2281","\\nsucc",!0),$("math",K,et,"\u22e1","\\nsucceq",!0),$("math",K,et,"\u22e9","\\succnsim",!0),$("math",K,et,"\u2aba","\\succnapprox",!0),$("math",K,et,"\u2246","\\ncong",!0),$("math",K,et,"\ue007","\\@nshortparallel"),$("math",K,et,"\u2226","\\nparallel",!0),$("math",K,et,"\u22af","\\nVDash",!0),$("math",K,et,"\u22eb","\\ntriangleright"),$("math",K,et,"\u22ed","\\ntrianglerighteq",!0),$("math",K,et,"\ue018","\\@nsupseteqq"),$("math",K,et,"\u228b","\\supsetneq",!0),$("math",K,et,"\ue01b","\\@varsupsetneq"),$("math",K,et,"\u2acc","\\supsetneqq",!0),$("math",K,et,"\ue019","\\@varsupsetneqq"),$("math",K,et,"\u22ae","\\nVdash",!0),$("math",K,et,"\u2ab5","\\precneqq",!0),$("math",K,et,"\u2ab6","\\succneqq",!0),$("math",K,et,"\ue016","\\@nsubseteqq"),$("math",K,J,"\u22b4","\\unlhd"),$("math",K,J,"\u22b5","\\unrhd"),$("math",K,et,"\u219a","\\nleftarrow",!0),$("math",K,et,"\u219b","\\nrightarrow",!0),$("math",K,et,"\u21cd","\\nLeftarrow",!0),$("math",K,et,"\u21cf","\\nRightarrow",!0),$("math",K,et,"\u21ae","\\nleftrightarrow",!0),$("math",K,et,"\u21ce","\\nLeftrightarrow",!0),$("math",K,et,"\u25b3","\\vartriangle"),$("math",K,"textord","\u210f","\\hslash"),$("math",K,"textord","\u25bd","\\triangledown"),$("math",K,"textord","\u25ca","\\lozenge"),$("math",K,"textord","\u24c8","\\circledS"),$("math",K,"textord","\xae","\\circledR"),$("text",K,"textord","\xae","\\circledR"),$("math",K,"textord","\u2221","\\measuredangle",!0),$("math",K,"textord","\u2204","\\nexists"),$("math",K,"textord","\u2127","\\mho"),$("math",K,"textord","\u2132","\\Finv",!0),$("math",K,"textord","\u2141","\\Game",!0),$("math",K,"textord","\u2035","\\backprime"),$("math",K,"textord","\u25b2","\\blacktriangle"),$("math",K,"textord","\u25bc","\\blacktriangledown"),$("math",K,"textord","\u25a0","\\blacksquare"),$("math",K,"textord","\u29eb","\\blacklozenge"),$("math",K,"textord","\u2605","\\bigstar"),$("math",K,"textord","\u2222","\\sphericalangle",!0),$("math",K,"textord","\u2201","\\complement",!0),$("math",K,"textord","\xf0","\\eth",!0),$("text",Z,"textord","\xf0","\xf0"),$("math",K,"textord","\u2571","\\diagup"),$("math",K,"textord","\u2572","\\diagdown"),$("math",K,"textord","\u25a1","\\square"),$("math",K,"textord","\u25a1","\\Box"),$("math",K,"textord","\u25ca","\\Diamond"),$("math",K,"textord","\xa5","\\yen",!0),$("text",K,"textord","\xa5","\\yen",!0),$("math",K,"textord","\u2713","\\checkmark",!0),$("text",K,"textord","\u2713","\\checkmark"),$("math",K,"textord","\u2136","\\beth",!0),$("math",K,"textord","\u2138","\\daleth",!0),$("math",K,"textord","\u2137","\\gimel",!0),$("math",K,"textord","\u03dd","\\digamma",!0),$("math",K,"textord","\u03f0","\\varkappa"),$("math",K,"open","\u250c","\\@ulcorner",!0),$("math",K,"close","\u2510","\\@urcorner",!0),$("math",K,"open","\u2514","\\@llcorner",!0),$("math",K,"close","\u2518","\\@lrcorner",!0),$("math",K,et,"\u2266","\\leqq",!0),$("math",K,et,"\u2a7d","\\leqslant",!0),$("math",K,et,"\u2a95","\\eqslantless",!0),$("math",K,et,"\u2272","\\lesssim",!0),$("math",K,et,"\u2a85","\\lessapprox",!0),$("math",K,et,"\u224a","\\approxeq",!0),$("math",K,J,"\u22d6","\\lessdot"),$("math",K,et,"\u22d8","\\lll",!0),$("math",K,et,"\u2276","\\lessgtr",!0),$("math",K,et,"\u22da","\\lesseqgtr",!0),$("math",K,et,"\u2a8b","\\lesseqqgtr",!0),$("math",K,et,"\u2251","\\doteqdot"),$("math",K,et,"\u2253","\\risingdotseq",!0),$("math",K,et,"\u2252","\\fallingdotseq",!0),$("math",K,et,"\u223d","\\backsim",!0),$("math",K,et,"\u22cd","\\backsimeq",!0),$("math",K,et,"\u2ac5","\\subseteqq",!0),$("math",K,et,"\u22d0","\\Subset",!0),$("math",K,et,"\u228f","\\sqsubset",!0),$("math",K,et,"\u227c","\\preccurlyeq",!0),$("math",K,et,"\u22de","\\curlyeqprec",!0),$("math",K,et,"\u227e","\\precsim",!0),$("math",K,et,"\u2ab7","\\precapprox",!0),$("math",K,et,"\u22b2","\\vartriangleleft"),$("math",K,et,"\u22b4","\\trianglelefteq"),$("math",K,et,"\u22a8","\\vDash",!0),$("math",K,et,"\u22aa","\\Vvdash",!0),$("math",K,et,"\u2323","\\smallsmile"),$("math",K,et,"\u2322","\\smallfrown"),$("math",K,et,"\u224f","\\bumpeq",!0),$("math",K,et,"\u224e","\\Bumpeq",!0),$("math",K,et,"\u2267","\\geqq",!0),$("math",K,et,"\u2a7e","\\geqslant",!0),$("math",K,et,"\u2a96","\\eqslantgtr",!0),$("math",K,et,"\u2273","\\gtrsim",!0),$("math",K,et,"\u2a86","\\gtrapprox",!0),$("math",K,J,"\u22d7","\\gtrdot"),$("math",K,et,"\u22d9","\\ggg",!0),$("math",K,et,"\u2277","\\gtrless",!0),$("math",K,et,"\u22db","\\gtreqless",!0),$("math",K,et,"\u2a8c","\\gtreqqless",!0),$("math",K,et,"\u2256","\\eqcirc",!0),$("math",K,et,"\u2257","\\circeq",!0),$("math",K,et,"\u225c","\\triangleq",!0),$("math",K,et,"\u223c","\\thicksim"),$("math",K,et,"\u2248","\\thickapprox"),$("math",K,et,"\u2ac6","\\supseteqq",!0),$("math",K,et,"\u22d1","\\Supset",!0),$("math",K,et,"\u2290","\\sqsupset",!0),$("math",K,et,"\u227d","\\succcurlyeq",!0),$("math",K,et,"\u22df","\\curlyeqsucc",!0),$("math",K,et,"\u227f","\\succsim",!0),$("math",K,et,"\u2ab8","\\succapprox",!0),$("math",K,et,"\u22b3","\\vartriangleright"),$("math",K,et,"\u22b5","\\trianglerighteq"),$("math",K,et,"\u22a9","\\Vdash",!0),$("math",K,et,"\u2223","\\shortmid"),$("math",K,et,"\u2225","\\shortparallel"),$("math",K,et,"\u226c","\\between",!0),$("math",K,et,"\u22d4","\\pitchfork",!0),$("math",K,et,"\u221d","\\varpropto"),$("math",K,et,"\u25c0","\\blacktriangleleft"),$("math",K,et,"\u2234","\\therefore",!0),$("math",K,et,"\u220d","\\backepsilon"),$("math",K,et,"\u25b6","\\blacktriangleright"),$("math",K,et,"\u2235","\\because",!0),$("math",K,et,"\u22d8","\\llless"),$("math",K,et,"\u22d9","\\gggtr"),$("math",K,J,"\u22b2","\\lhd"),$("math",K,J,"\u22b3","\\rhd"),$("math",K,et,"\u2242","\\eqsim",!0),$("math",Z,et,"\u22c8","\\Join"),$("math",K,et,"\u2251","\\Doteq",!0),$("math",K,J,"\u2214","\\dotplus",!0),$("math",K,J,"\u2216","\\smallsetminus"),$("math",K,J,"\u22d2","\\Cap",!0),$("math",K,J,"\u22d3","\\Cup",!0),$("math",K,J,"\u2a5e","\\doublebarwedge",!0),$("math",K,J,"\u229f","\\boxminus",!0),$("math",K,J,"\u229e","\\boxplus",!0),$("math",K,J,"\u22c7","\\divideontimes",!0),$("math",K,J,"\u22c9","\\ltimes",!0),$("math",K,J,"\u22ca","\\rtimes",!0),$("math",K,J,"\u22cb","\\leftthreetimes",!0),$("math",K,J,"\u22cc","\\rightthreetimes",!0),$("math",K,J,"\u22cf","\\curlywedge",!0),$("math",K,J,"\u22ce","\\curlyvee",!0),$("math",K,J,"\u229d","\\circleddash",!0),$("math",K,J,"\u229b","\\circledast",!0),$("math",K,J,"\u22c5","\\centerdot"),$("math",K,J,"\u22ba","\\intercal",!0),$("math",K,J,"\u22d2","\\doublecap"),$("math",K,J,"\u22d3","\\doublecup"),$("math",K,J,"\u22a0","\\boxtimes",!0),$("math",K,et,"\u21e2","\\dashrightarrow",!0),$("math",K,et,"\u21e0","\\dashleftarrow",!0),$("math",K,et,"\u21c7","\\leftleftarrows",!0),$("math",K,et,"\u21c6","\\leftrightarrows",!0),$("math",K,et,"\u21da","\\Lleftarrow",!0),$("math",K,et,"\u219e","\\twoheadleftarrow",!0),$("math",K,et,"\u21a2","\\leftarrowtail",!0),$("math",K,et,"\u21ab","\\looparrowleft",!0),$("math",K,et,"\u21cb","\\leftrightharpoons",!0),$("math",K,et,"\u21b6","\\curvearrowleft",!0),$("math",K,et,"\u21ba","\\circlearrowleft",!0),$("math",K,et,"\u21b0","\\Lsh",!0),$("math",K,et,"\u21c8","\\upuparrows",!0),$("math",K,et,"\u21bf","\\upharpoonleft",!0),$("math",K,et,"\u21c3","\\downharpoonleft",!0),$("math",K,et,"\u22b8","\\multimap",!0),$("math",K,et,"\u21ad","\\leftrightsquigarrow",!0),$("math",K,et,"\u21c9","\\rightrightarrows",!0),$("math",K,et,"\u21c4","\\rightleftarrows",!0),$("math",K,et,"\u21a0","\\twoheadrightarrow",!0),$("math",K,et,"\u21a3","\\rightarrowtail",!0),$("math",K,et,"\u21ac","\\looparrowright",!0),$("math",K,et,"\u21b7","\\curvearrowright",!0),$("math",K,et,"\u21bb","\\circlearrowright",!0),$("math",K,et,"\u21b1","\\Rsh",!0),$("math",K,et,"\u21ca","\\downdownarrows",!0),$("math",K,et,"\u21be","\\upharpoonright",!0),$("math",K,et,"\u21c2","\\downharpoonright",!0),$("math",K,et,"\u21dd","\\rightsquigarrow",!0),$("math",K,et,"\u21dd","\\leadsto"),$("math",K,et,"\u21db","\\Rrightarrow",!0),$("math",K,et,"\u21be","\\restriction"),$("math",Z,"textord","\u2018","`"),$("math",Z,"textord","$","\\$"),$("text",Z,"textord","$","\\$"),$("text",Z,"textord","$","\\textdollar"),$("math",Z,"textord","%","\\%"),$("text",Z,"textord","%","\\%"),$("math",Z,"textord","_","\\_"),$("text",Z,"textord","_","\\_"),$("text",Z,"textord","_","\\textunderscore"),$("math",Z,"textord","\u2220","\\angle",!0),$("math",Z,"textord","\u221e","\\infty",!0),$("math",Z,"textord","\u2032","\\prime"),$("math",Z,"textord","\u25b3","\\triangle"),$("math",Z,"textord","\u0393","\\Gamma",!0),$("math",Z,"textord","\u0394","\\Delta",!0),$("math",Z,"textord","\u0398","\\Theta",!0),$("math",Z,"textord","\u039b","\\Lambda",!0),$("math",Z,"textord","\u039e","\\Xi",!0),$("math",Z,"textord","\u03a0","\\Pi",!0),$("math",Z,"textord","\u03a3","\\Sigma",!0),$("math",Z,"textord","\u03a5","\\Upsilon",!0),$("math",Z,"textord","\u03a6","\\Phi",!0),$("math",Z,"textord","\u03a8","\\Psi",!0),$("math",Z,"textord","\u03a9","\\Omega",!0),$("math",Z,"textord","A","\u0391"),$("math",Z,"textord","B","\u0392"),$("math",Z,"textord","E","\u0395"),$("math",Z,"textord","Z","\u0396"),$("math",Z,"textord","H","\u0397"),$("math",Z,"textord","I","\u0399"),$("math",Z,"textord","K","\u039a"),$("math",Z,"textord","M","\u039c"),$("math",Z,"textord","N","\u039d"),$("math",Z,"textord","O","\u039f"),$("math",Z,"textord","P","\u03a1"),$("math",Z,"textord","T","\u03a4"),$("math",Z,"textord","X","\u03a7"),$("math",Z,"textord","\xac","\\neg",!0),$("math",Z,"textord","\xac","\\lnot"),$("math",Z,"textord","\u22a4","\\top"),$("math",Z,"textord","\u22a5","\\bot"),$("math",Z,"textord","\u2205","\\emptyset"),$("math",K,"textord","\u2205","\\varnothing"),$("math",Z,Q,"\u03b1","\\alpha",!0),$("math",Z,Q,"\u03b2","\\beta",!0),$("math",Z,Q,"\u03b3","\\gamma",!0),$("math",Z,Q,"\u03b4","\\delta",!0),$("math",Z,Q,"\u03f5","\\epsilon",!0),$("math",Z,Q,"\u03b6","\\zeta",!0),$("math",Z,Q,"\u03b7","\\eta",!0),$("math",Z,Q,"\u03b8","\\theta",!0),$("math",Z,Q,"\u03b9","\\iota",!0),$("math",Z,Q,"\u03ba","\\kappa",!0),$("math",Z,Q,"\u03bb","\\lambda",!0),$("math",Z,Q,"\u03bc","\\mu",!0),$("math",Z,Q,"\u03bd","\\nu",!0),$("math",Z,Q,"\u03be","\\xi",!0),$("math",Z,Q,"\u03bf","\\omicron",!0),$("math",Z,Q,"\u03c0","\\pi",!0),$("math",Z,Q,"\u03c1","\\rho",!0),$("math",Z,Q,"\u03c3","\\sigma",!0),$("math",Z,Q,"\u03c4","\\tau",!0),$("math",Z,Q,"\u03c5","\\upsilon",!0),$("math",Z,Q,"\u03d5","\\phi",!0),$("math",Z,Q,"\u03c7","\\chi",!0),$("math",Z,Q,"\u03c8","\\psi",!0),$("math",Z,Q,"\u03c9","\\omega",!0),$("math",Z,Q,"\u03b5","\\varepsilon",!0),$("math",Z,Q,"\u03d1","\\vartheta",!0),$("math",Z,Q,"\u03d6","\\varpi",!0),$("math",Z,Q,"\u03f1","\\varrho",!0),$("math",Z,Q,"\u03c2","\\varsigma",!0),$("math",Z,Q,"\u03c6","\\varphi",!0),$("math",Z,J,"\u2217","*"),$("math",Z,J,"+","+"),$("math",Z,J,"\u2212","-"),$("math",Z,J,"\u22c5","\\cdot",!0),$("math",Z,J,"\u2218","\\circ"),$("math",Z,J,"\xf7","\\div",!0),$("math",Z,J,"\xb1","\\pm",!0),$("math",Z,J,"\xd7","\\times",!0),$("math",Z,J,"\u2229","\\cap",!0),$("math",Z,J,"\u222a","\\cup",!0),$("math",Z,J,"\u2216","\\setminus"),$("math",Z,J,"\u2227","\\land"),$("math",Z,J,"\u2228","\\lor"),$("math",Z,J,"\u2227","\\wedge",!0),$("math",Z,J,"\u2228","\\vee",!0),$("math",Z,"textord","\u221a","\\surd"),$("math",Z,"open","\u27e8","\\langle",!0),$("math",Z,"open","\u2223","\\lvert"),$("math",Z,"open","\u2225","\\lVert"),$("math",Z,"close","?","?"),$("math",Z,"close","!","!"),$("math",Z,"close","\u27e9","\\rangle",!0),$("math",Z,"close","\u2223","\\rvert"),$("math",Z,"close","\u2225","\\rVert"),$("math",Z,et,"=","="),$("math",Z,et,":",":"),$("math",Z,et,"\u2248","\\approx",!0),$("math",Z,et,"\u2245","\\cong",!0),$("math",Z,et,"\u2265","\\ge"),$("math",Z,et,"\u2265","\\geq",!0),$("math",Z,et,"\u2190","\\gets"),$("math",Z,et,">","\\gt",!0),$("math",Z,et,"\u2208","\\in",!0),$("math",Z,et,"\ue020","\\@not"),$("math",Z,et,"\u2282","\\subset",!0),$("math",Z,et,"\u2283","\\supset",!0),$("math",Z,et,"\u2286","\\subseteq",!0),$("math",Z,et,"\u2287","\\supseteq",!0),$("math",K,et,"\u2288","\\nsubseteq",!0),$("math",K,et,"\u2289","\\nsupseteq",!0),$("math",Z,et,"\u22a8","\\models"),$("math",Z,et,"\u2190","\\leftarrow",!0),$("math",Z,et,"\u2264","\\le"),$("math",Z,et,"\u2264","\\leq",!0),$("math",Z,et,"<","\\lt",!0),$("math",Z,et,"\u2192","\\rightarrow",!0),$("math",Z,et,"\u2192","\\to"),$("math",K,et,"\u2271","\\ngeq",!0),$("math",K,et,"\u2270","\\nleq",!0),$("math",Z,"spacing","\xa0","\\ "),$("math",Z,"spacing","\xa0","~"),$("math",Z,"spacing","\xa0","\\space"),$("math",Z,"spacing","\xa0","\\nobreakspace"),$("text",Z,"spacing","\xa0","\\ "),$("text",Z,"spacing","\xa0"," "),$("text",Z,"spacing","\xa0","~"),$("text",Z,"spacing","\xa0","\\space"),$("text",Z,"spacing","\xa0","\\nobreakspace"),$("math",Z,"spacing",null,"\\nobreak"),$("math",Z,"spacing",null,"\\allowbreak"),$("math",Z,"punct",",",","),$("math",Z,"punct",";",";"),$("math",K,J,"\u22bc","\\barwedge",!0),$("math",K,J,"\u22bb","\\veebar",!0),$("math",Z,J,"\u2299","\\odot",!0),$("math",Z,J,"\u2295","\\oplus",!0),$("math",Z,J,"\u2297","\\otimes",!0),$("math",Z,"textord","\u2202","\\partial",!0),$("math",Z,J,"\u2298","\\oslash",!0),$("math",K,J,"\u229a","\\circledcirc",!0),$("math",K,J,"\u22a1","\\boxdot",!0),$("math",Z,J,"\u25b3","\\bigtriangleup"),$("math",Z,J,"\u25bd","\\bigtriangledown"),$("math",Z,J,"\u2020","\\dagger"),$("math",Z,J,"\u22c4","\\diamond"),$("math",Z,J,"\u22c6","\\star"),$("math",Z,J,"\u25c3","\\triangleleft"),$("math",Z,J,"\u25b9","\\triangleright"),$("math",Z,"open","{","\\{"),$("text",Z,"textord","{","\\{"),$("text",Z,"textord","{","\\textbraceleft"),$("math",Z,"close","}","\\}"),$("text",Z,"textord","}","\\}"),$("text",Z,"textord","}","\\textbraceright"),$("math",Z,"open","{","\\lbrace"),$("math",Z,"close","}","\\rbrace"),$("math",Z,"open","[","\\lbrack",!0),$("text",Z,"textord","[","\\lbrack",!0),$("math",Z,"close","]","\\rbrack",!0),$("text",Z,"textord","]","\\rbrack",!0),$("math",Z,"open","(","\\lparen",!0),$("math",Z,"close",")","\\rparen",!0),$("text",Z,"textord","<","\\textless",!0),$("text",Z,"textord",">","\\textgreater",!0),$("math",Z,"open","\u230a","\\lfloor",!0),$("math",Z,"close","\u230b","\\rfloor",!0),$("math",Z,"open","\u2308","\\lceil",!0),$("math",Z,"close","\u2309","\\rceil",!0),$("math",Z,"textord","\\","\\backslash"),$("math",Z,"textord","\u2223","|"),$("math",Z,"textord","\u2223","\\vert"),$("text",Z,"textord","|","\\textbar",!0),$("math",Z,"textord","\u2225","\\|"),$("math",Z,"textord","\u2225","\\Vert"),$("text",Z,"textord","\u2225","\\textbardbl"),$("text",Z,"textord","~","\\textasciitilde"),$("text",Z,"textord","\\","\\textbackslash"),$("text",Z,"textord","^","\\textasciicircum"),$("math",Z,et,"\u2191","\\uparrow",!0),$("math",Z,et,"\u21d1","\\Uparrow",!0),$("math",Z,et,"\u2193","\\downarrow",!0),$("math",Z,et,"\u21d3","\\Downarrow",!0),$("math",Z,et,"\u2195","\\updownarrow",!0),$("math",Z,et,"\u21d5","\\Updownarrow",!0),$("math",Z,tt,"\u2210","\\coprod"),$("math",Z,tt,"\u22c1","\\bigvee"),$("math",Z,tt,"\u22c0","\\bigwedge"),$("math",Z,tt,"\u2a04","\\biguplus"),$("math",Z,tt,"\u22c2","\\bigcap"),$("math",Z,tt,"\u22c3","\\bigcup"),$("math",Z,tt,"\u222b","\\int"),$("math",Z,tt,"\u222b","\\intop"),$("math",Z,tt,"\u222c","\\iint"),$("math",Z,tt,"\u222d","\\iiint"),$("math",Z,tt,"\u220f","\\prod"),$("math",Z,tt,"\u2211","\\sum"),$("math",Z,tt,"\u2a02","\\bigotimes"),$("math",Z,tt,"\u2a01","\\bigoplus"),$("math",Z,tt,"\u2a00","\\bigodot"),$("math",Z,tt,"\u222e","\\oint"),$("math",Z,tt,"\u2a06","\\bigsqcup"),$("math",Z,tt,"\u222b","\\smallint"),$("text",Z,"inner","\u2026","\\textellipsis"),$("math",Z,"inner","\u2026","\\mathellipsis"),$("text",Z,"inner","\u2026","\\ldots",!0),$("math",Z,"inner","\u2026","\\ldots",!0),$("math",Z,"inner","\u22ef","\\@cdots",!0),$("math",Z,"inner","\u22f1","\\ddots",!0),$("math",Z,"textord","\u22ee","\\varvdots"),$("math",Z,"accent-token","\u02ca","\\acute"),$("math",Z,"accent-token","\u02cb","\\grave"),$("math",Z,"accent-token","\xa8","\\ddot"),$("math",Z,"accent-token","~","\\tilde"),$("math",Z,"accent-token","\u02c9","\\bar"),$("math",Z,"accent-token","\u02d8","\\breve"),$("math",Z,"accent-token","\u02c7","\\check"),$("math",Z,"accent-token","^","\\hat"),$("math",Z,"accent-token","\u20d7","\\vec"),$("math",Z,"accent-token","\u02d9","\\dot"),$("math",Z,"accent-token","\u02da","\\mathring"),$("math",Z,Q,"\ue131","\\@imath"),$("math",Z,Q,"\ue237","\\@jmath"),$("math",Z,"textord","\u0131","\u0131"),$("math",Z,"textord","\u0237","\u0237"),$("text",Z,"textord","\u0131","\\i",!0),$("text",Z,"textord","\u0237","\\j",!0),$("text",Z,"textord","\xdf","\\ss",!0),$("text",Z,"textord","\xe6","\\ae",!0),$("text",Z,"textord","\u0153","\\oe",!0),$("text",Z,"textord","\xf8","\\o",!0),$("text",Z,"textord","\xc6","\\AE",!0),$("text",Z,"textord","\u0152","\\OE",!0),$("text",Z,"textord","\xd8","\\O",!0),$("text",Z,"accent-token","\u02ca","\\'"),$("text",Z,"accent-token","\u02cb","\\`"),$("text",Z,"accent-token","\u02c6","\\^"),$("text",Z,"accent-token","\u02dc","\\~"),$("text",Z,"accent-token","\u02c9","\\="),$("text",Z,"accent-token","\u02d8","\\u"),$("text",Z,"accent-token","\u02d9","\\."),$("text",Z,"accent-token","\u02da","\\r"),$("text",Z,"accent-token","\u02c7","\\v"),$("text",Z,"accent-token","\xa8",'\\"'),$("text",Z,"accent-token","\u02dd","\\H"),$("text",Z,"accent-token","\u25ef","\\textcircled");var rt={"--":!0,"---":!0,"``":!0,"''":!0};$("text",Z,"textord","\u2013","--",!0),$("text",Z,"textord","\u2013","\\textendash"),$("text",Z,"textord","\u2014","---",!0),$("text",Z,"textord","\u2014","\\textemdash"),$("text",Z,"textord","\u2018","`",!0),$("text",Z,"textord","\u2018","\\textquoteleft"),$("text",Z,"textord","\u2019","'",!0),$("text",Z,"textord","\u2019","\\textquoteright"),$("text",Z,"textord","\u201c","``",!0),$("text",Z,"textord","\u201c","\\textquotedblleft"),$("text",Z,"textord","\u201d","''",!0),$("text",Z,"textord","\u201d","\\textquotedblright"),$("math",Z,"textord","\xb0","\\degree",!0),$("text",Z,"textord","\xb0","\\degree"),$("text",Z,"textord","\xb0","\\textdegree",!0),$("math",Z,"textord","\xa3","\\pounds"),$("math",Z,"textord","\xa3","\\mathsterling",!0),$("text",Z,"textord","\xa3","\\pounds"),$("text",Z,"textord","\xa3","\\textsterling",!0),$("math",K,"textord","\u2720","\\maltese"),$("text",K,"textord","\u2720","\\maltese");for(var at=0;at<'0123456789/@."'.length;at++){var nt='0123456789/@."'.charAt(at);$("math",Z,"textord",nt,nt)}for(var it=0;it<'0123456789!@*()-=+";:?/.,'.length;it++){var ot='0123456789!@*()-=+";:?/.,'.charAt(it);$("text",Z,"textord",ot,ot)}for(var st="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",lt=0;lt<st.length;lt++){var ht=st.charAt(lt);$("math",Z,Q,ht,ht),$("text",Z,"textord",ht,ht)}$("math",K,"textord","C","\u2102"),$("text",K,"textord","C","\u2102"),$("math",K,"textord","H","\u210d"),$("text",K,"textord","H","\u210d"),$("math",K,"textord","N","\u2115"),$("text",K,"textord","N","\u2115"),$("math",K,"textord","P","\u2119"),$("text",K,"textord","P","\u2119"),$("math",K,"textord","Q","\u211a"),$("text",K,"textord","Q","\u211a"),$("math",K,"textord","R","\u211d"),$("text",K,"textord","R","\u211d"),$("math",K,"textord","Z","\u2124"),$("text",K,"textord","Z","\u2124"),$("math",Z,Q,"h","\u210e"),$("text",Z,Q,"h","\u210e");for(var mt="",ct=0;ct<st.length;ct++){var ut=st.charAt(ct);$("math",Z,Q,ut,mt=String.fromCharCode(55349,56320+ct)),$("text",Z,"textord",ut,mt),$("math",Z,Q,ut,mt=String.fromCharCode(55349,56372+ct)),$("text",Z,"textord",ut,mt),$("math",Z,Q,ut,mt=String.fromCharCode(55349,56424+ct)),$("text",Z,"textord",ut,mt),$("math",Z,Q,ut,mt=String.fromCharCode(55349,56580+ct)),$("text",Z,"textord",ut,mt),$("math",Z,Q,ut,mt=String.fromCharCode(55349,56736+ct)),$("text",Z,"textord",ut,mt),$("math",Z,Q,ut,mt=String.fromCharCode(55349,56788+ct)),$("text",Z,"textord",ut,mt),$("math",Z,Q,ut,mt=String.fromCharCode(55349,56840+ct)),$("text",Z,"textord",ut,mt),$("math",Z,Q,ut,mt=String.fromCharCode(55349,56944+ct)),$("text",Z,"textord",ut,mt),ct<26&&($("math",Z,Q,ut,mt=String.fromCharCode(55349,56632+ct)),$("text",Z,"textord",ut,mt),$("math",Z,Q,ut,mt=String.fromCharCode(55349,56476+ct)),$("text",Z,"textord",ut,mt))}$("math",Z,Q,"k",mt=String.fromCharCode(55349,56668)),$("text",Z,"textord","k",mt);for(var pt=0;pt<10;pt++){var dt=pt.toString();$("math",Z,Q,dt,mt=String.fromCharCode(55349,57294+pt)),$("text",Z,"textord",dt,mt),$("math",Z,Q,dt,mt=String.fromCharCode(55349,57314+pt)),$("text",Z,"textord",dt,mt),$("math",Z,Q,dt,mt=String.fromCharCode(55349,57324+pt)),$("text",Z,"textord",dt,mt),$("math",Z,Q,dt,mt=String.fromCharCode(55349,57334+pt)),$("text",Z,"textord",dt,mt)}for(var ft=0;ft<"\xc7\xd0\xde\xe7\xfe".length;ft++){var gt="\xc7\xd0\xde\xe7\xfe".charAt(ft);$("math",Z,Q,gt,gt),$("text",Z,"textord",gt,gt)}var xt=[["mathbf","textbf","Main-Bold"],["mathbf","textbf","Main-Bold"],["mathnormal","textit","Math-Italic"],["mathnormal","textit","Math-Italic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["boldsymbol","boldsymbol","Main-BoldItalic"],["mathscr","textscr","Script-Regular"],["","",""],["","",""],["","",""],["mathfrak","textfrak","Fraktur-Regular"],["mathfrak","textfrak","Fraktur-Regular"],["mathbb","textbb","AMS-Regular"],["mathbb","textbb","AMS-Regular"],["","",""],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathitsf","textitsf","SansSerif-Italic"],["mathitsf","textitsf","SansSerif-Italic"],["","",""],["","",""],["mathtt","texttt","Typewriter-Regular"],["mathtt","texttt","Typewriter-Regular"]],vt=[["mathbf","textbf","Main-Bold"],["","",""],["mathsf","textsf","SansSerif-Regular"],["mathboldsf","textboldsf","SansSerif-Bold"],["mathtt","texttt","Typewriter-Regular"]],bt=[[1,1,1],[2,1,1],[3,1,1],[4,2,1],[5,2,1],[6,3,1],[7,4,2],[8,6,3],[9,7,6],[10,8,7],[11,10,9]],yt=[.5,.6,.7,.8,.9,1,1.2,1.44,1.728,2.074,2.488],wt=function(t,e){return e.size<2?t:bt[t-1][e.size-1]},kt=function(){function t(e){this.style=void 0,this.color=void 0,this.size=void 0,this.textSize=void 0,this.phantom=void 0,this.font=void 0,this.fontFamily=void 0,this.fontWeight=void 0,this.fontShape=void 0,this.sizeMultiplier=void 0,this.maxSize=void 0,this.minRuleThickness=void 0,this._fontMetrics=void 0,this.style=e.style,this.color=e.color,this.size=e.size||t.BASESIZE,this.textSize=e.textSize||this.size,this.phantom=!!e.phantom,this.font=e.font||"",this.fontFamily=e.fontFamily||"",this.fontWeight=e.fontWeight||"",this.fontShape=e.fontShape||"",this.sizeMultiplier=yt[this.size-1],this.maxSize=e.maxSize,this.minRuleThickness=e.minRuleThickness,this._fontMetrics=void 0}var e=t.prototype;return e.extend=function(e){var r={style:this.style,size:this.size,textSize:this.textSize,color:this.color,phantom:this.phantom,font:this.font,fontFamily:this.fontFamily,fontWeight:this.fontWeight,fontShape:this.fontShape,maxSize:this.maxSize,minRuleThickness:this.minRuleThickness};for(var a in e)e.hasOwnProperty(a)&&(r[a]=e[a]);return new t(r)},e.havingStyle=function(t){return this.style===t?this:this.extend({style:t,size:wt(this.textSize,t)})},e.havingCrampedStyle=function(){return this.havingStyle(this.style.cramp())},e.havingSize=function(t){return this.size===t&&this.textSize===t?this:this.extend({style:this.style.text(),size:t,textSize:t,sizeMultiplier:yt[t-1]})},e.havingBaseStyle=function(e){e=e||this.style.text();var r=wt(t.BASESIZE,e);return this.size===r&&this.textSize===t.BASESIZE&&this.style===e?this:this.extend({style:e,size:r})},e.havingBaseSizing=function(){var t;switch(this.style.id){case 4:case 5:t=3;break;case 6:case 7:t=1;break;default:t=6}return this.extend({style:this.style.text(),size:t})},e.withColor=function(t){return this.extend({color:t})},e.withPhantom=function(){return this.extend({phantom:!0})},e.withFont=function(t){return this.extend({font:t})},e.withTextFontFamily=function(t){return this.extend({fontFamily:t,font:""})},e.withTextFontWeight=function(t){return this.extend({fontWeight:t,font:""})},e.withTextFontShape=function(t){return this.extend({fontShape:t,font:""})},e.sizingClasses=function(t){return t.size!==this.size?["sizing","reset-size"+t.size,"size"+this.size]:[]},e.baseSizingClasses=function(){return this.size!==t.BASESIZE?["sizing","reset-size"+this.size,"size"+t.BASESIZE]:[]},e.fontMetrics=function(){return this._fontMetrics||(this._fontMetrics=function(t){var e;if(!Y[e=t>=5?0:t>=3?1:2]){var r=Y[e]={cssEmPerMu:V.quad[e]/18};for(var a in V)V.hasOwnProperty(a)&&(r[a]=V[a][e])}return Y[e]}(this.size)),this._fontMetrics},e.getColor=function(){return this.phantom?"transparent":this.color},t}();kt.BASESIZE=6;var St=kt,Mt={pt:1,mm:7227/2540,cm:7227/254,in:72.27,bp:1.00375,pc:12,dd:1238/1157,cc:14856/1157,nd:685/642,nc:1370/107,sp:1/65536,px:1.00375},zt={ex:!0,em:!0,mu:!0},At=function(t){return"string"!=typeof t&&(t=t.unit),t in Mt||t in zt||"ex"===t},Tt=function(t,e){var r;if(t.unit in Mt)r=Mt[t.unit]/e.fontMetrics().ptPerEm/e.sizeMultiplier;else if("mu"===t.unit)r=e.fontMetrics().cssEmPerMu;else{var a;if(a=e.style.isTight()?e.havingStyle(e.style.text()):e,"ex"===t.unit)r=a.fontMetrics().xHeight;else{if("em"!==t.unit)throw new o("Invalid unit: '"+t.unit+"'");r=a.fontMetrics().quad}a!==e&&(r*=a.sizeMultiplier/e.sizeMultiplier)}return Math.min(t.number*r,e.maxSize)},Bt=function(t,e,r){return j[r][t]&&j[r][t].replace&&(t=j[r][t].replace),{value:t,metrics:G(t,e,r)}},Ct=function(t,e,r,a,n){var i,o=Bt(t,e,r),s=o.metrics;if(t=o.value,s){var l=s.italic;("text"===r||a&&"mathit"===a.font)&&(l=0),i=new E(t,s.height,s.depth,l,s.skew,s.width,n)}else"undefined"!=typeof console&&console.warn("No character metrics for '"+t+"' in style '"+e+"' and mode '"+r+"'"),i=new E(t,0,0,0,0,0,n);if(a){i.maxFontSize=a.sizeMultiplier,a.style.isTight()&&i.classes.push("mtight");var h=a.getColor();h&&(i.style.color=h)}return i},qt=function(t,e){if(T(t.classes)!==T(e.classes)||t.skew!==e.skew||t.maxFontSize!==e.maxFontSize)return!1;for(var r in t.style)if(t.style.hasOwnProperty(r)&&t.style[r]!==e.style[r])return!1;for(var a in e.style)if(e.style.hasOwnProperty(a)&&t.style[a]!==e.style[a])return!1;return!0},Nt=function(t){for(var e=0,r=0,a=0,n=0;n<t.children.length;n++){var i=t.children[n];i.height>e&&(e=i.height),i.depth>r&&(r=i.depth),i.maxFontSize>a&&(a=i.maxFontSize)}t.height=e,t.depth=r,t.maxFontSize=a},It=function(t,e,r,a){var n=new N(t,e,r,a);return Nt(n),n},Ot=function(t,e,r,a){return new N(t,e,r,a)},Rt=function(t){var e=new A(t);return Nt(e),e},Et=function(t,e,r){var a="";switch(t){case"amsrm":a="AMS";break;case"textrm":a="Main";break;case"textsf":a="SansSerif";break;case"texttt":a="Typewriter";break;default:a=t}return a+"-"+("textbf"===e&&"textit"===r?"BoldItalic":"textbf"===e?"Bold":"textit"===e?"Italic":"Regular")},Lt={mathbf:{variant:"bold",fontName:"Main-Bold"},mathrm:{variant:"normal",fontName:"Main-Regular"},textit:{variant:"italic",fontName:"Main-Italic"},mathit:{variant:"italic",fontName:"Main-Italic"},mathnormal:{variant:"italic",fontName:"Math-Italic"},mathbb:{variant:"double-struck",fontName:"AMS-Regular"},mathcal:{variant:"script",fontName:"Caligraphic-Regular"},mathfrak:{variant:"fraktur",fontName:"Fraktur-Regular"},mathscr:{variant:"script",fontName:"Script-Regular"},mathsf:{variant:"sans-serif",fontName:"SansSerif-Regular"},mathtt:{variant:"monospace",fontName:"Typewriter-Regular"}},Pt={vec:["vec",.471,.714],oiintSize1:["oiintSize1",.957,.499],oiintSize2:["oiintSize2",1.472,.659],oiiintSize1:["oiiintSize1",1.304,.499],oiiintSize2:["oiiintSize2",1.98,.659],leftParenInner:["leftParenInner",.875,.3],rightParenInner:["rightParenInner",.875,.3]},Dt={fontMap:Lt,makeSymbol:Ct,mathsym:function(t,e,r,a){return void 0===a&&(a=[]),"boldsymbol"===r.font&&Bt(t,"Main-Bold",e).metrics?Ct(t,"Main-Bold",e,r,a.concat(["mathbf"])):"\\"===t||"main"===j[e][t].font?Ct(t,"Main-Regular",e,r,a):Ct(t,"AMS-Regular",e,r,a.concat(["amsrm"]))},makeSpan:It,makeSvgSpan:Ot,makeLineSpan:function(t,e,r){var a=It([t],[],e);return a.height=Math.max(r||e.fontMetrics().defaultRuleThickness,e.minRuleThickness),a.style.borderBottomWidth=a.height+"em",a.maxFontSize=1,a},makeAnchor:function(t,e,r,a){var n=new I(t,e,r,a);return Nt(n),n},makeFragment:Rt,wrapFragment:function(t,e){return t instanceof A?It([],[t],e):t},makeVList:function(t,e){for(var r=function(t){if("individualShift"===t.positionType){for(var e=t.children,r=[e[0]],a=-e[0].shift-e[0].elem.depth,n=a,i=1;i<e.length;i++){var o=-e[i].shift-n-e[i].elem.depth,s=o-(e[i-1].elem.height+e[i-1].elem.depth);n+=o,r.push({type:"kern",size:s}),r.push(e[i])}return{children:r,depth:a}}var l;if("top"===t.positionType){for(var h=t.positionData,m=0;m<t.children.length;m++){var c=t.children[m];h-="kern"===c.type?c.size:c.elem.height+c.elem.depth}l=h}else if("bottom"===t.positionType)l=-t.positionData;else{var u=t.children[0];if("elem"!==u.type)throw new Error('First child must have type "elem".');if("shift"===t.positionType)l=-u.elem.depth-t.positionData;else{if("firstBaseline"!==t.positionType)throw new Error("Invalid positionType "+t.positionType+".");l=-u.elem.depth}}return{children:t.children,depth:l}}(t),a=r.children,n=r.depth,i=0,o=0;o<a.length;o++){var s=a[o];if("elem"===s.type){var l=s.elem;i=Math.max(i,l.maxFontSize,l.height)}}i+=2;var h=It(["pstrut"],[]);h.style.height=i+"em";for(var m=[],c=n,u=n,p=n,d=0;d<a.length;d++){var f=a[d];if("kern"===f.type)p+=f.size;else{var g=f.elem,x=f.wrapperClasses||[],v=f.wrapperStyle||{},b=It(x,[h,g],void 0,v);b.style.top=-i-p-g.depth+"em",f.marginLeft&&(b.style.marginLeft=f.marginLeft),f.marginRight&&(b.style.marginRight=f.marginRight),m.push(b),p+=g.height+g.depth}c=Math.min(c,p),u=Math.max(u,p)}var y,w=It(["vlist"],m);if(w.style.height=u+"em",c<0){var k=It([],[]),S=It(["vlist"],[k]);S.style.height=-c+"em";var M=It(["vlist-s"],[new E("\u200b")]);y=[It(["vlist-r"],[w,M]),It(["vlist-r"],[S])]}else y=[It(["vlist-r"],[w])];var z=It(["vlist-t"],y);return 2===y.length&&z.classes.push("vlist-t2"),z.height=u,z.depth=-c,z},makeOrd:function(t,e,r){var a=t.mode,n=t.text,i=["mord"],s="math"===a||"text"===a&&e.font,l=s?e.font:e.fontFamily;if(55349===n.charCodeAt(0)){var h=function(t,e){var r=1024*(t.charCodeAt(0)-55296)+(t.charCodeAt(1)-56320)+65536,a="math"===e?0:1;if(119808<=r&&r<120484){var n=Math.floor((r-119808)/26);return[xt[n][2],xt[n][a]]}if(120782<=r&&r<=120831){var i=Math.floor((r-120782)/10);return[vt[i][2],vt[i][a]]}if(120485===r||120486===r)return[xt[0][2],xt[0][a]];if(120486<r&&r<120782)return["",""];throw new o("Unsupported character: "+t)}(n,a),m=h[0],c=h[1];return Ct(n,m,a,e,i.concat(c))}if(l){var u,p;if("boldsymbol"===l){var d=function(t,e,r,a,n){return"textord"!==n&&Bt(t,"Math-BoldItalic",e).metrics?{fontName:"Math-BoldItalic",fontClass:"boldsymbol"}:{fontName:"Main-Bold",fontClass:"mathbf"}}(n,a,0,0,r);u=d.fontName,p=[d.fontClass]}else s?(u=Lt[l].fontName,p=[l]):(u=Et(l,e.fontWeight,e.fontShape),p=[l,e.fontWeight,e.fontShape]);if(Bt(n,u,a).metrics)return Ct(n,u,a,e,i.concat(p));if(rt.hasOwnProperty(n)&&"Typewriter"===u.substr(0,10)){for(var f=[],g=0;g<n.length;g++)f.push(Ct(n[g],u,a,e,i.concat(p)));return Rt(f)}}if("mathord"===r)return Ct(n,"Math-Italic",a,e,i.concat(["mathnormal"]));if("textord"===r){var x=j[a][n]&&j[a][n].font;if("ams"===x){var v=Et("amsrm",e.fontWeight,e.fontShape);return Ct(n,v,a,e,i.concat("amsrm",e.fontWeight,e.fontShape))}if("main"!==x&&x){var b=Et(x,e.fontWeight,e.fontShape);return Ct(n,b,a,e,i.concat(b,e.fontWeight,e.fontShape))}var y=Et("textrm",e.fontWeight,e.fontShape);return Ct(n,y,a,e,i.concat(e.fontWeight,e.fontShape))}throw new Error("unexpected type: "+r+" in makeOrd")},makeGlue:function(t,e){var r=It(["mspace"],[],e),a=Tt(t,e);return r.style.marginRight=a+"em",r},staticSvg:function(t,e){var r=Pt[t],a=r[0],n=r[1],i=r[2],o=new P(a),s=new L([o],{width:n+"em",height:i+"em",style:"width:"+n+"em",viewBox:"0 0 "+1e3*n+" "+1e3*i,preserveAspectRatio:"xMinYMin"}),l=Ot(["overlay"],[s],e);return l.height=i,l.style.height=i+"em",l.style.width=n+"em",l},svgData:Pt,tryCombineChars:function(t){for(var e=0;e<t.length-1;e++){var r=t[e],a=t[e+1];r instanceof E&&a instanceof E&&qt(r,a)&&(r.text+=a.text,r.height=Math.max(r.height,a.height),r.depth=Math.max(r.depth,a.depth),r.italic=a.italic,t.splice(e+1,1),e--)}return t}},Ht={number:3,unit:"mu"},Ft={number:4,unit:"mu"},Vt={number:5,unit:"mu"},Ut={mord:{mop:Ht,mbin:Ft,mrel:Vt,minner:Ht},mop:{mord:Ht,mop:Ht,mrel:Vt,minner:Ht},mbin:{mord:Ft,mop:Ft,mopen:Ft,minner:Ft},mrel:{mord:Vt,mop:Vt,mopen:Vt,minner:Vt},mopen:{},mclose:{mop:Ht,mbin:Ft,mrel:Vt,minner:Ht},mpunct:{mord:Ht,mop:Ht,mrel:Vt,mopen:Ht,mclose:Ht,mpunct:Ht,minner:Ht},minner:{mord:Ht,mop:Ht,mbin:Ft,mrel:Vt,mopen:Ht,mpunct:Ht,minner:Ht}},Gt={mord:{mop:Ht},mop:{mord:Ht,mop:Ht},mbin:{},mrel:{},mopen:{},mclose:{mop:Ht},mpunct:{},minner:{mop:Ht}},Yt={},Wt={},Xt={};function _t(t){for(var e=t.type,r=t.names,a=t.props,n=t.handler,i=t.htmlBuilder,o=t.mathmlBuilder,s={type:e,numArgs:a.numArgs,argTypes:a.argTypes,greediness:void 0===a.greediness?1:a.greediness,allowedInText:!!a.allowedInText,allowedInMath:void 0===a.allowedInMath||a.allowedInMath,numOptionalArgs:a.numOptionalArgs||0,infix:!!a.infix,handler:n},l=0;l<r.length;++l)Yt[r[l]]=s;e&&(i&&(Wt[e]=i),o&&(Xt[e]=o))}function jt(t){_t({type:t.type,names:[],props:{numArgs:0},handler:function(){throw new Error("Should never be called.")},htmlBuilder:t.htmlBuilder,mathmlBuilder:t.mathmlBuilder})}var $t=function(t){return"ordgroup"===t.type?t.body:[t]},Zt=Dt.makeSpan,Kt=["leftmost","mbin","mopen","mrel","mop","mpunct"],Jt=["rightmost","mrel","mclose","mpunct"],Qt={display:w.DISPLAY,text:w.TEXT,script:w.SCRIPT,scriptscript:w.SCRIPTSCRIPT},te={mord:"mord",mop:"mop",mbin:"mbin",mrel:"mrel",mopen:"mopen",mclose:"mclose",mpunct:"mpunct",minner:"minner"},ee=function(t,e,r,a){void 0===a&&(a=[null,null]);for(var n=[],i=0;i<t.length;i++){var o=oe(t[i],e);if(o instanceof A){var s=o.children;n.push.apply(n,s)}else n.push(o)}if(!r)return n;var l=e;if(1===t.length){var h=t[0];"sizing"===h.type?l=e.havingSize(h.size):"styling"===h.type&&(l=e.havingStyle(Qt[h.style]))}var m=Zt([a[0]||"leftmost"],[],e),u=Zt([a[1]||"rightmost"],[],e),p="root"===r;return re(n,function(t,e){var r=e.classes[0],a=t.classes[0];"mbin"===r&&c.contains(Jt,a)?e.classes[0]="mord":"mbin"===a&&c.contains(Kt,r)&&(t.classes[0]="mord")},{node:m},u,p),re(n,function(t,e){var r=ne(e),a=ne(t),n=r&&a?t.hasClass("mtight")?Gt[r][a]:Ut[r][a]:null;if(n)return Dt.makeGlue(n,l)},{node:m},u,p),n},re=function t(e,r,a,n,i){n&&e.push(n);for(var o=0;o<e.length;o++){var s=e[o],l=ae(s);if(l)t(l.children,r,a,null,i);else{var h=!s.hasClass("mspace");if(h){var m=r(s,a.node);m&&(a.insertAfter?a.insertAfter(m):(e.unshift(m),o++))}h?a.node=s:i&&s.hasClass("newline")&&(a.node=Zt(["leftmost"])),a.insertAfter=function(t){return function(r){e.splice(t+1,0,r),o++}}(o)}}n&&e.pop()},ae=function(t){return t instanceof A||t instanceof I||t instanceof N&&t.hasClass("enclosing")?t:null},ne=function(t,e){return t?(e&&(t=function t(e,r){var a=ae(e);if(a){var n=a.children;if(n.length){if("right"===r)return t(n[n.length-1],"right");if("left"===r)return t(n[0],"left")}}return e}(t,e)),te[t.classes[0]]||null):null},ie=function(t,e){var r=["nulldelimiter"].concat(t.baseSizingClasses());return Zt(e.concat(r))},oe=function(t,e,r){if(!t)return Zt();if(Wt[t.type]){var a=Wt[t.type](t,e);if(r&&e.size!==r.size){a=Zt(e.sizingClasses(r),[a],e);var n=e.sizeMultiplier/r.sizeMultiplier;a.height*=n,a.depth*=n}return a}throw new o("Got group of unknown type: '"+t.type+"'")};function se(t,e){var r=Zt(["base"],t,e),a=Zt(["strut"]);return a.style.height=r.height+r.depth+"em",a.style.verticalAlign=-r.depth+"em",r.children.unshift(a),r}function le(t,e){var r=null;1===t.length&&"tag"===t[0].type&&(r=t[0].tag,t=t[0].body);for(var a,n=ee(t,e,"root"),i=[],o=[],s=0;s<n.length;s++)if(o.push(n[s]),n[s].hasClass("mbin")||n[s].hasClass("mrel")||n[s].hasClass("allowbreak")){for(var l=!1;s<n.length-1&&n[s+1].hasClass("mspace")&&!n[s+1].hasClass("newline");)s++,o.push(n[s]),n[s].hasClass("nobreak")&&(l=!0);l||(i.push(se(o,e)),o=[])}else n[s].hasClass("newline")&&(o.pop(),o.length>0&&(i.push(se(o,e)),o=[]),i.push(n[s]));o.length>0&&i.push(se(o,e)),r&&((a=se(ee(r,e,!0))).classes=["tag"],i.push(a));var h=Zt(["katex-html"],i);if(h.setAttribute("aria-hidden","true"),a){var m=a.children[0];m.style.height=h.height+h.depth+"em",m.style.verticalAlign=-h.depth+"em"}return h}function he(t){return new A(t)}var me=function(){function t(t,e){this.type=void 0,this.attributes=void 0,this.children=void 0,this.type=t,this.attributes={},this.children=e||[]}var e=t.prototype;return e.setAttribute=function(t,e){this.attributes[t]=e},e.getAttribute=function(t){return this.attributes[t]},e.toNode=function(){var t=document.createElementNS("http://www.w3.org/1998/Math/MathML",this.type);for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&t.setAttribute(e,this.attributes[e]);for(var r=0;r<this.children.length;r++)t.appendChild(this.children[r].toNode());return t},e.toMarkup=function(){var t="<"+this.type;for(var e in this.attributes)Object.prototype.hasOwnProperty.call(this.attributes,e)&&(t+=" "+e+'="',t+=c.escape(this.attributes[e]),t+='"');t+=">";for(var r=0;r<this.children.length;r++)t+=this.children[r].toMarkup();return t+="</"+this.type+">"},e.toText=function(){return this.children.map(function(t){return t.toText()}).join("")},t}(),ce=function(){function t(t){this.text=void 0,this.text=t}var e=t.prototype;return e.toNode=function(){return document.createTextNode(this.text)},e.toMarkup=function(){return c.escape(this.toText())},e.toText=function(){return this.text},t}(),ue={MathNode:me,TextNode:ce,SpaceNode:function(){function t(t){this.width=void 0,this.character=void 0,this.width=t,this.character=t>=.05555&&t<=.05556?"\u200a":t>=.1666&&t<=.1667?"\u2009":t>=.2222&&t<=.2223?"\u2005":t>=.2777&&t<=.2778?"\u2005\u200a":t>=-.05556&&t<=-.05555?"\u200a\u2063":t>=-.1667&&t<=-.1666?"\u2009\u2063":t>=-.2223&&t<=-.2222?"\u205f\u2063":t>=-.2778&&t<=-.2777?"\u2005\u2063":null}var e=t.prototype;return e.toNode=function(){if(this.character)return document.createTextNode(this.character);var t=document.createElementNS("http://www.w3.org/1998/Math/MathML","mspace");return t.setAttribute("width",this.width+"em"),t},e.toMarkup=function(){return this.character?"<mtext>"+this.character+"</mtext>":'<mspace width="'+this.width+'em"/>'},e.toText=function(){return this.character?this.character:" "},t}(),newDocumentFragment:he},pe=function(t,e,r){return!j[e][t]||!j[e][t].replace||55349===t.charCodeAt(0)||rt.hasOwnProperty(t)&&r&&(r.fontFamily&&"tt"===r.fontFamily.substr(4,2)||r.font&&"tt"===r.font.substr(4,2))||(t=j[e][t].replace),new ue.TextNode(t)},de=function(t){return 1===t.length?t[0]:new ue.MathNode("mrow",t)},fe=function(t,e){if("texttt"===e.fontFamily)return"monospace";if("textsf"===e.fontFamily)return"textit"===e.fontShape&&"textbf"===e.fontWeight?"sans-serif-bold-italic":"textit"===e.fontShape?"sans-serif-italic":"textbf"===e.fontWeight?"bold-sans-serif":"sans-serif";if("textit"===e.fontShape&&"textbf"===e.fontWeight)return"bold-italic";if("textit"===e.fontShape)return"italic";if("textbf"===e.fontWeight)return"bold";var r=e.font;if(!r||"mathnormal"===r)return null;var a=t.mode;if("mathit"===r)return"italic";if("boldsymbol"===r)return"textord"===t.type?"bold":"bold-italic";if("mathbf"===r)return"bold";if("mathbb"===r)return"double-struck";if("mathfrak"===r)return"fraktur";if("mathscr"===r||"mathcal"===r)return"script";if("mathsf"===r)return"sans-serif";if("mathtt"===r)return"monospace";var n=t.text;return c.contains(["\\imath","\\jmath"],n)?null:(j[a][n]&&j[a][n].replace&&(n=j[a][n].replace),G(n,Dt.fontMap[r].fontName,a)?Dt.fontMap[r].variant:null)},ge=function(t,e,r){if(1===t.length){var a=ve(t[0],e);return r&&a instanceof me&&"mo"===a.type&&(a.setAttribute("lspace","0em"),a.setAttribute("rspace","0em")),[a]}for(var n,i=[],o=0;o<t.length;o++){var s=ve(t[o],e);if(s instanceof me&&n instanceof me){if("mtext"===s.type&&"mtext"===n.type&&s.getAttribute("mathvariant")===n.getAttribute("mathvariant")){var l;(l=n.children).push.apply(l,s.children);continue}if("mn"===s.type&&"mn"===n.type){var h;(h=n.children).push.apply(h,s.children);continue}if("mi"===s.type&&1===s.children.length&&"mn"===n.type){var m=s.children[0];if(m instanceof ce&&"."===m.text){var c;(c=n.children).push.apply(c,s.children);continue}}else if("mi"===n.type&&1===n.children.length){var u=n.children[0];if(u instanceof ce&&"\u0338"===u.text&&("mo"===s.type||"mi"===s.type||"mn"===s.type)){var p=s.children[0];p instanceof ce&&p.text.length>0&&(p.text=p.text.slice(0,1)+"\u0338"+p.text.slice(1),i.pop())}}}i.push(s),n=s}return i},xe=function(t,e,r){return de(ge(t,e,r))},ve=function(t,e){if(!t)return new ue.MathNode("mrow");if(Xt[t.type])return Xt[t.type](t,e);throw new o("Got group of unknown type: '"+t.type+"'")};function be(t,e,r,a,n){var i,o=ge(t,r);i=1===o.length&&o[0]instanceof me&&c.contains(["mrow","mtable"],o[0].type)?o[0]:new ue.MathNode("mrow",o);var s=new ue.MathNode("annotation",[new ue.TextNode(e)]);s.setAttribute("encoding","application/x-tex");var l=new ue.MathNode("semantics",[i,s]),h=new ue.MathNode("math",[l]);h.setAttribute("xmlns","http://www.w3.org/1998/Math/MathML"),a&&h.setAttribute("display","block");var m=n?"katex":"katex-mathml";return Dt.makeSpan([m],[h])}var ye=function(t){return new St({style:t.displayMode?w.DISPLAY:w.TEXT,maxSize:t.maxSize,minRuleThickness:t.minRuleThickness})},we=function(t,e){if(e.displayMode){var r=["katex-display"];e.leqno&&r.push("leqno"),e.fleqn&&r.push("fleqn"),t=Dt.makeSpan(r,[t])}return t},ke=function(t,e,r){var a,n=ye(r);if("mathml"===r.output)return be(t,e,n,r.displayMode,!0);if("html"===r.output){var i=le(t,n);a=Dt.makeSpan(["katex"],[i])}else{var o=be(t,e,n,r.displayMode,!1),s=le(t,n);a=Dt.makeSpan(["katex"],[o,s])}return we(a,r)},Se={widehat:"^",widecheck:"\u02c7",widetilde:"~",utilde:"~",overleftarrow:"\u2190",underleftarrow:"\u2190",xleftarrow:"\u2190",overrightarrow:"\u2192",underrightarrow:"\u2192",xrightarrow:"\u2192",underbrace:"\u23df",overbrace:"\u23de",overgroup:"\u23e0",undergroup:"\u23e1",overleftrightarrow:"\u2194",underleftrightarrow:"\u2194",xleftrightarrow:"\u2194",Overrightarrow:"\u21d2",xRightarrow:"\u21d2",overleftharpoon:"\u21bc",xleftharpoonup:"\u21bc",overrightharpoon:"\u21c0",xrightharpoonup:"\u21c0",xLeftarrow:"\u21d0",xLeftrightarrow:"\u21d4",xhookleftarrow:"\u21a9",xhookrightarrow:"\u21aa",xmapsto:"\u21a6",xrightharpoondown:"\u21c1",xleftharpoondown:"\u21bd",xrightleftharpoons:"\u21cc",xleftrightharpoons:"\u21cb",xtwoheadleftarrow:"\u219e",xtwoheadrightarrow:"\u21a0",xlongequal:"=",xtofrom:"\u21c4",xrightleftarrows:"\u21c4",xrightequilibrium:"\u21cc",xleftequilibrium:"\u21cb"},Me={overrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],overleftarrow:[["leftarrow"],.888,522,"xMinYMin"],underrightarrow:[["rightarrow"],.888,522,"xMaxYMin"],underleftarrow:[["leftarrow"],.888,522,"xMinYMin"],xrightarrow:[["rightarrow"],1.469,522,"xMaxYMin"],xleftarrow:[["leftarrow"],1.469,522,"xMinYMin"],Overrightarrow:[["doublerightarrow"],.888,560,"xMaxYMin"],xRightarrow:[["doublerightarrow"],1.526,560,"xMaxYMin"],xLeftarrow:[["doubleleftarrow"],1.526,560,"xMinYMin"],overleftharpoon:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoonup:[["leftharpoon"],.888,522,"xMinYMin"],xleftharpoondown:[["leftharpoondown"],.888,522,"xMinYMin"],overrightharpoon:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoonup:[["rightharpoon"],.888,522,"xMaxYMin"],xrightharpoondown:[["rightharpoondown"],.888,522,"xMaxYMin"],xlongequal:[["longequal"],.888,334,"xMinYMin"],xtwoheadleftarrow:[["twoheadleftarrow"],.888,334,"xMinYMin"],xtwoheadrightarrow:[["twoheadrightarrow"],.888,334,"xMaxYMin"],overleftrightarrow:[["leftarrow","rightarrow"],.888,522],overbrace:[["leftbrace","midbrace","rightbrace"],1.6,548],underbrace:[["leftbraceunder","midbraceunder","rightbraceunder"],1.6,548],underleftrightarrow:[["leftarrow","rightarrow"],.888,522],xleftrightarrow:[["leftarrow","rightarrow"],1.75,522],xLeftrightarrow:[["doubleleftarrow","doublerightarrow"],1.75,560],xrightleftharpoons:[["leftharpoondownplus","rightharpoonplus"],1.75,716],xleftrightharpoons:[["leftharpoonplus","rightharpoondownplus"],1.75,716],xhookleftarrow:[["leftarrow","righthook"],1.08,522],xhookrightarrow:[["lefthook","rightarrow"],1.08,522],overlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],underlinesegment:[["leftlinesegment","rightlinesegment"],.888,522],overgroup:[["leftgroup","rightgroup"],.888,342],undergroup:[["leftgroupunder","rightgroupunder"],.888,342],xmapsto:[["leftmapsto","rightarrow"],1.5,522],xtofrom:[["leftToFrom","rightToFrom"],1.75,528],xrightleftarrows:[["baraboveleftarrow","rightarrowabovebar"],1.75,901],xrightequilibrium:[["baraboveshortleftharpoon","rightharpoonaboveshortbar"],1.75,716],xleftequilibrium:[["shortbaraboveleftharpoon","shortrightharpoonabovebar"],1.75,716]},ze=function(t){return"ordgroup"===t.type?t.body.length:1},Ae=function(t,e,r,a){var n,i=t.height+t.depth+2*r;if(/fbox|color/.test(e)){if(n=Dt.makeSpan(["stretchy",e],[],a),"fbox"===e){var o=a.color&&a.getColor();o&&(n.style.borderColor=o)}}else{var s=[];/^[bx]cancel$/.test(e)&&s.push(new D({x1:"0",y1:"0",x2:"100%",y2:"100%","stroke-width":"0.046em"})),/^x?cancel$/.test(e)&&s.push(new D({x1:"0",y1:"100%",x2:"100%",y2:"0","stroke-width":"0.046em"}));var l=new L(s,{width:"100%",height:i+"em"});n=Dt.makeSvgSpan([],[l],a)}return n.height=i,n.style.height=i+"em",n},Te=function(t){var e=new ue.MathNode("mo",[new ue.TextNode(Se[t.substr(1)])]);return e.setAttribute("stretchy","true"),e},Be=function(t,e){var r=function(){var r=4e5,a=t.label.substr(1);if(c.contains(["widehat","widecheck","widetilde","utilde"],a)){var n,i,o,s=ze(t.base);if(s>5)"widehat"===a||"widecheck"===a?(n=420,r=2364,o=.42,i=a+"4"):(n=312,r=2340,o=.34,i="tilde4");else{var l=[1,1,2,2,3,3][s];"widehat"===a||"widecheck"===a?(r=[0,1062,2364,2364,2364][l],n=[0,239,300,360,420][l],o=[0,.24,.3,.3,.36,.42][l],i=a+l):(r=[0,600,1033,2339,2340][l],n=[0,260,286,306,312][l],o=[0,.26,.286,.3,.306,.34][l],i="tilde"+l)}var h=new P(i),m=new L([h],{width:"100%",height:o+"em",viewBox:"0 0 "+r+" "+n,preserveAspectRatio:"none"});return{span:Dt.makeSvgSpan([],[m],e),minWidth:0,height:o}}var u,p,d=[],f=Me[a],g=f[0],x=f[1],v=f[2],b=v/1e3,y=g.length;if(1===y)u=["hide-tail"],p=[f[3]];else if(2===y)u=["halfarrow-left","halfarrow-right"],p=["xMinYMin","xMaxYMin"];else{if(3!==y)throw new Error("Correct katexImagesData or update code here to support\n "+y+" children.");u=["brace-left","brace-center","brace-right"],p=["xMinYMin","xMidYMin","xMaxYMin"]}for(var w=0;w<y;w++){var k=new P(g[w]),S=new L([k],{width:"400em",height:b+"em",viewBox:"0 0 "+r+" "+v,preserveAspectRatio:p[w]+" slice"}),M=Dt.makeSvgSpan([u[w]],[S],e);if(1===y)return{span:M,minWidth:x,height:b};M.style.height=b+"em",d.push(M)}return{span:Dt.makeSpan(["stretchy"],d,e),minWidth:x,height:b}}(),a=r.span,n=r.minWidth,i=r.height;return a.height=i,a.style.height=i+"em",n>0&&(a.style.minWidth=n+"em"),a};function Ce(t,e){if(!t||t.type!==e)throw new Error("Expected node of type "+e+", but got "+(t?"node of type "+t.type:String(t)));return t}function qe(t){var e=Ne(t);if(!e)throw new Error("Expected node of symbol group type, but got "+(t?"node of type "+t.type:String(t)));return e}function Ne(t){return t&&("atom"===t.type||X.hasOwnProperty(t.type))?t:null}var Ie=function(t,e){var r,a,n;t&&"supsub"===t.type?(r=(a=Ce(t.base,"accent")).base,t.base=r,n=function(t){if(t instanceof N)return t;throw new Error("Expected span<HtmlDomNode> but got "+String(t)+".")}(oe(t,e)),t.base=a):r=(a=Ce(t,"accent")).base;var i=oe(r,e.havingCrampedStyle()),o=0;if(a.isShifty&&c.isCharacterBox(r)){var s=c.getBaseElem(r);o=H(oe(s,e.havingCrampedStyle())).skew}var l,h=Math.min(i.height,e.fontMetrics().xHeight);if(a.isStretchy)l=Be(a,e),l=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"elem",elem:l,wrapperClasses:["svg-align"],wrapperStyle:o>0?{width:"calc(100% - "+2*o+"em)",marginLeft:2*o+"em"}:void 0}]},e);else{var m,u;"\\vec"===a.label?(m=Dt.staticSvg("vec",e),u=Dt.svgData.vec[1]):((m=H(m=Dt.makeOrd({mode:a.mode,text:a.label},e,"textord"))).italic=0,u=m.width),l=Dt.makeSpan(["accent-body"],[m]);var p="\\textcircled"===a.label;p&&(l.classes.push("accent-full"),h=i.height);var d=o;p||(d-=u/2),l.style.left=d+"em","\\textcircled"===a.label&&(l.style.top=".2em"),l=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:i},{type:"kern",size:-h},{type:"elem",elem:l}]},e)}var f=Dt.makeSpan(["mord","accent"],[l],e);return n?(n.children[0]=f,n.height=Math.max(f.height,n.height),n.classes[0]="mord",n):f},Oe=function(t,e){var r=t.isStretchy?Te(t.label):new ue.MathNode("mo",[pe(t.label,t.mode)]),a=new ue.MathNode("mover",[ve(t.base,e),r]);return a.setAttribute("accent","true"),a},Re=new RegExp(["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring"].map(function(t){return"\\"+t}).join("|"));_t({type:"accent",names:["\\acute","\\grave","\\ddot","\\tilde","\\bar","\\breve","\\check","\\hat","\\vec","\\dot","\\mathring","\\widecheck","\\widehat","\\widetilde","\\overrightarrow","\\overleftarrow","\\Overrightarrow","\\overleftrightarrow","\\overgroup","\\overlinesegment","\\overleftharpoon","\\overrightharpoon"],props:{numArgs:1},handler:function(t,e){var r=e[0],a=!Re.test(t.funcName),n=!a||"\\widehat"===t.funcName||"\\widetilde"===t.funcName||"\\widecheck"===t.funcName;return{type:"accent",mode:t.parser.mode,label:t.funcName,isStretchy:a,isShifty:n,base:r}},htmlBuilder:Ie,mathmlBuilder:Oe}),_t({type:"accent",names:["\\'","\\`","\\^","\\~","\\=","\\u","\\.",'\\"',"\\r","\\H","\\v","\\textcircled"],props:{numArgs:1,allowedInText:!0,allowedInMath:!1},handler:function(t,e){var r=e[0];return{type:"accent",mode:t.parser.mode,label:t.funcName,isStretchy:!1,isShifty:!0,base:r}},htmlBuilder:Ie,mathmlBuilder:Oe}),_t({type:"accentUnder",names:["\\underleftarrow","\\underrightarrow","\\underleftrightarrow","\\undergroup","\\underlinesegment","\\utilde"],props:{numArgs:1},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];return{type:"accentUnder",mode:r.mode,label:a,base:n}},htmlBuilder:function(t,e){var r=oe(t.base,e),a=Be(t,e),n="\\utilde"===t.label?.12:0,i=Dt.makeVList({positionType:"top",positionData:r.height,children:[{type:"elem",elem:a,wrapperClasses:["svg-align"]},{type:"kern",size:n},{type:"elem",elem:r}]},e);return Dt.makeSpan(["mord","accentunder"],[i],e)},mathmlBuilder:function(t,e){var r=Te(t.label),a=new ue.MathNode("munder",[ve(t.base,e),r]);return a.setAttribute("accentunder","true"),a}});var Ee=function(t){var e=new ue.MathNode("mpadded",t?[t]:[]);return e.setAttribute("width","+0.6em"),e.setAttribute("lspace","0.3em"),e};_t({type:"xArrow",names:["\\xleftarrow","\\xrightarrow","\\xLeftarrow","\\xRightarrow","\\xleftrightarrow","\\xLeftrightarrow","\\xhookleftarrow","\\xhookrightarrow","\\xmapsto","\\xrightharpoondown","\\xrightharpoonup","\\xleftharpoondown","\\xleftharpoonup","\\xrightleftharpoons","\\xleftrightharpoons","\\xlongequal","\\xtwoheadrightarrow","\\xtwoheadleftarrow","\\xtofrom","\\xrightleftarrows","\\xrightequilibrium","\\xleftequilibrium"],props:{numArgs:1,numOptionalArgs:1},handler:function(t,e,r){var a=t.parser,n=t.funcName;return{type:"xArrow",mode:a.mode,label:n,body:e[0],below:r[0]}},htmlBuilder:function(t,e){var r,a=e.style,n=e.havingStyle(a.sup()),i=Dt.wrapFragment(oe(t.body,n,e),e);i.classes.push("x-arrow-pad"),t.below&&(n=e.havingStyle(a.sub()),(r=Dt.wrapFragment(oe(t.below,n,e),e)).classes.push("x-arrow-pad"));var o,s=Be(t,e),l=-e.fontMetrics().axisHeight+.5*s.height,h=-e.fontMetrics().axisHeight-.5*s.height-.111;if((i.depth>.25||"\\xleftequilibrium"===t.label)&&(h-=i.depth),r){var m=-e.fontMetrics().axisHeight+r.height+.5*s.height+.111;o=Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:h},{type:"elem",elem:s,shift:l},{type:"elem",elem:r,shift:m}]},e)}else o=Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:i,shift:h},{type:"elem",elem:s,shift:l}]},e);return o.children[0].children[0].children[1].classes.push("svg-align"),Dt.makeSpan(["mrel","x-arrow"],[o],e)},mathmlBuilder:function(t,e){var r,a=Te(t.label);if(t.body){var n=Ee(ve(t.body,e));if(t.below){var i=Ee(ve(t.below,e));r=new ue.MathNode("munderover",[a,i,n])}else r=new ue.MathNode("mover",[a,n])}else if(t.below){var o=Ee(ve(t.below,e));r=new ue.MathNode("munder",[a,o])}else r=Ee(),r=new ue.MathNode("mover",[a,r]);return r}}),_t({type:"textord",names:["\\@char"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){for(var r=t.parser,a=Ce(e[0],"ordgroup").body,n="",i=0;i<a.length;i++){n+=Ce(a[i],"textord").text}var s=parseInt(n);if(isNaN(s))throw new o("\\@char has non-numeric argument "+n);return{type:"textord",mode:r.mode,text:String.fromCharCode(s)}}});var Le=function(t,e){var r=ee(t.body,e.withColor(t.color),!1);return Dt.makeFragment(r)},Pe=function(t,e){var r=ge(t.body,e.withColor(t.color)),a=new ue.MathNode("mstyle",r);return a.setAttribute("mathcolor",t.color),a};_t({type:"color",names:["\\textcolor"],props:{numArgs:2,allowedInText:!0,greediness:3,argTypes:["color","original"]},handler:function(t,e){var r=t.parser,a=Ce(e[0],"color-token").color,n=e[1];return{type:"color",mode:r.mode,color:a,body:$t(n)}},htmlBuilder:Le,mathmlBuilder:Pe}),_t({type:"color",names:["\\color"],props:{numArgs:1,allowedInText:!0,greediness:3,argTypes:["color"]},handler:function(t,e){var r=t.parser,a=t.breakOnTokenText,n=Ce(e[0],"color-token").color;r.gullet.macros.set("\\current@color",n);var i=r.parseExpression(!0,a);return{type:"color",mode:r.mode,color:n,body:i}},htmlBuilder:Le,mathmlBuilder:Pe}),_t({type:"cr",names:["\\cr","\\newline"],props:{numArgs:0,numOptionalArgs:1,argTypes:["size"],allowedInText:!0},handler:function(t,e,r){var a=t.parser,n=t.funcName,i=r[0],o="\\cr"===n,s=!1;return o||(s=!a.settings.displayMode||!a.settings.useStrictBehavior("newLineInDisplayMode","In LaTeX, \\\\ or \\newline does nothing in display mode")),{type:"cr",mode:a.mode,newLine:s,newRow:o,size:i&&Ce(i,"size").value}},htmlBuilder:function(t,e){if(t.newRow)throw new o("\\cr valid only within a tabular/array environment");var r=Dt.makeSpan(["mspace"],[],e);return t.newLine&&(r.classes.push("newline"),t.size&&(r.style.marginTop=Tt(t.size,e)+"em")),r},mathmlBuilder:function(t,e){var r=new ue.MathNode("mspace");return t.newLine&&(r.setAttribute("linebreak","newline"),t.size&&r.setAttribute("height",Tt(t.size,e)+"em")),r}});var De={"\\global":"\\global","\\long":"\\\\globallong","\\\\globallong":"\\\\globallong","\\def":"\\gdef","\\gdef":"\\gdef","\\edef":"\\xdef","\\xdef":"\\xdef","\\let":"\\\\globallet","\\futurelet":"\\\\globalfuture"},He=function(t){var e=t.text;if(/^(?:[\\{}$&#^_]|EOF)$/.test(e))throw new o("Expected a control sequence",t);return e},Fe=function(t,e,r,a){var n=t.gullet.macros.get(r.text);null==n&&(r.noexpand=!0,n={tokens:[r],numArgs:0,unexpandable:!t.gullet.isExpandable(r.text)}),t.gullet.macros.set(e,n,a)};_t({type:"internal",names:["\\global","\\long","\\\\globallong"],props:{numArgs:0,allowedInText:!0},handler:function(t){var e=t.parser,r=t.funcName;e.consumeSpaces();var a=e.fetch();if(De[a.text])return"\\global"!==r&&"\\\\globallong"!==r||(a.text=De[a.text]),Ce(e.parseFunction(),"internal");throw new o("Invalid token after macro prefix",a)}}),_t({type:"internal",names:["\\def","\\gdef","\\edef","\\xdef"],props:{numArgs:0,allowedInText:!0},handler:function(t){var e=t.parser,r=t.funcName,a=e.gullet.consumeArgs(1)[0];if(1!==a.length)throw new o("\\gdef's first argument must be a macro name");var n=a[0].text,i=0;for(a=e.gullet.consumeArgs(1)[0];1===a.length&&"#"===a[0].text;){if(1!==(a=e.gullet.consumeArgs(1)[0]).length)throw new o('Invalid argument number length "'+a.length+'"');if(!/^[1-9]$/.test(a[0].text))throw new o('Invalid argument number "'+a[0].text+'"');if(i++,parseInt(a[0].text)!==i)throw new o('Argument number "'+a[0].text+'" out of order');a=e.gullet.consumeArgs(1)[0]}return"\\edef"!==r&&"\\xdef"!==r||(a=e.gullet.expandTokens(a)).reverse(),e.gullet.macros.set(n,{tokens:a,numArgs:i},r===De[r]),{type:"internal",mode:e.mode}}}),_t({type:"internal",names:["\\let","\\\\globallet"],props:{numArgs:0,allowedInText:!0},handler:function(t){var e=t.parser,r=t.funcName,a=He(e.gullet.popToken());e.gullet.consumeSpaces();var n=function(t){var e=t.gullet.popToken();return"="===e.text&&" "===(e=t.gullet.popToken()).text&&(e=t.gullet.popToken()),e}(e);return Fe(e,a,n,"\\\\globallet"===r),{type:"internal",mode:e.mode}}}),_t({type:"internal",names:["\\futurelet","\\\\globalfuture"],props:{numArgs:0,allowedInText:!0},handler:function(t){var e=t.parser,r=t.funcName,a=He(e.gullet.popToken()),n=e.gullet.popToken(),i=e.gullet.popToken();return Fe(e,a,i,"\\\\globalfuture"===r),e.gullet.pushToken(i),e.gullet.pushToken(n),{type:"internal",mode:e.mode}}});var Ve=function(t,e,r){var a=G(j.math[t]&&j.math[t].replace||t,e,r);if(!a)throw new Error("Unsupported symbol "+t+" and font size "+e+".");return a},Ue=function(t,e,r,a){var n=r.havingBaseStyle(e),i=Dt.makeSpan(a.concat(n.sizingClasses(r)),[t],r),o=n.sizeMultiplier/r.sizeMultiplier;return i.height*=o,i.depth*=o,i.maxFontSize=n.sizeMultiplier,i},Ge=function(t,e,r){var a=e.havingBaseStyle(r),n=(1-e.sizeMultiplier/a.sizeMultiplier)*e.fontMetrics().axisHeight;t.classes.push("delimcenter"),t.style.top=n+"em",t.height-=n,t.depth+=n},Ye=function(t,e,r,a,n,i){var o=function(t,e,r,a){return Dt.makeSymbol(t,"Size"+e+"-Regular",r,a)}(t,e,n,a),s=Ue(Dt.makeSpan(["delimsizing","size"+e],[o],a),w.TEXT,a,i);return r&&Ge(s,a,w.TEXT),s},We=function(t,e,r){var a;return a="Size1-Regular"===e?"delim-size1":"delim-size4",{type:"elem",elem:Dt.makeSpan(["delimsizinginner",a],[Dt.makeSpan([],[Dt.makeSymbol(t,e,r)])])}},Xe={type:"kern",size:-.005},_e=function(t,e,r,a,n,i){var o,s,l,h;o=l=h=t,s=null;var m="Size1-Regular";"\\uparrow"===t?l=h="\u23d0":"\\Uparrow"===t?l=h="\u2016":"\\downarrow"===t?o=l="\u23d0":"\\Downarrow"===t?o=l="\u2016":"\\updownarrow"===t?(o="\\uparrow",l="\u23d0",h="\\downarrow"):"\\Updownarrow"===t?(o="\\Uparrow",l="\u2016",h="\\Downarrow"):"["===t||"\\lbrack"===t?(o="\u23a1",l="\u23a2",h="\u23a3",m="Size4-Regular"):"]"===t||"\\rbrack"===t?(o="\u23a4",l="\u23a5",h="\u23a6",m="Size4-Regular"):"\\lfloor"===t||"\u230a"===t?(l=o="\u23a2",h="\u23a3",m="Size4-Regular"):"\\lceil"===t||"\u2308"===t?(o="\u23a1",l=h="\u23a2",m="Size4-Regular"):"\\rfloor"===t||"\u230b"===t?(l=o="\u23a5",h="\u23a6",m="Size4-Regular"):"\\rceil"===t||"\u2309"===t?(o="\u23a4",l=h="\u23a5",m="Size4-Regular"):"("===t||"\\lparen"===t?(o="\u239b",l="\u239c",h="\u239d",m="Size4-Regular"):")"===t||"\\rparen"===t?(o="\u239e",l="\u239f",h="\u23a0",m="Size4-Regular"):"\\{"===t||"\\lbrace"===t?(o="\u23a7",s="\u23a8",h="\u23a9",l="\u23aa",m="Size4-Regular"):"\\}"===t||"\\rbrace"===t?(o="\u23ab",s="\u23ac",h="\u23ad",l="\u23aa",m="Size4-Regular"):"\\lgroup"===t||"\u27ee"===t?(o="\u23a7",h="\u23a9",l="\u23aa",m="Size4-Regular"):"\\rgroup"===t||"\u27ef"===t?(o="\u23ab",h="\u23ad",l="\u23aa",m="Size4-Regular"):"\\lmoustache"===t||"\u23b0"===t?(o="\u23a7",h="\u23ad",l="\u23aa",m="Size4-Regular"):"\\rmoustache"!==t&&"\u23b1"!==t||(o="\u23ab",h="\u23a9",l="\u23aa",m="Size4-Regular");var c=Ve(o,m,n),u=c.height+c.depth,p=Ve(l,m,n),d=p.height+p.depth,f=Ve(h,m,n),g=f.height+f.depth,x=0,v=1;if(null!==s){var b=Ve(s,m,n);x=b.height+b.depth,v=2}var y=u+g+x,k=Math.max(0,Math.ceil((e-y)/(v*d))),S=y+k*v*d,M=a.fontMetrics().axisHeight;r&&(M*=a.sizeMultiplier);var z=S/2-M,A=.005*(k+1)-d,T=[];if(T.push(We(h,m,n)),null===s)for(var B=0;B<k;B++)T.push(Xe),T.push(We(l,m,n));else{for(var C=0;C<k;C++)T.push(Xe),T.push(We(l,m,n));T.push({type:"kern",size:A}),T.push(We(l,m,n)),T.push(Xe),T.push(We(s,m,n));for(var q=0;q<k;q++)T.push(Xe),T.push(We(l,m,n))}if("\u239c"!==l&&"\u239f"!==l||0!==k)T.push({type:"kern",size:A}),T.push(We(l,m,n)),T.push(Xe);else{var N=Dt.svgData.leftParenInner[2]/2;T.push({type:"kern",size:-N});var I="\u239c"===l?"leftParenInner":"rightParenInner",O=Dt.staticSvg(I,a);T.push({type:"elem",elem:O}),T.push({type:"kern",size:-N})}T.push(We(o,m,n));var R=a.havingBaseStyle(w.TEXT),E=Dt.makeVList({positionType:"bottom",positionData:z,children:T},R);return Ue(Dt.makeSpan(["delimsizing","mult"],[E],R),w.TEXT,a,i)},je=function(t,e,r,a,n){var i=function(t,e,r){e*=1e3;var a="";switch(t){case"sqrtMain":a=function(t,e){return"M95,"+(622+t+e)+"\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl"+t/2.075+" -"+t+"\nc5.3,-9.3,12,-14,20,-14\nH400000v"+(40+t)+"H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM"+(834+t)+" "+e+"h400000v"+(40+t)+"h-400000z"}(e,80);break;case"sqrtSize1":a=function(t,e){return"M263,"+(601+t+e)+"c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl"+t/2.084+" -"+t+"\nc4.7,-7.3,11,-11,19,-11\nH40000v"+(40+t)+"H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM"+(1001+t)+" "+e+"h400000v"+(40+t)+"h-400000z"}(e,80);break;case"sqrtSize2":a=function(t,e){return"M983 "+(10+t+e)+"\nl"+t/3.13+" -"+t+"\nc4,-6.7,10,-10,18,-10 H400000v"+(40+t)+"\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM"+(1001+t)+" "+e+"h400000v"+(40+t)+"h-400000z"}(e,80);break;case"sqrtSize3":a=function(t,e){return"M424,"+(2398+t+e)+"\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl"+t/4.223+" -"+t+"c4,-6.7,10,-10,18,-10 H400000\nv"+(40+t)+"H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M"+(1001+t)+" "+e+"\nh400000v"+(40+t)+"h-400000z"}(e,80);break;case"sqrtSize4":a=function(t,e){return"M473,"+(2713+t+e)+"\nc339.3,-1799.3,509.3,-2700,510,-2702 l"+t/5.298+" -"+t+"\nc3.3,-7.3,9.3,-11,18,-11 H400000v"+(40+t)+"H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM"+(1001+t)+" "+e+"h400000v"+(40+t)+"H1017.7z"}(e,80);break;case"sqrtTall":a=function(t,e,r){return"M702 "+(t+e)+"H400000"+(40+t)+"\nH742v"+(r-54-e-t)+"l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 "+e+"H400000v"+(40+t)+"H742z"}(e,80,r)}return a}(t,a,r),o=new P(t,i),s=new L([o],{width:"400em",height:e+"em",viewBox:"0 0 400000 "+r,preserveAspectRatio:"xMinYMin slice"});return Dt.makeSvgSpan(["hide-tail"],[s],n)},$e=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","\\surd"],Ze=["\\uparrow","\\downarrow","\\updownarrow","\\Uparrow","\\Downarrow","\\Updownarrow","|","\\|","\\vert","\\Vert","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1"],Ke=["<",">","\\langle","\\rangle","/","\\backslash","\\lt","\\gt"],Je=[0,1.2,1.8,2.4,3],Qe=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4}],tr=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"stack"}],er=[{type:"small",style:w.SCRIPTSCRIPT},{type:"small",style:w.SCRIPT},{type:"small",style:w.TEXT},{type:"large",size:1},{type:"large",size:2},{type:"large",size:3},{type:"large",size:4},{type:"stack"}],rr=function(t){if("small"===t.type)return"Main-Regular";if("large"===t.type)return"Size"+t.size+"-Regular";if("stack"===t.type)return"Size4-Regular";throw new Error("Add support for delim type '"+t.type+"' here.")},ar=function(t,e,r,a){for(var n=Math.min(2,3-a.style.size);n<r.length&&"stack"!==r[n].type;n++){var i=Ve(t,rr(r[n]),"math"),o=i.height+i.depth;if("small"===r[n].type&&(o*=a.havingBaseStyle(r[n].style).sizeMultiplier),o>e)return r[n]}return r[r.length-1]},nr=function(t,e,r,a,n,i){var o;"<"===t||"\\lt"===t||"\u27e8"===t?t="\\langle":">"!==t&&"\\gt"!==t&&"\u27e9"!==t||(t="\\rangle"),o=c.contains(Ke,t)?Qe:c.contains($e,t)?er:tr;var s=ar(t,e,o,a);return"small"===s.type?function(t,e,r,a,n,i){var o=Dt.makeSymbol(t,"Main-Regular",n,a),s=Ue(o,e,a,i);return r&&Ge(s,a,e),s}(t,s.style,r,a,n,i):"large"===s.type?Ye(t,s.size,r,a,n,i):_e(t,e,r,a,n,i)},ir=function(t,e){var r,a,n=e.havingBaseSizing(),i=ar("\\surd",t*n.sizeMultiplier,er,n),o=n.sizeMultiplier,s=Math.max(0,e.minRuleThickness-e.fontMetrics().sqrtRuleThickness),l=0,h=0,m=0;return"small"===i.type?(t<1?o=1:t<1.4&&(o=.7),h=(1+s)/o,(r=je("sqrtMain",l=(1+s+.08)/o,m=1e3+1e3*s+80,s,e)).style.minWidth="0.853em",a=.833/o):"large"===i.type?(m=1080*Je[i.size],h=(Je[i.size]+s)/o,l=(Je[i.size]+s+.08)/o,(r=je("sqrtSize"+i.size,l,m,s,e)).style.minWidth="1.02em",a=1/o):(l=t+s+.08,h=t+s,m=Math.floor(1e3*t+s)+80,(r=je("sqrtTall",l,m,s,e)).style.minWidth="0.742em",a=1.056),r.height=h,r.style.height=l+"em",{span:r,advanceWidth:a,ruleWidth:(e.fontMetrics().sqrtRuleThickness+s)*o}},or=function(t,e,r,a,n){if("<"===t||"\\lt"===t||"\u27e8"===t?t="\\langle":">"!==t&&"\\gt"!==t&&"\u27e9"!==t||(t="\\rangle"),c.contains($e,t)||c.contains(Ke,t))return Ye(t,e,!1,r,a,n);if(c.contains(Ze,t))return _e(t,Je[e],!1,r,a,n);throw new o("Illegal delimiter: '"+t+"'")},sr=nr,lr=function(t,e,r,a,n,i){var o=a.fontMetrics().axisHeight*a.sizeMultiplier,s=5/a.fontMetrics().ptPerEm,l=Math.max(e-o,r+o),h=Math.max(l/500*901,2*l-s);return nr(t,h,!0,a,n,i)},hr={"\\bigl":{mclass:"mopen",size:1},"\\Bigl":{mclass:"mopen",size:2},"\\biggl":{mclass:"mopen",size:3},"\\Biggl":{mclass:"mopen",size:4},"\\bigr":{mclass:"mclose",size:1},"\\Bigr":{mclass:"mclose",size:2},"\\biggr":{mclass:"mclose",size:3},"\\Biggr":{mclass:"mclose",size:4},"\\bigm":{mclass:"mrel",size:1},"\\Bigm":{mclass:"mrel",size:2},"\\biggm":{mclass:"mrel",size:3},"\\Biggm":{mclass:"mrel",size:4},"\\big":{mclass:"mord",size:1},"\\Big":{mclass:"mord",size:2},"\\bigg":{mclass:"mord",size:3},"\\Bigg":{mclass:"mord",size:4}},mr=["(","\\lparen",")","\\rparen","[","\\lbrack","]","\\rbrack","\\{","\\lbrace","\\}","\\rbrace","\\lfloor","\\rfloor","\u230a","\u230b","\\lceil","\\rceil","\u2308","\u2309","<",">","\\langle","\u27e8","\\rangle","\u27e9","\\lt","\\gt","\\lvert","\\rvert","\\lVert","\\rVert","\\lgroup","\\rgroup","\u27ee","\u27ef","\\lmoustache","\\rmoustache","\u23b0","\u23b1","/","\\backslash","|","\\vert","\\|","\\Vert","\\uparrow","\\Uparrow","\\downarrow","\\Downarrow","\\updownarrow","\\Updownarrow","."];function cr(t,e){var r=Ne(t);if(r&&c.contains(mr,r.text))return r;throw new o(r?"Invalid delimiter '"+r.text+"' after '"+e.funcName+"'":"Invalid delimiter type '"+t.type+"'",t)}function ur(t){if(!t.body)throw new Error("Bug: The leftright ParseNode wasn't fully parsed.")}_t({type:"delimsizing",names:["\\bigl","\\Bigl","\\biggl","\\Biggl","\\bigr","\\Bigr","\\biggr","\\Biggr","\\bigm","\\Bigm","\\biggm","\\Biggm","\\big","\\Big","\\bigg","\\Bigg"],props:{numArgs:1},handler:function(t,e){var r=cr(e[0],t);return{type:"delimsizing",mode:t.parser.mode,size:hr[t.funcName].size,mclass:hr[t.funcName].mclass,delim:r.text}},htmlBuilder:function(t,e){return"."===t.delim?Dt.makeSpan([t.mclass]):or(t.delim,t.size,e,t.mode,[t.mclass])},mathmlBuilder:function(t){var e=[];"."!==t.delim&&e.push(pe(t.delim,t.mode));var r=new ue.MathNode("mo",e);return"mopen"===t.mclass||"mclose"===t.mclass?r.setAttribute("fence","true"):r.setAttribute("fence","false"),r}}),_t({type:"leftright-right",names:["\\right"],props:{numArgs:1},handler:function(t,e){var r=t.parser.gullet.macros.get("\\current@color");if(r&&"string"!=typeof r)throw new o("\\current@color set to non-string in \\right");return{type:"leftright-right",mode:t.parser.mode,delim:cr(e[0],t).text,color:r}}}),_t({type:"leftright",names:["\\left"],props:{numArgs:1},handler:function(t,e){var r=cr(e[0],t),a=t.parser;++a.leftrightDepth;var n=a.parseExpression(!1);--a.leftrightDepth,a.expect("\\right",!1);var i=Ce(a.parseFunction(),"leftright-right");return{type:"leftright",mode:a.mode,body:n,left:r.text,right:i.delim,rightColor:i.color}},htmlBuilder:function(t,e){ur(t);for(var r,a,n=ee(t.body,e,!0,["mopen","mclose"]),i=0,o=0,s=!1,l=0;l<n.length;l++)n[l].isMiddle?s=!0:(i=Math.max(n[l].height,i),o=Math.max(n[l].depth,o));if(i*=e.sizeMultiplier,o*=e.sizeMultiplier,r="."===t.left?ie(e,["mopen"]):lr(t.left,i,o,e,t.mode,["mopen"]),n.unshift(r),s)for(var h=1;h<n.length;h++){var m=n[h].isMiddle;m&&(n[h]=lr(m.delim,i,o,m.options,t.mode,[]))}if("."===t.right)a=ie(e,["mclose"]);else{var c=t.rightColor?e.withColor(t.rightColor):e;a=lr(t.right,i,o,c,t.mode,["mclose"])}return n.push(a),Dt.makeSpan(["minner"],n,e)},mathmlBuilder:function(t,e){ur(t);var r=ge(t.body,e);if("."!==t.left){var a=new ue.MathNode("mo",[pe(t.left,t.mode)]);a.setAttribute("fence","true"),r.unshift(a)}if("."!==t.right){var n=new ue.MathNode("mo",[pe(t.right,t.mode)]);n.setAttribute("fence","true"),t.rightColor&&n.setAttribute("mathcolor",t.rightColor),r.push(n)}return de(r)}}),_t({type:"middle",names:["\\middle"],props:{numArgs:1},handler:function(t,e){var r=cr(e[0],t);if(!t.parser.leftrightDepth)throw new o("\\middle without preceding \\left",r);return{type:"middle",mode:t.parser.mode,delim:r.text}},htmlBuilder:function(t,e){var r;if("."===t.delim)r=ie(e,[]);else{r=or(t.delim,1,e,t.mode,[]);var a={delim:t.delim,options:e};r.isMiddle=a}return r},mathmlBuilder:function(t,e){var r="\\vert"===t.delim||"|"===t.delim?pe("|","text"):pe(t.delim,t.mode),a=new ue.MathNode("mo",[r]);return a.setAttribute("fence","true"),a.setAttribute("lspace","0.05em"),a.setAttribute("rspace","0.05em"),a}});var pr=function(t,e){var r,a,n=Dt.wrapFragment(oe(t.body,e),e),i=t.label.substr(1),o=e.sizeMultiplier,s=0,l=c.isCharacterBox(t.body);if("sout"===i)(r=Dt.makeSpan(["stretchy","sout"])).height=e.fontMetrics().defaultRuleThickness/o,s=-.5*e.fontMetrics().xHeight;else{/cancel/.test(i)?l||n.classes.push("cancel-pad"):n.classes.push("boxpad");var h=0,m=0;/box/.test(i)?(m=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness),h=e.fontMetrics().fboxsep+("colorbox"===i?0:m)):h=l?.2:0,r=Ae(n,i,h,e),/fbox|boxed|fcolorbox/.test(i)&&(r.style.borderStyle="solid",r.style.borderWidth=m+"em"),s=n.depth+h,t.backgroundColor&&(r.style.backgroundColor=t.backgroundColor,t.borderColor&&(r.style.borderColor=t.borderColor))}return a=t.backgroundColor?Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:r,shift:s},{type:"elem",elem:n,shift:0}]},e):Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:n,shift:0},{type:"elem",elem:r,shift:s,wrapperClasses:/cancel/.test(i)?["svg-align"]:[]}]},e),/cancel/.test(i)&&(a.height=n.height,a.depth=n.depth),/cancel/.test(i)&&!l?Dt.makeSpan(["mord","cancel-lap"],[a],e):Dt.makeSpan(["mord"],[a],e)},dr=function(t,e){var r=0,a=new ue.MathNode(t.label.indexOf("colorbox")>-1?"mpadded":"menclose",[ve(t.body,e)]);switch(t.label){case"\\cancel":a.setAttribute("notation","updiagonalstrike");break;case"\\bcancel":a.setAttribute("notation","downdiagonalstrike");break;case"\\sout":a.setAttribute("notation","horizontalstrike");break;case"\\fbox":a.setAttribute("notation","box");break;case"\\fcolorbox":case"\\colorbox":if(r=e.fontMetrics().fboxsep*e.fontMetrics().ptPerEm,a.setAttribute("width","+"+2*r+"pt"),a.setAttribute("height","+"+2*r+"pt"),a.setAttribute("lspace",r+"pt"),a.setAttribute("voffset",r+"pt"),"\\fcolorbox"===t.label){var n=Math.max(e.fontMetrics().fboxrule,e.minRuleThickness);a.setAttribute("style","border: "+n+"em solid "+String(t.borderColor))}break;case"\\xcancel":a.setAttribute("notation","updiagonalstrike downdiagonalstrike")}return t.backgroundColor&&a.setAttribute("mathbackground",t.backgroundColor),a};_t({type:"enclose",names:["\\colorbox"],props:{numArgs:2,allowedInText:!0,greediness:3,argTypes:["color","text"]},handler:function(t,e,r){var a=t.parser,n=t.funcName,i=Ce(e[0],"color-token").color,o=e[1];return{type:"enclose",mode:a.mode,label:n,backgroundColor:i,body:o}},htmlBuilder:pr,mathmlBuilder:dr}),_t({type:"enclose",names:["\\fcolorbox"],props:{numArgs:3,allowedInText:!0,greediness:3,argTypes:["color","color","text"]},handler:function(t,e,r){var a=t.parser,n=t.funcName,i=Ce(e[0],"color-token").color,o=Ce(e[1],"color-token").color,s=e[2];return{type:"enclose",mode:a.mode,label:n,backgroundColor:o,borderColor:i,body:s}},htmlBuilder:pr,mathmlBuilder:dr}),_t({type:"enclose",names:["\\fbox"],props:{numArgs:1,argTypes:["hbox"],allowedInText:!0},handler:function(t,e){return{type:"enclose",mode:t.parser.mode,label:"\\fbox",body:e[0]}}}),_t({type:"enclose",names:["\\cancel","\\bcancel","\\xcancel","\\sout"],props:{numArgs:1},handler:function(t,e,r){var a=t.parser,n=t.funcName,i=e[0];return{type:"enclose",mode:a.mode,label:n,body:i}},htmlBuilder:pr,mathmlBuilder:dr});var fr={};function gr(t){for(var e=t.type,r=t.names,a=t.props,n=t.handler,i=t.htmlBuilder,o=t.mathmlBuilder,s={type:e,numArgs:a.numArgs||0,greediness:1,allowedInText:!1,numOptionalArgs:0,handler:n},l=0;l<r.length;++l)fr[r[l]]=s;i&&(Wt[e]=i),o&&(Xt[e]=o)}function xr(t){var e=[];t.consumeSpaces();for(var r=t.fetch().text;"\\hline"===r||"\\hdashline"===r;)t.consume(),e.push("\\hdashline"===r),t.consumeSpaces(),r=t.fetch().text;return e}function vr(t,e,r){var a=e.hskipBeforeAndAfter,n=e.addJot,i=e.cols,s=e.arraystretch,l=e.colSeparationType;if(t.gullet.beginGroup(),t.gullet.macros.set("\\\\","\\cr"),!s){var h=t.gullet.expandMacroAsText("\\arraystretch");if(null==h)s=1;else if(!(s=parseFloat(h))||s<0)throw new o("Invalid \\arraystretch: "+h)}t.gullet.beginGroup();var m=[],c=[m],u=[],p=[];for(p.push(xr(t));;){var d=t.parseExpression(!1,"\\cr");t.gullet.endGroup(),t.gullet.beginGroup(),d={type:"ordgroup",mode:t.mode,body:d},r&&(d={type:"styling",mode:t.mode,style:r,body:[d]}),m.push(d);var f=t.fetch().text;if("&"===f)t.consume();else{if("\\end"===f){1===m.length&&"styling"===d.type&&0===d.body[0].body.length&&c.pop(),p.length<c.length+1&&p.push([]);break}if("\\cr"!==f)throw new o("Expected & or \\\\ or \\cr or \\end",t.nextToken);var g=Ce(t.parseFunction(),"cr");u.push(g.size),p.push(xr(t)),m=[],c.push(m)}}return t.gullet.endGroup(),t.gullet.endGroup(),{type:"array",mode:t.mode,addJot:n,arraystretch:s,body:c,cols:i,rowGaps:u,hskipBeforeAndAfter:a,hLinesBeforeRow:p,colSeparationType:l}}function br(t){return"d"===t.substr(0,1)?"display":"text"}var yr=function(t,e){var r,a,n=t.body.length,i=t.hLinesBeforeRow,s=0,l=new Array(n),h=[],m=Math.max(e.fontMetrics().arrayRuleWidth,e.minRuleThickness),u=1/e.fontMetrics().ptPerEm,p=5*u;t.colSeparationType&&"small"===t.colSeparationType&&(p=e.havingStyle(w.SCRIPT).sizeMultiplier/e.sizeMultiplier*.2778);var d=12*u,f=3*u,g=t.arraystretch*d,x=.7*g,v=.3*g,b=0;function y(t){for(var e=0;e<t.length;++e)e>0&&(b+=.25),h.push({pos:b,isDashed:t[e]})}for(y(i[0]),r=0;r<t.body.length;++r){var k=t.body[r],S=x,M=v;s<k.length&&(s=k.length);var z=new Array(k.length);for(a=0;a<k.length;++a){var A=oe(k[a],e);M<A.depth&&(M=A.depth),S<A.height&&(S=A.height),z[a]=A}var T=t.rowGaps[r],B=0;T&&(B=Tt(T,e))>0&&(M<(B+=v)&&(M=B),B=0),t.addJot&&(M+=f),z.height=S,z.depth=M,b+=S,z.pos=b,b+=M+B,l[r]=z,y(i[r+1])}var C,q,N=b/2+e.fontMetrics().axisHeight,I=t.cols||[],O=[];for(a=0,q=0;a<s||q<I.length;++a,++q){for(var R=I[q]||{},E=!0;"separator"===R.type;){if(E||((C=Dt.makeSpan(["arraycolsep"],[])).style.width=e.fontMetrics().doubleRuleSep+"em",O.push(C)),"|"!==R.separator&&":"!==R.separator)throw new o("Invalid separator type: "+R.separator);var L="|"===R.separator?"solid":"dashed",P=Dt.makeSpan(["vertical-separator"],[],e);P.style.height=b+"em",P.style.borderRightWidth=m+"em",P.style.borderRightStyle=L,P.style.margin="0 -"+m/2+"em",P.style.verticalAlign=-(b-N)+"em",O.push(P),R=I[++q]||{},E=!1}if(!(a>=s)){var D=void 0;(a>0||t.hskipBeforeAndAfter)&&0!==(D=c.deflt(R.pregap,p))&&((C=Dt.makeSpan(["arraycolsep"],[])).style.width=D+"em",O.push(C));var H=[];for(r=0;r<n;++r){var F=l[r],V=F[a];if(V){var U=F.pos-N;V.depth=F.depth,V.height=F.height,H.push({type:"elem",elem:V,shift:U})}}H=Dt.makeVList({positionType:"individualShift",children:H},e),H=Dt.makeSpan(["col-align-"+(R.align||"c")],[H]),O.push(H),(a<s-1||t.hskipBeforeAndAfter)&&0!==(D=c.deflt(R.postgap,p))&&((C=Dt.makeSpan(["arraycolsep"],[])).style.width=D+"em",O.push(C))}}if(l=Dt.makeSpan(["mtable"],O),h.length>0){for(var G=Dt.makeLineSpan("hline",e,m),Y=Dt.makeLineSpan("hdashline",e,m),W=[{type:"elem",elem:l,shift:0}];h.length>0;){var X=h.pop(),_=X.pos-N;X.isDashed?W.push({type:"elem",elem:Y,shift:_}):W.push({type:"elem",elem:G,shift:_})}l=Dt.makeVList({positionType:"individualShift",children:W},e)}return Dt.makeSpan(["mord"],[l],e)},wr={c:"center ",l:"left ",r:"right "},kr=function(t,e){var r=new ue.MathNode("mtable",t.body.map(function(t){return new ue.MathNode("mtr",t.map(function(t){return new ue.MathNode("mtd",[ve(t,e)])}))})),a=.5===t.arraystretch?.1:.16+t.arraystretch-1+(t.addJot?.09:0);r.setAttribute("rowspacing",a+"em");var n="",i="";if(t.cols&&t.cols.length>0){var o=t.cols,s="",l=!1,h=0,m=o.length;"separator"===o[0].type&&(n+="top ",h=1),"separator"===o[o.length-1].type&&(n+="bottom ",m-=1);for(var c=h;c<m;c++)"align"===o[c].type?(i+=wr[o[c].align],l&&(s+="none "),l=!0):"separator"===o[c].type&&l&&(s+="|"===o[c].separator?"solid ":"dashed ",l=!1);r.setAttribute("columnalign",i.trim()),/[sd]/.test(s)&&r.setAttribute("columnlines",s.trim())}if("align"===t.colSeparationType){for(var u=t.cols||[],p="",d=1;d<u.length;d++)p+=d%2?"0em ":"1em ";r.setAttribute("columnspacing",p.trim())}else"alignat"===t.colSeparationType?r.setAttribute("columnspacing","0em"):"small"===t.colSeparationType?r.setAttribute("columnspacing","0.2778em"):r.setAttribute("columnspacing","1em");var f="",g=t.hLinesBeforeRow;n+=g[0].length>0?"left ":"",n+=g[g.length-1].length>0?"right ":"";for(var x=1;x<g.length-1;x++)f+=0===g[x].length?"none ":g[x][0]?"dashed ":"solid ";return/[sd]/.test(f)&&r.setAttribute("rowlines",f.trim()),""!==n&&(r=new ue.MathNode("menclose",[r])).setAttribute("notation",n.trim()),t.arraystretch&&t.arraystretch<1&&(r=new ue.MathNode("mstyle",[r])).setAttribute("scriptlevel","1"),r},Sr=function(t,e){var r,a=[],n=vr(t.parser,{cols:a,addJot:!0},"display"),i=0,s={type:"ordgroup",mode:t.mode,body:[]};if(e[0]&&"ordgroup"===e[0].type){for(var l="",h=0;h<e[0].body.length;h++){l+=Ce(e[0].body[h],"textord").text}r=Number(l),i=2*r}var m=!i;n.body.forEach(function(t){for(var e=1;e<t.length;e+=2){var a=Ce(t[e],"styling");Ce(a.body[0],"ordgroup").body.unshift(s)}if(m)i<t.length&&(i=t.length);else{var n=t.length/2;if(r<n)throw new o("Too many math in a row: expected "+r+", but got "+n,t[0])}});for(var c=0;c<i;++c){var u="r",p=0;c%2==1?u="l":c>0&&m&&(p=1),a[c]={type:"align",align:u,pregap:p,postgap:0}}return n.colSeparationType=m?"align":"alignat",n};gr({type:"array",names:["array","darray"],props:{numArgs:1},handler:function(t,e){var r={cols:(Ne(e[0])?[e[0]]:Ce(e[0],"ordgroup").body).map(function(t){var e=qe(t).text;if(-1!=="lcr".indexOf(e))return{type:"align",align:e};if("|"===e)return{type:"separator",separator:"|"};if(":"===e)return{type:"separator",separator:":"};throw new o("Unknown column alignment: "+e,t)}),hskipBeforeAndAfter:!0};return vr(t.parser,r,br(t.envName))},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["matrix","pmatrix","bmatrix","Bmatrix","vmatrix","Vmatrix"],props:{numArgs:0},handler:function(t){var e={matrix:null,pmatrix:["(",")"],bmatrix:["[","]"],Bmatrix:["\\{","\\}"],vmatrix:["|","|"],Vmatrix:["\\Vert","\\Vert"]}[t.envName],r=vr(t.parser,{hskipBeforeAndAfter:!1},br(t.envName));return e?{type:"leftright",mode:t.mode,body:[r],left:e[0],right:e[1],rightColor:void 0}:r},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["smallmatrix"],props:{numArgs:0},handler:function(t){var e=vr(t.parser,{arraystretch:.5},"script");return e.colSeparationType="small",e},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["subarray"],props:{numArgs:1},handler:function(t,e){var r=(Ne(e[0])?[e[0]]:Ce(e[0],"ordgroup").body).map(function(t){var e=qe(t).text;if(-1!=="lc".indexOf(e))return{type:"align",align:e};throw new o("Unknown column alignment: "+e,t)});if(r.length>1)throw new o("{subarray} can contain only one column");var a={cols:r,hskipBeforeAndAfter:!1,arraystretch:.5};if((a=vr(t.parser,a,"script")).body.length>0&&a.body[0].length>1)throw new o("{subarray} can contain only one column");return a},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["cases","dcases","rcases","drcases"],props:{numArgs:0},handler:function(t){var e=vr(t.parser,{arraystretch:1.2,cols:[{type:"align",align:"l",pregap:0,postgap:1},{type:"align",align:"l",pregap:0,postgap:0}]},br(t.envName));return{type:"leftright",mode:t.mode,body:[e],left:t.envName.indexOf("r")>-1?".":"\\{",right:t.envName.indexOf("r")>-1?"\\}":".",rightColor:void 0}},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["aligned"],props:{numArgs:0},handler:Sr,htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["gathered"],props:{numArgs:0},handler:function(t){return vr(t.parser,{cols:[{type:"align",align:"c"}],addJot:!0},"display")},htmlBuilder:yr,mathmlBuilder:kr}),gr({type:"array",names:["alignedat"],props:{numArgs:1},handler:Sr,htmlBuilder:yr,mathmlBuilder:kr}),_t({type:"text",names:["\\hline","\\hdashline"],props:{numArgs:0,allowedInText:!0,allowedInMath:!0},handler:function(t,e){throw new o(t.funcName+" valid only within array environment")}});var Mr=fr;_t({type:"environment",names:["\\begin","\\end"],props:{numArgs:1,argTypes:["text"]},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];if("ordgroup"!==n.type)throw new o("Invalid environment name",n);for(var i="",s=0;s<n.body.length;++s)i+=Ce(n.body[s],"textord").text;if("\\begin"===a){if(!Mr.hasOwnProperty(i))throw new o("No such environment: "+i,n);var l=Mr[i],h=r.parseArguments("\\begin{"+i+"}",l),m=h.args,c=h.optArgs,u={mode:r.mode,envName:i,parser:r},p=l.handler(u,m,c);r.expect("\\end",!1);var d=r.nextToken,f=Ce(r.parseFunction(),"environment");if(f.name!==i)throw new o("Mismatch: \\begin{"+i+"} matched by \\end{"+f.name+"}",d);return p}return{type:"environment",mode:r.mode,name:i,nameGroup:n}}});var zr=Dt.makeSpan;function Ar(t,e){var r=ee(t.body,e,!0);return zr([t.mclass],r,e)}function Tr(t,e){var r,a=ge(t.body,e);return"minner"===t.mclass?ue.newDocumentFragment(a):("mord"===t.mclass?t.isCharacterBox?(r=a[0]).type="mi":r=new ue.MathNode("mi",a):(t.isCharacterBox?(r=a[0]).type="mo":r=new ue.MathNode("mo",a),"mbin"===t.mclass?(r.attributes.lspace="0.22em",r.attributes.rspace="0.22em"):"mpunct"===t.mclass?(r.attributes.lspace="0em",r.attributes.rspace="0.17em"):"mopen"!==t.mclass&&"mclose"!==t.mclass||(r.attributes.lspace="0em",r.attributes.rspace="0em")),r)}_t({type:"mclass",names:["\\mathord","\\mathbin","\\mathrel","\\mathopen","\\mathclose","\\mathpunct","\\mathinner"],props:{numArgs:1},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];return{type:"mclass",mode:r.mode,mclass:"m"+a.substr(5),body:$t(n),isCharacterBox:c.isCharacterBox(n)}},htmlBuilder:Ar,mathmlBuilder:Tr});var Br=function(t){var e="ordgroup"===t.type&&t.body.length?t.body[0]:t;return"atom"!==e.type||"bin"!==e.family&&"rel"!==e.family?"mord":"m"+e.family};_t({type:"mclass",names:["\\@binrel"],props:{numArgs:2},handler:function(t,e){return{type:"mclass",mode:t.parser.mode,mclass:Br(e[0]),body:[e[1]],isCharacterBox:c.isCharacterBox(e[1])}}}),_t({type:"mclass",names:["\\stackrel","\\overset","\\underset"],props:{numArgs:2},handler:function(t,e){var r,a=t.parser,n=t.funcName,i=e[1],o=e[0];r="\\stackrel"!==n?Br(i):"mrel";var s={type:"op",mode:i.mode,limits:!0,alwaysHandleSupSub:!0,parentIsSupSub:!1,symbol:!1,suppressBaseShift:"\\stackrel"!==n,body:$t(i)},l={type:"supsub",mode:o.mode,base:s,sup:"\\underset"===n?null:o,sub:"\\underset"===n?o:null};return{type:"mclass",mode:a.mode,mclass:r,body:[l],isCharacterBox:c.isCharacterBox(l)}},htmlBuilder:Ar,mathmlBuilder:Tr});var Cr=function(t,e){var r=t.font,a=e.withFont(r);return oe(t.body,a)},qr=function(t,e){var r=t.font,a=e.withFont(r);return ve(t.body,a)},Nr={"\\Bbb":"\\mathbb","\\bold":"\\mathbf","\\frak":"\\mathfrak","\\bm":"\\boldsymbol"};_t({type:"font",names:["\\mathrm","\\mathit","\\mathbf","\\mathnormal","\\mathbb","\\mathcal","\\mathfrak","\\mathscr","\\mathsf","\\mathtt","\\Bbb","\\bold","\\frak"],props:{numArgs:1,greediness:2},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0],i=a;return i in Nr&&(i=Nr[i]),{type:"font",mode:r.mode,font:i.slice(1),body:n}},htmlBuilder:Cr,mathmlBuilder:qr}),_t({type:"mclass",names:["\\boldsymbol","\\bm"],props:{numArgs:1,greediness:2},handler:function(t,e){var r=t.parser,a=e[0],n=c.isCharacterBox(a);return{type:"mclass",mode:r.mode,mclass:Br(a),body:[{type:"font",mode:r.mode,font:"boldsymbol",body:a}],isCharacterBox:n}}}),_t({type:"font",names:["\\rm","\\sf","\\tt","\\bf","\\it","\\cal"],props:{numArgs:0,allowedInText:!0},handler:function(t,e){var r=t.parser,a=t.funcName,n=t.breakOnTokenText,i=r.mode,o=r.parseExpression(!0,n);return{type:"font",mode:i,font:"math"+a.slice(1),body:{type:"ordgroup",mode:r.mode,body:o}}},htmlBuilder:Cr,mathmlBuilder:qr});var Ir=function(t,e){var r=e;return"display"===t?r=r.id>=w.SCRIPT.id?r.text():w.DISPLAY:"text"===t&&r.size===w.DISPLAY.size?r=w.TEXT:"script"===t?r=w.SCRIPT:"scriptscript"===t&&(r=w.SCRIPTSCRIPT),r},Or=function(t,e){var r,a=Ir(t.size,e.style),n=a.fracNum(),i=a.fracDen();r=e.havingStyle(n);var o=oe(t.numer,r,e);if(t.continued){var s=8.5/e.fontMetrics().ptPerEm,l=3.5/e.fontMetrics().ptPerEm;o.height=o.height<s?s:o.height,o.depth=o.depth<l?l:o.depth}r=e.havingStyle(i);var h,m,c,u,p,d,f,g,x,v,b=oe(t.denom,r,e);if(t.hasBarLine?(t.barSize?(m=Tt(t.barSize,e),h=Dt.makeLineSpan("frac-line",e,m)):h=Dt.makeLineSpan("frac-line",e),m=h.height,c=h.height):(h=null,m=0,c=e.fontMetrics().defaultRuleThickness),a.size===w.DISPLAY.size||"display"===t.size?(u=e.fontMetrics().num1,p=m>0?3*c:7*c,d=e.fontMetrics().denom1):(m>0?(u=e.fontMetrics().num2,p=c):(u=e.fontMetrics().num3,p=3*c),d=e.fontMetrics().denom2),h){var y=e.fontMetrics().axisHeight;u-o.depth-(y+.5*m)<p&&(u+=p-(u-o.depth-(y+.5*m))),y-.5*m-(b.height-d)<p&&(d+=p-(y-.5*m-(b.height-d)));var k=-(y-.5*m);f=Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:b,shift:d},{type:"elem",elem:h,shift:k},{type:"elem",elem:o,shift:-u}]},e)}else{var S=u-o.depth-(b.height-d);S<p&&(u+=.5*(p-S),d+=.5*(p-S)),f=Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:b,shift:d},{type:"elem",elem:o,shift:-u}]},e)}return r=e.havingStyle(a),f.height*=r.sizeMultiplier/e.sizeMultiplier,f.depth*=r.sizeMultiplier/e.sizeMultiplier,g=a.size===w.DISPLAY.size?e.fontMetrics().delim1:e.fontMetrics().delim2,x=null==t.leftDelim?ie(e,["mopen"]):sr(t.leftDelim,g,!0,e.havingStyle(a),t.mode,["mopen"]),v=t.continued?Dt.makeSpan([]):null==t.rightDelim?ie(e,["mclose"]):sr(t.rightDelim,g,!0,e.havingStyle(a),t.mode,["mclose"]),Dt.makeSpan(["mord"].concat(r.sizingClasses(e)),[x,Dt.makeSpan(["mfrac"],[f]),v],e)},Rr=function(t,e){var r=new ue.MathNode("mfrac",[ve(t.numer,e),ve(t.denom,e)]);if(t.hasBarLine){if(t.barSize){var a=Tt(t.barSize,e);r.setAttribute("linethickness",a+"em")}}else r.setAttribute("linethickness","0px");var n=Ir(t.size,e.style);if(n.size!==e.style.size){r=new ue.MathNode("mstyle",[r]);var i=n.size===w.DISPLAY.size?"true":"false";r.setAttribute("displaystyle",i),r.setAttribute("scriptlevel","0")}if(null!=t.leftDelim||null!=t.rightDelim){var o=[];if(null!=t.leftDelim){var s=new ue.MathNode("mo",[new ue.TextNode(t.leftDelim.replace("\\",""))]);s.setAttribute("fence","true"),o.push(s)}if(o.push(r),null!=t.rightDelim){var l=new ue.MathNode("mo",[new ue.TextNode(t.rightDelim.replace("\\",""))]);l.setAttribute("fence","true"),o.push(l)}return de(o)}return r};_t({type:"genfrac",names:["\\cfrac","\\dfrac","\\frac","\\tfrac","\\dbinom","\\binom","\\tbinom","\\\\atopfrac","\\\\bracefrac","\\\\brackfrac"],props:{numArgs:2,greediness:2},handler:function(t,e){var r,a=t.parser,n=t.funcName,i=e[0],o=e[1],s=null,l=null,h="auto";switch(n){case"\\cfrac":case"\\dfrac":case"\\frac":case"\\tfrac":r=!0;break;case"\\\\atopfrac":r=!1;break;case"\\dbinom":case"\\binom":case"\\tbinom":r=!1,s="(",l=")";break;case"\\\\bracefrac":r=!1,s="\\{",l="\\}";break;case"\\\\brackfrac":r=!1,s="[",l="]";break;default:throw new Error("Unrecognized genfrac command")}switch(n){case"\\cfrac":case"\\dfrac":case"\\dbinom":h="display";break;case"\\tfrac":case"\\tbinom":h="text"}return{type:"genfrac",mode:a.mode,continued:"\\cfrac"===n,numer:i,denom:o,hasBarLine:r,leftDelim:s,rightDelim:l,size:h,barSize:null}},htmlBuilder:Or,mathmlBuilder:Rr}),_t({type:"infix",names:["\\over","\\choose","\\atop","\\brace","\\brack"],props:{numArgs:0,infix:!0},handler:function(t){var e,r=t.parser,a=t.funcName,n=t.token;switch(a){case"\\over":e="\\frac";break;case"\\choose":e="\\binom";break;case"\\atop":e="\\\\atopfrac";break;case"\\brace":e="\\\\bracefrac";break;case"\\brack":e="\\\\brackfrac";break;default:throw new Error("Unrecognized infix genfrac command")}return{type:"infix",mode:r.mode,replaceWith:e,token:n}}});var Er=["display","text","script","scriptscript"],Lr=function(t){var e=null;return t.length>0&&(e="."===(e=t)?null:e),e};_t({type:"genfrac",names:["\\genfrac"],props:{numArgs:6,greediness:6,argTypes:["math","math","size","text","math","math"]},handler:function(t,e){var r,a=t.parser,n=e[4],i=e[5],o="atom"===e[0].type&&"open"===e[0].family?Lr(e[0].text):null,s="atom"===e[1].type&&"close"===e[1].family?Lr(e[1].text):null,l=Ce(e[2],"size"),h=null;r=!!l.isBlank||(h=l.value).number>0;var m="auto",c=e[3];if("ordgroup"===c.type){if(c.body.length>0){var u=Ce(c.body[0],"textord");m=Er[Number(u.text)]}}else c=Ce(c,"textord"),m=Er[Number(c.text)];return{type:"genfrac",mode:a.mode,numer:n,denom:i,continued:!1,hasBarLine:r,barSize:h,leftDelim:o,rightDelim:s,size:m}},htmlBuilder:Or,mathmlBuilder:Rr}),_t({type:"infix",names:["\\above"],props:{numArgs:1,argTypes:["size"],infix:!0},handler:function(t,e){var r=t.parser,a=(t.funcName,t.token);return{type:"infix",mode:r.mode,replaceWith:"\\\\abovefrac",size:Ce(e[0],"size").value,token:a}}}),_t({type:"genfrac",names:["\\\\abovefrac"],props:{numArgs:3,argTypes:["math","size","math"]},handler:function(t,e){var r=t.parser,a=(t.funcName,e[0]),n=function(t){if(!t)throw new Error("Expected non-null, but got "+String(t));return t}(Ce(e[1],"infix").size),i=e[2],o=n.number>0;return{type:"genfrac",mode:r.mode,numer:a,denom:i,continued:!1,hasBarLine:o,barSize:n,leftDelim:null,rightDelim:null,size:"auto"}},htmlBuilder:Or,mathmlBuilder:Rr});var Pr=function(t,e){var r,a,n=e.style;"supsub"===t.type?(r=t.sup?oe(t.sup,e.havingStyle(n.sup()),e):oe(t.sub,e.havingStyle(n.sub()),e),a=Ce(t.base,"horizBrace")):a=Ce(t,"horizBrace");var i,o=oe(a.base,e.havingBaseStyle(w.DISPLAY)),s=Be(a,e);if(a.isOver?(i=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:o},{type:"kern",size:.1},{type:"elem",elem:s}]},e)).children[0].children[0].children[1].classes.push("svg-align"):(i=Dt.makeVList({positionType:"bottom",positionData:o.depth+.1+s.height,children:[{type:"elem",elem:s},{type:"kern",size:.1},{type:"elem",elem:o}]},e)).children[0].children[0].children[0].classes.push("svg-align"),r){var l=Dt.makeSpan(["mord",a.isOver?"mover":"munder"],[i],e);i=a.isOver?Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:l},{type:"kern",size:.2},{type:"elem",elem:r}]},e):Dt.makeVList({positionType:"bottom",positionData:l.depth+.2+r.height+r.depth,children:[{type:"elem",elem:r},{type:"kern",size:.2},{type:"elem",elem:l}]},e)}return Dt.makeSpan(["mord",a.isOver?"mover":"munder"],[i],e)};_t({type:"horizBrace",names:["\\overbrace","\\underbrace"],props:{numArgs:1},handler:function(t,e){var r=t.parser,a=t.funcName;return{type:"horizBrace",mode:r.mode,label:a,isOver:/^\\over/.test(a),base:e[0]}},htmlBuilder:Pr,mathmlBuilder:function(t,e){var r=Te(t.label);return new ue.MathNode(t.isOver?"mover":"munder",[ve(t.base,e),r])}}),_t({type:"href",names:["\\href"],props:{numArgs:2,argTypes:["url","original"],allowedInText:!0},handler:function(t,e){var r=t.parser,a=e[1],n=Ce(e[0],"url").url;return r.settings.isTrusted({command:"\\href",url:n})?{type:"href",mode:r.mode,href:n,body:$t(a)}:r.formatUnsupportedCmd("\\href")},htmlBuilder:function(t,e){var r=ee(t.body,e,!1);return Dt.makeAnchor(t.href,[],r,e)},mathmlBuilder:function(t,e){var r=xe(t.body,e);return r instanceof me||(r=new me("mrow",[r])),r.setAttribute("href",t.href),r}}),_t({type:"href",names:["\\url"],props:{numArgs:1,argTypes:["url"],allowedInText:!0},handler:function(t,e){var r=t.parser,a=Ce(e[0],"url").url;if(!r.settings.isTrusted({command:"\\url",url:a}))return r.formatUnsupportedCmd("\\url");for(var n=[],i=0;i<a.length;i++){var o=a[i];"~"===o&&(o="\\textasciitilde"),n.push({type:"textord",mode:"text",text:o})}var s={type:"text",mode:r.mode,font:"\\texttt",body:n};return{type:"href",mode:r.mode,href:a,body:$t(s)}}}),_t({type:"html",names:["\\htmlClass","\\htmlId","\\htmlStyle","\\htmlData"],props:{numArgs:2,argTypes:["raw","original"],allowedInText:!0},handler:function(t,e){var r,a=t.parser,n=t.funcName,i=(t.token,Ce(e[0],"raw").string),s=e[1];a.settings.strict&&a.settings.reportNonstrict("htmlExtension","HTML extension is disabled on strict mode");var l={};switch(n){case"\\htmlClass":l.class=i,r={command:"\\htmlClass",class:i};break;case"\\htmlId":l.id=i,r={command:"\\htmlId",id:i};break;case"\\htmlStyle":l.style=i,r={command:"\\htmlStyle",style:i};break;case"\\htmlData":for(var h=i.split(","),m=0;m<h.length;m++){var c=h[m].split("=");if(2!==c.length)throw new o("Error parsing key-value for \\htmlData");l["data-"+c[0].trim()]=c[1].trim()}r={command:"\\htmlData",attributes:l};break;default:throw new Error("Unrecognized html command")}return a.settings.isTrusted(r)?{type:"html",mode:a.mode,attributes:l,body:$t(s)}:a.formatUnsupportedCmd(n)},htmlBuilder:function(t,e){var r=ee(t.body,e,!1),a=["enclosing"];t.attributes.class&&a.push.apply(a,t.attributes.class.trim().split(/\s+/));var n=Dt.makeSpan(a,r,e);for(var i in t.attributes)"class"!==i&&t.attributes.hasOwnProperty(i)&&n.setAttribute(i,t.attributes[i]);return n},mathmlBuilder:function(t,e){return xe(t.body,e)}}),_t({type:"htmlmathml",names:["\\html@mathml"],props:{numArgs:2,allowedInText:!0},handler:function(t,e){return{type:"htmlmathml",mode:t.parser.mode,html:$t(e[0]),mathml:$t(e[1])}},htmlBuilder:function(t,e){var r=ee(t.html,e,!1);return Dt.makeFragment(r)},mathmlBuilder:function(t,e){return xe(t.mathml,e)}});var Dr=function(t){if(/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(t))return{number:+t,unit:"bp"};var e=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(t);if(!e)throw new o("Invalid size: '"+t+"' in \\includegraphics");var r={number:+(e[1]+e[2]),unit:e[3]};if(!At(r))throw new o("Invalid unit: '"+r.unit+"' in \\includegraphics.");return r};_t({type:"includegraphics",names:["\\includegraphics"],props:{numArgs:1,numOptionalArgs:1,argTypes:["raw","url"],allowedInText:!1},handler:function(t,e,r){var a=t.parser,n={number:0,unit:"em"},i={number:.9,unit:"em"},s={number:0,unit:"em"},l="";if(r[0])for(var h=Ce(r[0],"raw").string.split(","),m=0;m<h.length;m++){var c=h[m].split("=");if(2===c.length){var u=c[1].trim();switch(c[0].trim()){case"alt":l=u;break;case"width":n=Dr(u);break;case"height":i=Dr(u);break;case"totalheight":s=Dr(u);break;default:throw new o("Invalid key: '"+c[0]+"' in \\includegraphics.")}}}var p=Ce(e[0],"url").url;return""===l&&(l=(l=(l=p).replace(/^.*[\\/]/,"")).substring(0,l.lastIndexOf("."))),a.settings.isTrusted({command:"\\includegraphics",url:p})?{type:"includegraphics",mode:a.mode,alt:l,width:n,height:i,totalheight:s,src:p}:a.formatUnsupportedCmd("\\includegraphics")},htmlBuilder:function(t,e){var r=Tt(t.height,e),a=0;t.totalheight.number>0&&(a=Tt(t.totalheight,e)-r,a=Number(a.toFixed(2)));var n=0;t.width.number>0&&(n=Tt(t.width,e));var i={height:r+a+"em"};n>0&&(i.width=n+"em"),a>0&&(i.verticalAlign=-a+"em");var o=new O(t.src,t.alt,i);return o.height=r,o.depth=a,o},mathmlBuilder:function(t,e){var r=new ue.MathNode("mglyph",[]);r.setAttribute("alt",t.alt);var a=Tt(t.height,e),n=0;if(t.totalheight.number>0&&(n=(n=Tt(t.totalheight,e)-a).toFixed(2),r.setAttribute("valign","-"+n+"em")),r.setAttribute("height",a+n+"em"),t.width.number>0){var i=Tt(t.width,e);r.setAttribute("width",i+"em")}return r.setAttribute("src",t.src),r}}),_t({type:"kern",names:["\\kern","\\mkern","\\hskip","\\mskip"],props:{numArgs:1,argTypes:["size"],allowedInText:!0},handler:function(t,e){var r=t.parser,a=t.funcName,n=Ce(e[0],"size");if(r.settings.strict){var i="m"===a[1],o="mu"===n.value.unit;i?(o||r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" supports only mu units, not "+n.value.unit+" units"),"math"!==r.mode&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" works only in math mode")):o&&r.settings.reportNonstrict("mathVsTextUnits","LaTeX's "+a+" doesn't support mu units")}return{type:"kern",mode:r.mode,dimension:n.value}},htmlBuilder:function(t,e){return Dt.makeGlue(t.dimension,e)},mathmlBuilder:function(t,e){var r=Tt(t.dimension,e);return new ue.SpaceNode(r)}}),_t({type:"lap",names:["\\mathllap","\\mathrlap","\\mathclap"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];return{type:"lap",mode:r.mode,alignment:a.slice(5),body:n}},htmlBuilder:function(t,e){var r;"clap"===t.alignment?(r=Dt.makeSpan([],[oe(t.body,e)]),r=Dt.makeSpan(["inner"],[r],e)):r=Dt.makeSpan(["inner"],[oe(t.body,e)]);var a=Dt.makeSpan(["fix"],[]),n=Dt.makeSpan([t.alignment],[r,a],e),i=Dt.makeSpan(["strut"]);return i.style.height=n.height+n.depth+"em",i.style.verticalAlign=-n.depth+"em",n.children.unshift(i),n=Dt.makeSpan(["thinbox"],[n],e),Dt.makeSpan(["mord","vbox"],[n],e)},mathmlBuilder:function(t,e){var r=new ue.MathNode("mpadded",[ve(t.body,e)]);if("rlap"!==t.alignment){var a="llap"===t.alignment?"-1":"-0.5";r.setAttribute("lspace",a+"width")}return r.setAttribute("width","0px"),r}}),_t({type:"styling",names:["\\(","$"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(t,e){var r=t.funcName,a=t.parser,n=a.mode;a.switchMode("math");var i="\\("===r?"\\)":"$",o=a.parseExpression(!1,i);return a.expect(i),a.switchMode(n),{type:"styling",mode:a.mode,style:"text",body:o}}}),_t({type:"text",names:["\\)","\\]"],props:{numArgs:0,allowedInText:!0,allowedInMath:!1},handler:function(t,e){throw new o("Mismatched "+t.funcName)}});var Hr=function(t,e){switch(e.style.size){case w.DISPLAY.size:return t.display;case w.TEXT.size:return t.text;case w.SCRIPT.size:return t.script;case w.SCRIPTSCRIPT.size:return t.scriptscript;default:return t.text}};_t({type:"mathchoice",names:["\\mathchoice"],props:{numArgs:4},handler:function(t,e){return{type:"mathchoice",mode:t.parser.mode,display:$t(e[0]),text:$t(e[1]),script:$t(e[2]),scriptscript:$t(e[3])}},htmlBuilder:function(t,e){var r=Hr(t,e),a=ee(r,e,!1);return Dt.makeFragment(a)},mathmlBuilder:function(t,e){var r=Hr(t,e);return xe(r,e)}});var Fr=function(t,e,r,a,n,i,o){var s,l,h;if(t=Dt.makeSpan([],[t]),e){var m=oe(e,a.havingStyle(n.sup()),a);l={elem:m,kern:Math.max(a.fontMetrics().bigOpSpacing1,a.fontMetrics().bigOpSpacing3-m.depth)}}if(r){var c=oe(r,a.havingStyle(n.sub()),a);s={elem:c,kern:Math.max(a.fontMetrics().bigOpSpacing2,a.fontMetrics().bigOpSpacing4-c.height)}}if(l&&s){var u=a.fontMetrics().bigOpSpacing5+s.elem.height+s.elem.depth+s.kern+t.depth+o;h=Dt.makeVList({positionType:"bottom",positionData:u,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:-i+"em"},{type:"kern",size:s.kern},{type:"elem",elem:t},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:i+"em"},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}else if(s){var p=t.height-o;h=Dt.makeVList({positionType:"top",positionData:p,children:[{type:"kern",size:a.fontMetrics().bigOpSpacing5},{type:"elem",elem:s.elem,marginLeft:-i+"em"},{type:"kern",size:s.kern},{type:"elem",elem:t}]},a)}else{if(!l)return t;var d=t.depth+o;h=Dt.makeVList({positionType:"bottom",positionData:d,children:[{type:"elem",elem:t},{type:"kern",size:l.kern},{type:"elem",elem:l.elem,marginLeft:i+"em"},{type:"kern",size:a.fontMetrics().bigOpSpacing5}]},a)}return Dt.makeSpan(["mop","op-limits"],[h],a)},Vr=["\\smallint"],Ur=function(t,e){var r,a,n,i=!1;"supsub"===t.type?(r=t.sup,a=t.sub,n=Ce(t.base,"op"),i=!0):n=Ce(t,"op");var o,s=e.style,l=!1;if(s.size===w.DISPLAY.size&&n.symbol&&!c.contains(Vr,n.name)&&(l=!0),n.symbol){var h=l?"Size2-Regular":"Size1-Regular",m="";if("\\oiint"!==n.name&&"\\oiiint"!==n.name||(m=n.name.substr(1),n.name="oiint"===m?"\\iint":"\\iiint"),o=Dt.makeSymbol(n.name,h,"math",e,["mop","op-symbol",l?"large-op":"small-op"]),m.length>0){var u=o.italic,p=Dt.staticSvg(m+"Size"+(l?"2":"1"),e);o=Dt.makeVList({positionType:"individualShift",children:[{type:"elem",elem:o,shift:0},{type:"elem",elem:p,shift:l?.08:0}]},e),n.name="\\"+m,o.classes.unshift("mop"),o.italic=u}}else if(n.body){var d=ee(n.body,e,!0);1===d.length&&d[0]instanceof E?(o=d[0]).classes[0]="mop":o=Dt.makeSpan(["mop"],Dt.tryCombineChars(d),e)}else{for(var f=[],g=1;g<n.name.length;g++)f.push(Dt.mathsym(n.name[g],n.mode,e));o=Dt.makeSpan(["mop"],f,e)}var x=0,v=0;return(o instanceof E||"\\oiint"===n.name||"\\oiiint"===n.name)&&!n.suppressBaseShift&&(x=(o.height-o.depth)/2-e.fontMetrics().axisHeight,v=o.italic),i?Fr(o,r,a,e,s,v,x):(x&&(o.style.position="relative",o.style.top=x+"em"),o)},Gr=function(t,e){var r;if(t.symbol)r=new me("mo",[pe(t.name,t.mode)]),c.contains(Vr,t.name)&&r.setAttribute("largeop","false");else if(t.body)r=new me("mo",ge(t.body,e));else{r=new me("mi",[new ce(t.name.slice(1))]);var a=new me("mo",[pe("\u2061","text")]);r=t.parentIsSupSub?new me("mo",[r,a]):he([r,a])}return r},Yr={"\u220f":"\\prod","\u2210":"\\coprod","\u2211":"\\sum","\u22c0":"\\bigwedge","\u22c1":"\\bigvee","\u22c2":"\\bigcap","\u22c3":"\\bigcup","\u2a00":"\\bigodot","\u2a01":"\\bigoplus","\u2a02":"\\bigotimes","\u2a04":"\\biguplus","\u2a06":"\\bigsqcup"};_t({type:"op",names:["\\coprod","\\bigvee","\\bigwedge","\\biguplus","\\bigcap","\\bigcup","\\intop","\\prod","\\sum","\\bigotimes","\\bigoplus","\\bigodot","\\bigsqcup","\\smallint","\u220f","\u2210","\u2211","\u22c0","\u22c1","\u22c2","\u22c3","\u2a00","\u2a01","\u2a02","\u2a04","\u2a06"],props:{numArgs:0},handler:function(t,e){var r=t.parser,a=t.funcName;return 1===a.length&&(a=Yr[a]),{type:"op",mode:r.mode,limits:!0,parentIsSupSub:!1,symbol:!0,name:a}},htmlBuilder:Ur,mathmlBuilder:Gr}),_t({type:"op",names:["\\mathop"],props:{numArgs:1},handler:function(t,e){var r=t.parser,a=e[0];return{type:"op",mode:r.mode,limits:!1,parentIsSupSub:!1,symbol:!1,body:$t(a)}},htmlBuilder:Ur,mathmlBuilder:Gr});var Wr={"\u222b":"\\int","\u222c":"\\iint","\u222d":"\\iiint","\u222e":"\\oint","\u222f":"\\oiint","\u2230":"\\oiiint"};_t({type:"op",names:["\\arcsin","\\arccos","\\arctan","\\arctg","\\arcctg","\\arg","\\ch","\\cos","\\cosec","\\cosh","\\cot","\\cotg","\\coth","\\csc","\\ctg","\\cth","\\deg","\\dim","\\exp","\\hom","\\ker","\\lg","\\ln","\\log","\\sec","\\sin","\\sinh","\\sh","\\tan","\\tanh","\\tg","\\th"],props:{numArgs:0},handler:function(t){var e=t.parser,r=t.funcName;return{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:Ur,mathmlBuilder:Gr}),_t({type:"op",names:["\\det","\\gcd","\\inf","\\lim","\\max","\\min","\\Pr","\\sup"],props:{numArgs:0},handler:function(t){var e=t.parser,r=t.funcName;return{type:"op",mode:e.mode,limits:!0,parentIsSupSub:!1,symbol:!1,name:r}},htmlBuilder:Ur,mathmlBuilder:Gr}),_t({type:"op",names:["\\int","\\iint","\\iiint","\\oint","\\oiint","\\oiiint","\u222b","\u222c","\u222d","\u222e","\u222f","\u2230"],props:{numArgs:0},handler:function(t){var e=t.parser,r=t.funcName;return 1===r.length&&(r=Wr[r]),{type:"op",mode:e.mode,limits:!1,parentIsSupSub:!1,symbol:!0,name:r}},htmlBuilder:Ur,mathmlBuilder:Gr});var Xr=function(t,e){var r,a,n,i,o=!1;if("supsub"===t.type?(r=t.sup,a=t.sub,n=Ce(t.base,"operatorname"),o=!0):n=Ce(t,"operatorname"),n.body.length>0){for(var s=n.body.map(function(t){var e=t.text;return"string"==typeof e?{type:"textord",mode:t.mode,text:e}:t}),l=ee(s,e.withFont("mathrm"),!0),h=0;h<l.length;h++){var m=l[h];m instanceof E&&(m.text=m.text.replace(/\u2212/,"-").replace(/\u2217/,"*"))}i=Dt.makeSpan(["mop"],l,e)}else i=Dt.makeSpan(["mop"],[],e);return o?Fr(i,r,a,e,e.style,0,0):i};function _r(t,e,r){for(var a=ee(t,e,!1),n=e.sizeMultiplier/r.sizeMultiplier,i=0;i<a.length;i++){var o=a[i].classes.indexOf("sizing");o<0?Array.prototype.push.apply(a[i].classes,e.sizingClasses(r)):a[i].classes[o+1]==="reset-size"+e.size&&(a[i].classes[o+1]="reset-size"+r.size),a[i].height*=n,a[i].depth*=n}return Dt.makeFragment(a)}_t({type:"operatorname",names:["\\operatorname","\\operatorname*"],props:{numArgs:1},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];return{type:"operatorname",mode:r.mode,body:$t(n),alwaysHandleSupSub:"\\operatorname*"===a,limits:!1,parentIsSupSub:!1}},htmlBuilder:Xr,mathmlBuilder:function(t,e){for(var r=ge(t.body,e.withFont("mathrm")),a=!0,n=0;n<r.length;n++){var i=r[n];if(i instanceof ue.SpaceNode);else if(i instanceof ue.MathNode)switch(i.type){case"mi":case"mn":case"ms":case"mspace":case"mtext":break;case"mo":var o=i.children[0];1===i.children.length&&o instanceof ue.TextNode?o.text=o.text.replace(/\u2212/,"-").replace(/\u2217/,"*"):a=!1;break;default:a=!1}else a=!1}if(a){var s=r.map(function(t){return t.toText()}).join("");r=[new ue.TextNode(s)]}var l=new ue.MathNode("mi",r);l.setAttribute("mathvariant","normal");var h=new ue.MathNode("mo",[pe("\u2061","text")]);return t.parentIsSupSub?new ue.MathNode("mo",[l,h]):ue.newDocumentFragment([l,h])}}),jt({type:"ordgroup",htmlBuilder:function(t,e){return t.semisimple?Dt.makeFragment(ee(t.body,e,!1)):Dt.makeSpan(["mord"],ee(t.body,e,!0),e)},mathmlBuilder:function(t,e){return xe(t.body,e,!0)}}),_t({type:"overline",names:["\\overline"],props:{numArgs:1},handler:function(t,e){var r=t.parser,a=e[0];return{type:"overline",mode:r.mode,body:a}},htmlBuilder:function(t,e){var r=oe(t.body,e.havingCrampedStyle()),a=Dt.makeLineSpan("overline-line",e),n=e.fontMetrics().defaultRuleThickness,i=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r},{type:"kern",size:3*n},{type:"elem",elem:a},{type:"kern",size:n}]},e);return Dt.makeSpan(["mord","overline"],[i],e)},mathmlBuilder:function(t,e){var r=new ue.MathNode("mo",[new ue.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new ue.MathNode("mover",[ve(t.body,e),r]);return a.setAttribute("accent","true"),a}}),_t({type:"phantom",names:["\\phantom"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){var r=t.parser,a=e[0];return{type:"phantom",mode:r.mode,body:$t(a)}},htmlBuilder:function(t,e){var r=ee(t.body,e.withPhantom(),!1);return Dt.makeFragment(r)},mathmlBuilder:function(t,e){var r=ge(t.body,e);return new ue.MathNode("mphantom",r)}}),_t({type:"hphantom",names:["\\hphantom"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){var r=t.parser,a=e[0];return{type:"hphantom",mode:r.mode,body:a}},htmlBuilder:function(t,e){var r=Dt.makeSpan([],[oe(t.body,e.withPhantom())]);if(r.height=0,r.depth=0,r.children)for(var a=0;a<r.children.length;a++)r.children[a].height=0,r.children[a].depth=0;return r=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r}]},e),Dt.makeSpan(["mord"],[r],e)},mathmlBuilder:function(t,e){var r=ge($t(t.body),e),a=new ue.MathNode("mphantom",r),n=new ue.MathNode("mpadded",[a]);return n.setAttribute("height","0px"),n.setAttribute("depth","0px"),n}}),_t({type:"vphantom",names:["\\vphantom"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){var r=t.parser,a=e[0];return{type:"vphantom",mode:r.mode,body:a}},htmlBuilder:function(t,e){var r=Dt.makeSpan(["inner"],[oe(t.body,e.withPhantom())]),a=Dt.makeSpan(["fix"],[]);return Dt.makeSpan(["mord","rlap"],[r,a],e)},mathmlBuilder:function(t,e){var r=ge($t(t.body),e),a=new ue.MathNode("mphantom",r),n=new ue.MathNode("mpadded",[a]);return n.setAttribute("width","0px"),n}}),_t({type:"raisebox",names:["\\raisebox"],props:{numArgs:2,argTypes:["size","hbox"],allowedInText:!0},handler:function(t,e){var r=t.parser,a=Ce(e[0],"size").value,n=e[1];return{type:"raisebox",mode:r.mode,dy:a,body:n}},htmlBuilder:function(t,e){var r=oe(t.body,e),a=Tt(t.dy,e);return Dt.makeVList({positionType:"shift",positionData:-a,children:[{type:"elem",elem:r}]},e)},mathmlBuilder:function(t,e){var r=new ue.MathNode("mpadded",[ve(t.body,e)]),a=t.dy.number+t.dy.unit;return r.setAttribute("voffset",a),r}}),_t({type:"rule",names:["\\rule"],props:{numArgs:2,numOptionalArgs:1,argTypes:["size","size","size"]},handler:function(t,e,r){var a=t.parser,n=r[0],i=Ce(e[0],"size"),o=Ce(e[1],"size");return{type:"rule",mode:a.mode,shift:n&&Ce(n,"size").value,width:i.value,height:o.value}},htmlBuilder:function(t,e){var r=Dt.makeSpan(["mord","rule"],[],e),a=Tt(t.width,e),n=Tt(t.height,e),i=t.shift?Tt(t.shift,e):0;return r.style.borderRightWidth=a+"em",r.style.borderTopWidth=n+"em",r.style.bottom=i+"em",r.width=a,r.height=n+i,r.depth=-i,r.maxFontSize=1.125*n*e.sizeMultiplier,r},mathmlBuilder:function(t,e){var r=Tt(t.width,e),a=Tt(t.height,e),n=t.shift?Tt(t.shift,e):0,i=e.color&&e.getColor()||"black",o=new ue.MathNode("mspace");o.setAttribute("mathbackground",i),o.setAttribute("width",r+"em"),o.setAttribute("height",a+"em");var s=new ue.MathNode("mpadded",[o]);return n>=0?s.setAttribute("height","+"+n+"em"):(s.setAttribute("height",n+"em"),s.setAttribute("depth","+"+-n+"em")),s.setAttribute("voffset",n+"em"),s}});var jr=["\\tiny","\\sixptsize","\\scriptsize","\\footnotesize","\\small","\\normalsize","\\large","\\Large","\\LARGE","\\huge","\\Huge"];_t({type:"sizing",names:jr,props:{numArgs:0,allowedInText:!0},handler:function(t,e){var r=t.breakOnTokenText,a=t.funcName,n=t.parser,i=n.parseExpression(!1,r);return{type:"sizing",mode:n.mode,size:jr.indexOf(a)+1,body:i}},htmlBuilder:function(t,e){var r=e.havingSize(t.size);return _r(t.body,r,e)},mathmlBuilder:function(t,e){var r=e.havingSize(t.size),a=ge(t.body,r),n=new ue.MathNode("mstyle",a);return n.setAttribute("mathsize",r.sizeMultiplier+"em"),n}}),_t({type:"smash",names:["\\smash"],props:{numArgs:1,numOptionalArgs:1,allowedInText:!0},handler:function(t,e,r){var a=t.parser,n=!1,i=!1,o=r[0]&&Ce(r[0],"ordgroup");if(o)for(var s="",l=0;l<o.body.length;++l){if("t"===(s=o.body[l].text))n=!0;else{if("b"!==s){n=!1,i=!1;break}i=!0}}else n=!0,i=!0;var h=e[0];return{type:"smash",mode:a.mode,body:h,smashHeight:n,smashDepth:i}},htmlBuilder:function(t,e){var r=Dt.makeSpan([],[oe(t.body,e)]);if(!t.smashHeight&&!t.smashDepth)return r;if(t.smashHeight&&(r.height=0,r.children))for(var a=0;a<r.children.length;a++)r.children[a].height=0;if(t.smashDepth&&(r.depth=0,r.children))for(var n=0;n<r.children.length;n++)r.children[n].depth=0;var i=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r}]},e);return Dt.makeSpan(["mord"],[i],e)},mathmlBuilder:function(t,e){var r=new ue.MathNode("mpadded",[ve(t.body,e)]);return t.smashHeight&&r.setAttribute("height","0px"),t.smashDepth&&r.setAttribute("depth","0px"),r}}),_t({type:"sqrt",names:["\\sqrt"],props:{numArgs:1,numOptionalArgs:1},handler:function(t,e,r){var a=t.parser,n=r[0],i=e[0];return{type:"sqrt",mode:a.mode,body:i,index:n}},htmlBuilder:function(t,e){var r=oe(t.body,e.havingCrampedStyle());0===r.height&&(r.height=e.fontMetrics().xHeight),r=Dt.wrapFragment(r,e);var a=e.fontMetrics().defaultRuleThickness,n=a;e.style.id<w.TEXT.id&&(n=e.fontMetrics().xHeight);var i=a+n/4,o=r.height+r.depth+i+a,s=ir(o,e),l=s.span,h=s.ruleWidth,m=s.advanceWidth,c=l.height-h;c>r.height+r.depth+i&&(i=(i+c-r.height-r.depth)/2);var u=l.height-r.height-i-h;r.style.paddingLeft=m+"em";var p=Dt.makeVList({positionType:"firstBaseline",children:[{type:"elem",elem:r,wrapperClasses:["svg-align"]},{type:"kern",size:-(r.height+u)},{type:"elem",elem:l},{type:"kern",size:h}]},e);if(t.index){var d=e.havingStyle(w.SCRIPTSCRIPT),f=oe(t.index,d,e),g=.6*(p.height-p.depth),x=Dt.makeVList({positionType:"shift",positionData:-g,children:[{type:"elem",elem:f}]},e),v=Dt.makeSpan(["root"],[x]);return Dt.makeSpan(["mord","sqrt"],[v,p],e)}return Dt.makeSpan(["mord","sqrt"],[p],e)},mathmlBuilder:function(t,e){var r=t.body,a=t.index;return a?new ue.MathNode("mroot",[ve(r,e),ve(a,e)]):new ue.MathNode("msqrt",[ve(r,e)])}});var $r={display:w.DISPLAY,text:w.TEXT,script:w.SCRIPT,scriptscript:w.SCRIPTSCRIPT};_t({type:"styling",names:["\\displaystyle","\\textstyle","\\scriptstyle","\\scriptscriptstyle"],props:{numArgs:0,allowedInText:!0},handler:function(t,e){var r=t.breakOnTokenText,a=t.funcName,n=t.parser,i=n.parseExpression(!0,r),o=a.slice(1,a.length-5);return{type:"styling",mode:n.mode,style:o,body:i}},htmlBuilder:function(t,e){var r=$r[t.style],a=e.havingStyle(r).withFont("");return _r(t.body,a,e)},mathmlBuilder:function(t,e){var r=$r[t.style],a=e.havingStyle(r),n=ge(t.body,a),i=new ue.MathNode("mstyle",n),o={display:["0","true"],text:["0","false"],script:["1","false"],scriptscript:["2","false"]}[t.style];return i.setAttribute("scriptlevel",o[0]),i.setAttribute("displaystyle",o[1]),i}});jt({type:"supsub",htmlBuilder:function(t,e){var r=function(t,e){var r=t.base;return r?"op"===r.type?r.limits&&(e.style.size===w.DISPLAY.size||r.alwaysHandleSupSub)?Ur:null:"operatorname"===r.type?r.alwaysHandleSupSub&&(e.style.size===w.DISPLAY.size||r.limits)?Xr:null:"accent"===r.type?c.isCharacterBox(r.base)?Ie:null:"horizBrace"===r.type&&!t.sub===r.isOver?Pr:null:null}(t,e);if(r)return r(t,e);var a,n,i,o=t.base,s=t.sup,l=t.sub,h=oe(o,e),m=e.fontMetrics(),u=0,p=0,d=o&&c.isCharacterBox(o);if(s){var f=e.havingStyle(e.style.sup());a=oe(s,f,e),d||(u=h.height-f.fontMetrics().supDrop*f.sizeMultiplier/e.sizeMultiplier)}if(l){var g=e.havingStyle(e.style.sub());n=oe(l,g,e),d||(p=h.depth+g.fontMetrics().subDrop*g.sizeMultiplier/e.sizeMultiplier)}i=e.style===w.DISPLAY?m.sup1:e.style.cramped?m.sup3:m.sup2;var x,v=e.sizeMultiplier,b=.5/m.ptPerEm/v+"em",y=null;if(n){var k=t.base&&"op"===t.base.type&&t.base.name&&("\\oiint"===t.base.name||"\\oiiint"===t.base.name);(h instanceof E||k)&&(y=-h.italic+"em")}if(a&&n){u=Math.max(u,i,a.depth+.25*m.xHeight),p=Math.max(p,m.sub2);var S=4*m.defaultRuleThickness;if(u-a.depth-(n.height-p)<S){p=S-(u-a.depth)+n.height;var M=.8*m.xHeight-(u-a.depth);M>0&&(u+=M,p-=M)}var z=[{type:"elem",elem:n,shift:p,marginRight:b,marginLeft:y},{type:"elem",elem:a,shift:-u,marginRight:b}];x=Dt.makeVList({positionType:"individualShift",children:z},e)}else if(n){p=Math.max(p,m.sub1,n.height-.8*m.xHeight);var A=[{type:"elem",elem:n,marginLeft:y,marginRight:b}];x=Dt.makeVList({positionType:"shift",positionData:p,children:A},e)}else{if(!a)throw new Error("supsub must have either sup or sub.");u=Math.max(u,i,a.depth+.25*m.xHeight),x=Dt.makeVList({positionType:"shift",positionData:-u,children:[{type:"elem",elem:a,marginRight:b}]},e)}var T=ne(h,"right")||"mord";return Dt.makeSpan([T],[h,Dt.makeSpan(["msupsub"],[x])],e)},mathmlBuilder:function(t,e){var r,a=!1;t.base&&"horizBrace"===t.base.type&&!!t.sup===t.base.isOver&&(a=!0,r=t.base.isOver),!t.base||"op"!==t.base.type&&"operatorname"!==t.base.type||(t.base.parentIsSupSub=!0);var n,i=[ve(t.base,e)];if(t.sub&&i.push(ve(t.sub,e)),t.sup&&i.push(ve(t.sup,e)),a)n=r?"mover":"munder";else if(t.sub)if(t.sup){var o=t.base;n=o&&"op"===o.type&&o.limits&&e.style===w.DISPLAY?"munderover":o&&"operatorname"===o.type&&o.alwaysHandleSupSub&&(e.style===w.DISPLAY||o.limits)?"munderover":"msubsup"}else{var s=t.base;n=s&&"op"===s.type&&s.limits&&(e.style===w.DISPLAY||s.alwaysHandleSupSub)?"munder":s&&"operatorname"===s.type&&s.alwaysHandleSupSub&&(s.limits||e.style===w.DISPLAY)?"munder":"msub"}else{var l=t.base;n=l&&"op"===l.type&&l.limits&&(e.style===w.DISPLAY||l.alwaysHandleSupSub)?"mover":l&&"operatorname"===l.type&&l.alwaysHandleSupSub&&(l.limits||e.style===w.DISPLAY)?"mover":"msup"}return new ue.MathNode(n,i)}}),jt({type:"atom",htmlBuilder:function(t,e){return Dt.mathsym(t.text,t.mode,e,["m"+t.family])},mathmlBuilder:function(t,e){var r=new ue.MathNode("mo",[pe(t.text,t.mode)]);if("bin"===t.family){var a=fe(t,e);"bold-italic"===a&&r.setAttribute("mathvariant",a)}else"punct"===t.family?r.setAttribute("separator","true"):"open"!==t.family&&"close"!==t.family||r.setAttribute("stretchy","false");return r}});var Zr={mi:"italic",mn:"normal",mtext:"normal"};jt({type:"mathord",htmlBuilder:function(t,e){return Dt.makeOrd(t,e,"mathord")},mathmlBuilder:function(t,e){var r=new ue.MathNode("mi",[pe(t.text,t.mode,e)]),a=fe(t,e)||"italic";return a!==Zr[r.type]&&r.setAttribute("mathvariant",a),r}}),jt({type:"textord",htmlBuilder:function(t,e){return Dt.makeOrd(t,e,"textord")},mathmlBuilder:function(t,e){var r,a=pe(t.text,t.mode,e),n=fe(t,e)||"normal";return r="text"===t.mode?new ue.MathNode("mtext",[a]):/[0-9]/.test(t.text)?new ue.MathNode("mn",[a]):"\\prime"===t.text?new ue.MathNode("mo",[a]):new ue.MathNode("mi",[a]),n!==Zr[r.type]&&r.setAttribute("mathvariant",n),r}});var Kr={"\\nobreak":"nobreak","\\allowbreak":"allowbreak"},Jr={" ":{},"\\ ":{},"~":{className:"nobreak"},"\\space":{},"\\nobreakspace":{className:"nobreak"}};jt({type:"spacing",htmlBuilder:function(t,e){if(Jr.hasOwnProperty(t.text)){var r=Jr[t.text].className||"";if("text"===t.mode){var a=Dt.makeOrd(t,e,"textord");return a.classes.push(r),a}return Dt.makeSpan(["mspace",r],[Dt.mathsym(t.text,t.mode,e)],e)}if(Kr.hasOwnProperty(t.text))return Dt.makeSpan(["mspace",Kr[t.text]],[],e);throw new o('Unknown type of space "'+t.text+'"')},mathmlBuilder:function(t,e){if(!Jr.hasOwnProperty(t.text)){if(Kr.hasOwnProperty(t.text))return new ue.MathNode("mspace");throw new o('Unknown type of space "'+t.text+'"')}return new ue.MathNode("mtext",[new ue.TextNode("\xa0")])}});var Qr=function(){var t=new ue.MathNode("mtd",[]);return t.setAttribute("width","50%"),t};jt({type:"tag",mathmlBuilder:function(t,e){var r=new ue.MathNode("mtable",[new ue.MathNode("mtr",[Qr(),new ue.MathNode("mtd",[xe(t.body,e)]),Qr(),new ue.MathNode("mtd",[xe(t.tag,e)])])]);return r.setAttribute("width","100%"),r}});var ta={"\\text":void 0,"\\textrm":"textrm","\\textsf":"textsf","\\texttt":"texttt","\\textnormal":"textrm"},ea={"\\textbf":"textbf","\\textmd":"textmd"},ra={"\\textit":"textit","\\textup":"textup"},aa=function(t,e){var r=t.font;return r?ta[r]?e.withTextFontFamily(ta[r]):ea[r]?e.withTextFontWeight(ea[r]):e.withTextFontShape(ra[r]):e};_t({type:"text",names:["\\text","\\textrm","\\textsf","\\texttt","\\textnormal","\\textbf","\\textmd","\\textit","\\textup"],props:{numArgs:1,argTypes:["text"],greediness:2,allowedInText:!0},handler:function(t,e){var r=t.parser,a=t.funcName,n=e[0];return{type:"text",mode:r.mode,body:$t(n),font:a}},htmlBuilder:function(t,e){var r=aa(t,e),a=ee(t.body,r,!0);return Dt.makeSpan(["mord","text"],Dt.tryCombineChars(a),r)},mathmlBuilder:function(t,e){var r=aa(t,e);return xe(t.body,r)}}),_t({type:"underline",names:["\\underline"],props:{numArgs:1,allowedInText:!0},handler:function(t,e){return{type:"underline",mode:t.parser.mode,body:e[0]}},htmlBuilder:function(t,e){var r=oe(t.body,e),a=Dt.makeLineSpan("underline-line",e),n=e.fontMetrics().defaultRuleThickness,i=Dt.makeVList({positionType:"top",positionData:r.height,children:[{type:"kern",size:n},{type:"elem",elem:a},{type:"kern",size:3*n},{type:"elem",elem:r}]},e);return Dt.makeSpan(["mord","underline"],[i],e)},mathmlBuilder:function(t,e){var r=new ue.MathNode("mo",[new ue.TextNode("\u203e")]);r.setAttribute("stretchy","true");var a=new ue.MathNode("munder",[ve(t.body,e),r]);return a.setAttribute("accentunder","true"),a}}),_t({type:"verb",names:["\\verb"],props:{numArgs:0,allowedInText:!0},handler:function(t,e,r){throw new o("\\verb ended by end of line instead of matching delimiter")},htmlBuilder:function(t,e){for(var r=na(t),a=[],n=e.havingStyle(e.style.text()),i=0;i<r.length;i++){var o=r[i];"~"===o&&(o="\\textasciitilde"),a.push(Dt.makeSymbol(o,"Typewriter-Regular",t.mode,n,["mord","texttt"]))}return Dt.makeSpan(["mord","text"].concat(n.sizingClasses(e)),Dt.tryCombineChars(a),n)},mathmlBuilder:function(t,e){var r=new ue.TextNode(na(t)),a=new ue.MathNode("mtext",[r]);return a.setAttribute("mathvariant","monospace"),a}});var na=function(t){return t.body.replace(/ /g,t.star?"\u2423":"\xa0")},ia=Yt,oa=new RegExp("^(\\\\[a-zA-Z@]+)[ \r\n\t]*$"),sa=new RegExp("[\u0300-\u036f]+$"),la="([ \r\n\t]+)|([!-\\[\\]-\u2027\u202a-\ud7ff\uf900-\uffff][\u0300-\u036f]*|[\ud800-\udbff][\udc00-\udfff][\u0300-\u036f]*|\\\\verb\\*([^]).*?\\3|\\\\verb([^*a-zA-Z]).*?\\4|\\\\operatorname\\*|\\\\[a-zA-Z@]+[ \r\n\t]*|\\\\[^\ud800-\udfff])",ha=function(){function t(t,e){this.input=void 0,this.settings=void 0,this.tokenRegex=void 0,this.catcodes=void 0,this.input=t,this.settings=e,this.tokenRegex=new RegExp(la,"g"),this.catcodes={"%":14}}var e=t.prototype;return e.setCatcode=function(t,e){this.catcodes[t]=e},e.lex=function(){var t=this.input,e=this.tokenRegex.lastIndex;if(e===t.length)return new n("EOF",new a(this,e,e));var r=this.tokenRegex.exec(t);if(null===r||r.index!==e)throw new o("Unexpected character: '"+t[e]+"'",new n(t[e],new a(this,e,e+1)));var i=r[2]||" ";if(14===this.catcodes[i]){var s=t.indexOf("\n",this.tokenRegex.lastIndex);return-1===s?(this.tokenRegex.lastIndex=t.length,this.settings.reportNonstrict("commentAtEnd","% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)")):this.tokenRegex.lastIndex=s+1,this.lex()}var l=i.match(oa);return l&&(i=l[1]),new n(i,new a(this,e,this.tokenRegex.lastIndex))},t}(),ma=function(){function t(t,e){void 0===t&&(t={}),void 0===e&&(e={}),this.current=void 0,this.builtins=void 0,this.undefStack=void 0,this.current=e,this.builtins=t,this.undefStack=[]}var e=t.prototype;return e.beginGroup=function(){this.undefStack.push({})},e.endGroup=function(){if(0===this.undefStack.length)throw new o("Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug");var t=this.undefStack.pop();for(var e in t)t.hasOwnProperty(e)&&(void 0===t[e]?delete this.current[e]:this.current[e]=t[e])},e.has=function(t){return this.current.hasOwnProperty(t)||this.builtins.hasOwnProperty(t)},e.get=function(t){return this.current.hasOwnProperty(t)?this.current[t]:this.builtins[t]},e.set=function(t,e,r){if(void 0===r&&(r=!1),r){for(var a=0;a<this.undefStack.length;a++)delete this.undefStack[a][t];this.undefStack.length>0&&(this.undefStack[this.undefStack.length-1][t]=e)}else{var n=this.undefStack[this.undefStack.length-1];n&&!n.hasOwnProperty(t)&&(n[t]=this.current[t])}this.current[t]=e},t}(),ca={},ua=ca;function pa(t,e){ca[t]=e}pa("\\noexpand",function(t){var e=t.popToken();return t.isExpandable(e.text)&&(e.noexpand=!0,e.treatAsRelax=!0),{tokens:[e],numArgs:0}}),pa("\\expandafter",function(t){var e=t.popToken();return t.expandOnce(!0),{tokens:[e],numArgs:0}}),pa("\\@firstoftwo",function(t){return{tokens:t.consumeArgs(2)[0],numArgs:0}}),pa("\\@secondoftwo",function(t){return{tokens:t.consumeArgs(2)[1],numArgs:0}}),pa("\\@ifnextchar",function(t){var e=t.consumeArgs(3);t.consumeSpaces();var r=t.future();return 1===e[0].length&&e[0][0].text===r.text?{tokens:e[1],numArgs:0}:{tokens:e[2],numArgs:0}}),pa("\\@ifstar","\\@ifnextchar *{\\@firstoftwo{#1}}"),pa("\\TextOrMath",function(t){var e=t.consumeArgs(2);return"text"===t.mode?{tokens:e[0],numArgs:0}:{tokens:e[1],numArgs:0}});var da={0:0,1:1,2:2,3:3,4:4,5:5,6:6,7:7,8:8,9:9,a:10,A:10,b:11,B:11,c:12,C:12,d:13,D:13,e:14,E:14,f:15,F:15};pa("\\char",function(t){var e,r=t.popToken(),a="";if("'"===r.text)e=8,r=t.popToken();else if('"'===r.text)e=16,r=t.popToken();else if("`"===r.text)if("\\"===(r=t.popToken()).text[0])a=r.text.charCodeAt(1);else{if("EOF"===r.text)throw new o("\\char` missing argument");a=r.text.charCodeAt(0)}else e=10;if(e){if(null==(a=da[r.text])||a>=e)throw new o("Invalid base-"+e+" digit "+r.text);for(var n;null!=(n=da[t.future().text])&&n<e;)a*=e,a+=n,t.popToken()}return"\\@char{"+a+"}"});var fa=function(t,e,r){var a=t.consumeArgs(1)[0];if(1!==a.length)throw new o("\\newcommand's first argument must be a macro name");var n=a[0].text,i=t.isDefined(n);if(i&&!e)throw new o("\\newcommand{"+n+"} attempting to redefine "+n+"; use \\renewcommand");if(!i&&!r)throw new o("\\renewcommand{"+n+"} when command "+n+" does not yet exist; use \\newcommand");var s=0;if(1===(a=t.consumeArgs(1)[0]).length&&"["===a[0].text){for(var l="",h=t.expandNextToken();"]"!==h.text&&"EOF"!==h.text;)l+=h.text,h=t.expandNextToken();if(!l.match(/^\s*[0-9]+\s*$/))throw new o("Invalid number of arguments: "+l);s=parseInt(l),a=t.consumeArgs(1)[0]}return t.macros.set(n,{tokens:a,numArgs:s}),""};pa("\\newcommand",function(t){return fa(t,!1,!0)}),pa("\\renewcommand",function(t){return fa(t,!0,!1)}),pa("\\providecommand",function(t){return fa(t,!0,!0)}),pa("\\message",function(t){var e=t.consumeArgs(1)[0];return console.log(e.reverse().map(function(t){return t.text}).join("")),""}),pa("\\errmessage",function(t){var e=t.consumeArgs(1)[0];return console.error(e.reverse().map(function(t){return t.text}).join("")),""}),pa("\\show",function(t){var e=t.popToken(),r=e.text;return console.log(e,t.macros.get(r),ia[r],j.math[r],j.text[r]),""}),pa("\\bgroup","{"),pa("\\egroup","}"),pa("\\lq","`"),pa("\\rq","'"),pa("\\aa","\\r a"),pa("\\AA","\\r A"),pa("\\textcopyright","\\html@mathml{\\textcircled{c}}{\\char`\xa9}"),pa("\\copyright","\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}"),pa("\\textregistered","\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xae}"),pa("\u212c","\\mathscr{B}"),pa("\u2130","\\mathscr{E}"),pa("\u2131","\\mathscr{F}"),pa("\u210b","\\mathscr{H}"),pa("\u2110","\\mathscr{I}"),pa("\u2112","\\mathscr{L}"),pa("\u2133","\\mathscr{M}"),pa("\u211b","\\mathscr{R}"),pa("\u212d","\\mathfrak{C}"),pa("\u210c","\\mathfrak{H}"),pa("\u2128","\\mathfrak{Z}"),pa("\\Bbbk","\\Bbb{k}"),pa("\xb7","\\cdotp"),pa("\\llap","\\mathllap{\\textrm{#1}}"),pa("\\rlap","\\mathrlap{\\textrm{#1}}"),pa("\\clap","\\mathclap{\\textrm{#1}}"),pa("\\not",'\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'),pa("\\neq","\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}"),pa("\\ne","\\neq"),pa("\u2260","\\neq"),pa("\\notin","\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}"),pa("\u2209","\\notin"),pa("\u2258","\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}"),pa("\u2259","\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}"),pa("\u225a","\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225a}}"),pa("\u225b","\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225b}}"),pa("\u225d","\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225d}}"),pa("\u225e","\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225e}}"),pa("\u225f","\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225f}}"),pa("\u27c2","\\perp"),pa("\u203c","\\mathclose{!\\mkern-0.8mu!}"),pa("\u220c","\\notni"),pa("\u231c","\\ulcorner"),pa("\u231d","\\urcorner"),pa("\u231e","\\llcorner"),pa("\u231f","\\lrcorner"),pa("\xa9","\\copyright"),pa("\xae","\\textregistered"),pa("\ufe0f","\\textregistered"),pa("\\ulcorner",'\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'),pa("\\urcorner",'\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'),pa("\\llcorner",'\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'),pa("\\lrcorner",'\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'),pa("\\vdots","\\mathord{\\varvdots\\rule{0pt}{15pt}}"),pa("\u22ee","\\vdots"),pa("\\varGamma","\\mathit{\\Gamma}"),pa("\\varDelta","\\mathit{\\Delta}"),pa("\\varTheta","\\mathit{\\Theta}"),pa("\\varLambda","\\mathit{\\Lambda}"),pa("\\varXi","\\mathit{\\Xi}"),pa("\\varPi","\\mathit{\\Pi}"),pa("\\varSigma","\\mathit{\\Sigma}"),pa("\\varUpsilon","\\mathit{\\Upsilon}"),pa("\\varPhi","\\mathit{\\Phi}"),pa("\\varPsi","\\mathit{\\Psi}"),pa("\\varOmega","\\mathit{\\Omega}"),pa("\\substack","\\begin{subarray}{c}#1\\end{subarray}"),pa("\\colon","\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu"),pa("\\boxed","\\fbox{$\\displaystyle{#1}$}"),pa("\\iff","\\DOTSB\\;\\Longleftrightarrow\\;"),pa("\\implies","\\DOTSB\\;\\Longrightarrow\\;"),pa("\\impliedby","\\DOTSB\\;\\Longleftarrow\\;");var ga={",":"\\dotsc","\\not":"\\dotsb","+":"\\dotsb","=":"\\dotsb","<":"\\dotsb",">":"\\dotsb","-":"\\dotsb","*":"\\dotsb",":":"\\dotsb","\\DOTSB":"\\dotsb","\\coprod":"\\dotsb","\\bigvee":"\\dotsb","\\bigwedge":"\\dotsb","\\biguplus":"\\dotsb","\\bigcap":"\\dotsb","\\bigcup":"\\dotsb","\\prod":"\\dotsb","\\sum":"\\dotsb","\\bigotimes":"\\dotsb","\\bigoplus":"\\dotsb","\\bigodot":"\\dotsb","\\bigsqcup":"\\dotsb","\\And":"\\dotsb","\\longrightarrow":"\\dotsb","\\Longrightarrow":"\\dotsb","\\longleftarrow":"\\dotsb","\\Longleftarrow":"\\dotsb","\\longleftrightarrow":"\\dotsb","\\Longleftrightarrow":"\\dotsb","\\mapsto":"\\dotsb","\\longmapsto":"\\dotsb","\\hookrightarrow":"\\dotsb","\\doteq":"\\dotsb","\\mathbin":"\\dotsb","\\mathrel":"\\dotsb","\\relbar":"\\dotsb","\\Relbar":"\\dotsb","\\xrightarrow":"\\dotsb","\\xleftarrow":"\\dotsb","\\DOTSI":"\\dotsi","\\int":"\\dotsi","\\oint":"\\dotsi","\\iint":"\\dotsi","\\iiint":"\\dotsi","\\iiiint":"\\dotsi","\\idotsint":"\\dotsi","\\DOTSX":"\\dotsx"};pa("\\dots",function(t){var e="\\dotso",r=t.expandAfterFuture().text;return r in ga?e=ga[r]:"\\not"===r.substr(0,4)?e="\\dotsb":r in j.math&&c.contains(["bin","rel"],j.math[r].group)&&(e="\\dotsb"),e});var xa={")":!0,"]":!0,"\\rbrack":!0,"\\}":!0,"\\rbrace":!0,"\\rangle":!0,"\\rceil":!0,"\\rfloor":!0,"\\rgroup":!0,"\\rmoustache":!0,"\\right":!0,"\\bigr":!0,"\\biggr":!0,"\\Bigr":!0,"\\Biggr":!0,$:!0,";":!0,".":!0,",":!0};pa("\\dotso",function(t){return t.future().text in xa?"\\ldots\\,":"\\ldots"}),pa("\\dotsc",function(t){var e=t.future().text;return e in xa&&","!==e?"\\ldots\\,":"\\ldots"}),pa("\\cdots",function(t){return t.future().text in xa?"\\@cdots\\,":"\\@cdots"}),pa("\\dotsb","\\cdots"),pa("\\dotsm","\\cdots"),pa("\\dotsi","\\!\\cdots"),pa("\\dotsx","\\ldots\\,"),pa("\\DOTSI","\\relax"),pa("\\DOTSB","\\relax"),pa("\\DOTSX","\\relax"),pa("\\tmspace","\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax"),pa("\\,","\\tmspace+{3mu}{.1667em}"),pa("\\thinspace","\\,"),pa("\\>","\\mskip{4mu}"),pa("\\:","\\tmspace+{4mu}{.2222em}"),pa("\\medspace","\\:"),pa("\\;","\\tmspace+{5mu}{.2777em}"),pa("\\thickspace","\\;"),pa("\\!","\\tmspace-{3mu}{.1667em}"),pa("\\negthinspace","\\!"),pa("\\negmedspace","\\tmspace-{4mu}{.2222em}"),pa("\\negthickspace","\\tmspace-{5mu}{.277em}"),pa("\\enspace","\\kern.5em "),pa("\\enskip","\\hskip.5em\\relax"),pa("\\quad","\\hskip1em\\relax"),pa("\\qquad","\\hskip2em\\relax"),pa("\\tag","\\@ifstar\\tag@literal\\tag@paren"),pa("\\tag@paren","\\tag@literal{({#1})}"),pa("\\tag@literal",function(t){if(t.macros.get("\\df@tag"))throw new o("Multiple \\tag");return"\\gdef\\df@tag{\\text{#1}}"}),pa("\\bmod","\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}"),pa("\\pod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)"),pa("\\pmod","\\pod{{\\rm mod}\\mkern6mu#1}"),pa("\\mod","\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1"),pa("\\pmb","\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}"),pa("\\\\","\\newline"),pa("\\TeX","\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}");var va=F["Main-Regular"]["T".charCodeAt(0)][1]-.7*F["Main-Regular"]["A".charCodeAt(0)][1]+"em";pa("\\LaTeX","\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{"+va+"}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}"),pa("\\KaTeX","\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{"+va+"}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}"),pa("\\hspace","\\@ifstar\\@hspacer\\@hspace"),pa("\\@hspace","\\hskip #1\\relax"),pa("\\@hspacer","\\rule{0pt}{0pt}\\hskip #1\\relax"),pa("\\ordinarycolon",":"),pa("\\vcentcolon","\\mathrel{\\mathop\\ordinarycolon}"),pa("\\dblcolon",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'),pa("\\coloneqq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'),pa("\\Coloneqq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'),pa("\\coloneq",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'),pa("\\Coloneq",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'),pa("\\eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'),pa("\\Eqqcolon",'\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'),pa("\\eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'),pa("\\Eqcolon",'\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'),pa("\\colonapprox",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'),pa("\\Colonapprox",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'),pa("\\colonsim",'\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'),pa("\\Colonsim",'\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'),pa("\u2237","\\dblcolon"),pa("\u2239","\\eqcolon"),pa("\u2254","\\coloneqq"),pa("\u2255","\\eqqcolon"),pa("\u2a74","\\Coloneqq"),pa("\\ratio","\\vcentcolon"),pa("\\coloncolon","\\dblcolon"),pa("\\colonequals","\\coloneqq"),pa("\\coloncolonequals","\\Coloneqq"),pa("\\equalscolon","\\eqqcolon"),pa("\\equalscoloncolon","\\Eqqcolon"),pa("\\colonminus","\\coloneq"),pa("\\coloncolonminus","\\Coloneq"),pa("\\minuscolon","\\eqcolon"),pa("\\minuscoloncolon","\\Eqcolon"),pa("\\coloncolonapprox","\\Colonapprox"),pa("\\coloncolonsim","\\Colonsim"),pa("\\simcolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),pa("\\simcoloncolon","\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}"),pa("\\approxcolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}"),pa("\\approxcoloncolon","\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}"),pa("\\notni","\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}"),pa("\\limsup","\\DOTSB\\operatorname*{lim\\,sup}"),pa("\\liminf","\\DOTSB\\operatorname*{lim\\,inf}"),pa("\\gvertneqq","\\html@mathml{\\@gvertneqq}{\u2269}"),pa("\\lvertneqq","\\html@mathml{\\@lvertneqq}{\u2268}"),pa("\\ngeqq","\\html@mathml{\\@ngeqq}{\u2271}"),pa("\\ngeqslant","\\html@mathml{\\@ngeqslant}{\u2271}"),pa("\\nleqq","\\html@mathml{\\@nleqq}{\u2270}"),pa("\\nleqslant","\\html@mathml{\\@nleqslant}{\u2270}"),pa("\\nshortmid","\\html@mathml{\\@nshortmid}{\u2224}"),pa("\\nshortparallel","\\html@mathml{\\@nshortparallel}{\u2226}"),pa("\\nsubseteqq","\\html@mathml{\\@nsubseteqq}{\u2288}"),pa("\\nsupseteqq","\\html@mathml{\\@nsupseteqq}{\u2289}"),pa("\\varsubsetneq","\\html@mathml{\\@varsubsetneq}{\u228a}"),pa("\\varsubsetneqq","\\html@mathml{\\@varsubsetneqq}{\u2acb}"),pa("\\varsupsetneq","\\html@mathml{\\@varsupsetneq}{\u228b}"),pa("\\varsupsetneqq","\\html@mathml{\\@varsupsetneqq}{\u2acc}"),pa("\\imath","\\html@mathml{\\@imath}{\u0131}"),pa("\\jmath","\\html@mathml{\\@jmath}{\u0237}"),pa("\\llbracket","\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}"),pa("\\rrbracket","\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}"),pa("\u27e6","\\llbracket"),pa("\u27e7","\\rrbracket"),pa("\\lBrace","\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}"),pa("\\rBrace","\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}"),pa("\u2983","\\lBrace"),pa("\u2984","\\rBrace"),pa("\\minuso","\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}"),pa("\u29b5","\\minuso"),pa("\\darr","\\downarrow"),pa("\\dArr","\\Downarrow"),pa("\\Darr","\\Downarrow"),pa("\\lang","\\langle"),pa("\\rang","\\rangle"),pa("\\uarr","\\uparrow"),pa("\\uArr","\\Uparrow"),pa("\\Uarr","\\Uparrow"),pa("\\N","\\mathbb{N}"),pa("\\R","\\mathbb{R}"),pa("\\Z","\\mathbb{Z}"),pa("\\alef","\\aleph"),pa("\\alefsym","\\aleph"),pa("\\Alpha","\\mathrm{A}"),pa("\\Beta","\\mathrm{B}"),pa("\\bull","\\bullet"),pa("\\Chi","\\mathrm{X}"),pa("\\clubs","\\clubsuit"),pa("\\cnums","\\mathbb{C}"),pa("\\Complex","\\mathbb{C}"),pa("\\Dagger","\\ddagger"),pa("\\diamonds","\\diamondsuit"),pa("\\empty","\\emptyset"),pa("\\Epsilon","\\mathrm{E}"),pa("\\Eta","\\mathrm{H}"),pa("\\exist","\\exists"),pa("\\harr","\\leftrightarrow"),pa("\\hArr","\\Leftrightarrow"),pa("\\Harr","\\Leftrightarrow"),pa("\\hearts","\\heartsuit"),pa("\\image","\\Im"),pa("\\infin","\\infty"),pa("\\Iota","\\mathrm{I}"),pa("\\isin","\\in"),pa("\\Kappa","\\mathrm{K}"),pa("\\larr","\\leftarrow"),pa("\\lArr","\\Leftarrow"),pa("\\Larr","\\Leftarrow"),pa("\\lrarr","\\leftrightarrow"),pa("\\lrArr","\\Leftrightarrow"),pa("\\Lrarr","\\Leftrightarrow"),pa("\\Mu","\\mathrm{M}"),pa("\\natnums","\\mathbb{N}"),pa("\\Nu","\\mathrm{N}"),pa("\\Omicron","\\mathrm{O}"),pa("\\plusmn","\\pm"),pa("\\rarr","\\rightarrow"),pa("\\rArr","\\Rightarrow"),pa("\\Rarr","\\Rightarrow"),pa("\\real","\\Re"),pa("\\reals","\\mathbb{R}"),pa("\\Reals","\\mathbb{R}"),pa("\\Rho","\\mathrm{P}"),pa("\\sdot","\\cdot"),pa("\\sect","\\S"),pa("\\spades","\\spadesuit"),pa("\\sub","\\subset"),pa("\\sube","\\subseteq"),pa("\\supe","\\supseteq"),pa("\\Tau","\\mathrm{T}"),pa("\\thetasym","\\vartheta"),pa("\\weierp","\\wp"),pa("\\Zeta","\\mathrm{Z}"),pa("\\argmin","\\DOTSB\\operatorname*{arg\\,min}"),pa("\\argmax","\\DOTSB\\operatorname*{arg\\,max}"),pa("\\plim","\\DOTSB\\mathop{\\operatorname{plim}}\\limits"),pa("\\bra","\\mathinner{\\langle{#1}|}"),pa("\\ket","\\mathinner{|{#1}\\rangle}"),pa("\\braket","\\mathinner{\\langle{#1}\\rangle}"),pa("\\Bra","\\left\\langle#1\\right|"),pa("\\Ket","\\left|#1\\right\\rangle"),pa("\\blue","\\textcolor{##6495ed}{#1}"),pa("\\orange","\\textcolor{##ffa500}{#1}"),pa("\\pink","\\textcolor{##ff00af}{#1}"),pa("\\red","\\textcolor{##df0030}{#1}"),pa("\\green","\\textcolor{##28ae7b}{#1}"),pa("\\gray","\\textcolor{gray}{#1}"),pa("\\purple","\\textcolor{##9d38bd}{#1}"),pa("\\blueA","\\textcolor{##ccfaff}{#1}"),pa("\\blueB","\\textcolor{##80f6ff}{#1}"),pa("\\blueC","\\textcolor{##63d9ea}{#1}"),pa("\\blueD","\\textcolor{##11accd}{#1}"),pa("\\blueE","\\textcolor{##0c7f99}{#1}"),pa("\\tealA","\\textcolor{##94fff5}{#1}"),pa("\\tealB","\\textcolor{##26edd5}{#1}"),pa("\\tealC","\\textcolor{##01d1c1}{#1}"),pa("\\tealD","\\textcolor{##01a995}{#1}"),pa("\\tealE","\\textcolor{##208170}{#1}"),pa("\\greenA","\\textcolor{##b6ffb0}{#1}"),pa("\\greenB","\\textcolor{##8af281}{#1}"),pa("\\greenC","\\textcolor{##74cf70}{#1}"),pa("\\greenD","\\textcolor{##1fab54}{#1}"),pa("\\greenE","\\textcolor{##0d923f}{#1}"),pa("\\goldA","\\textcolor{##ffd0a9}{#1}"),pa("\\goldB","\\textcolor{##ffbb71}{#1}"),pa("\\goldC","\\textcolor{##ff9c39}{#1}"),pa("\\goldD","\\textcolor{##e07d10}{#1}"),pa("\\goldE","\\textcolor{##a75a05}{#1}"),pa("\\redA","\\textcolor{##fca9a9}{#1}"),pa("\\redB","\\textcolor{##ff8482}{#1}"),pa("\\redC","\\textcolor{##f9685d}{#1}"),pa("\\redD","\\textcolor{##e84d39}{#1}"),pa("\\redE","\\textcolor{##bc2612}{#1}"),pa("\\maroonA","\\textcolor{##ffbde0}{#1}"),pa("\\maroonB","\\textcolor{##ff92c6}{#1}"),pa("\\maroonC","\\textcolor{##ed5fa6}{#1}"),pa("\\maroonD","\\textcolor{##ca337c}{#1}"),pa("\\maroonE","\\textcolor{##9e034e}{#1}"),pa("\\purpleA","\\textcolor{##ddd7ff}{#1}"),pa("\\purpleB","\\textcolor{##c6b9fc}{#1}"),pa("\\purpleC","\\textcolor{##aa87ff}{#1}"),pa("\\purpleD","\\textcolor{##7854ab}{#1}"),pa("\\purpleE","\\textcolor{##543b78}{#1}"),pa("\\mintA","\\textcolor{##f5f9e8}{#1}"),pa("\\mintB","\\textcolor{##edf2df}{#1}"),pa("\\mintC","\\textcolor{##e0e5cc}{#1}"),pa("\\grayA","\\textcolor{##f6f7f7}{#1}"),pa("\\grayB","\\textcolor{##f0f1f2}{#1}"),pa("\\grayC","\\textcolor{##e3e5e6}{#1}"),pa("\\grayD","\\textcolor{##d6d8da}{#1}"),pa("\\grayE","\\textcolor{##babec2}{#1}"),pa("\\grayF","\\textcolor{##888d93}{#1}"),pa("\\grayG","\\textcolor{##626569}{#1}"),pa("\\grayH","\\textcolor{##3b3e40}{#1}"),pa("\\grayI","\\textcolor{##21242c}{#1}"),pa("\\kaBlue","\\textcolor{##314453}{#1}"),pa("\\kaGreen","\\textcolor{##71B307}{#1}");var ba={"\\relax":!0,"^":!0,_:!0,"\\limits":!0,"\\nolimits":!0},ya=function(){function t(t,e,r){this.settings=void 0,this.expansionCount=void 0,this.lexer=void 0,this.macros=void 0,this.stack=void 0,this.mode=void 0,this.settings=e,this.expansionCount=0,this.feed(t),this.macros=new ma(ua,e.macros),this.mode=r,this.stack=[]}var e=t.prototype;return e.feed=function(t){this.lexer=new ha(t,this.settings)},e.switchMode=function(t){this.mode=t},e.beginGroup=function(){this.macros.beginGroup()},e.endGroup=function(){this.macros.endGroup()},e.future=function(){return 0===this.stack.length&&this.pushToken(this.lexer.lex()),this.stack[this.stack.length-1]},e.popToken=function(){return this.future(),this.stack.pop()},e.pushToken=function(t){this.stack.push(t)},e.pushTokens=function(t){var e;(e=this.stack).push.apply(e,t)},e.consumeSpaces=function(){for(;;){if(" "!==this.future().text)break;this.stack.pop()}},e.consumeArgs=function(t){for(var e=[],r=0;r<t;++r){this.consumeSpaces();var a=this.popToken();if("{"===a.text){for(var n=[],i=1;0!==i;){var s=this.popToken();if(n.push(s),"{"===s.text)++i;else if("}"===s.text)--i;else if("EOF"===s.text)throw new o("End of input in macro argument",a)}n.pop(),n.reverse(),e[r]=n}else{if("EOF"===a.text)throw new o("End of input expecting macro argument");e[r]=[a]}}return e},e.expandOnce=function(t){var e=this.popToken(),r=e.text,a=e.noexpand?null:this._getExpansion(r);if(null==a||t&&a.unexpandable){if(t&&null==a&&"\\"===r[0]&&!this.isDefined(r))throw new o("Undefined control sequence: "+r);return this.pushToken(e),e}if(this.expansionCount++,this.expansionCount>this.settings.maxExpand)throw new o("Too many expansions: infinite loop or need to increase maxExpand setting");var n=a.tokens;if(a.numArgs)for(var i=this.consumeArgs(a.numArgs),s=(n=n.slice()).length-1;s>=0;--s){var l=n[s];if("#"===l.text){if(0===s)throw new o("Incomplete placeholder at end of macro body",l);if("#"===(l=n[--s]).text)n.splice(s+1,1);else{if(!/^[1-9]$/.test(l.text))throw new o("Not a valid argument number",l);var h;(h=n).splice.apply(h,[s,2].concat(i[+l.text-1]))}}}return this.pushTokens(n),n},e.expandAfterFuture=function(){return this.expandOnce(),this.future()},e.expandNextToken=function(){for(;;){var t=this.expandOnce();if(t instanceof n){if("\\relax"!==t.text&&!t.treatAsRelax)return this.stack.pop();this.stack.pop()}}throw new Error},e.expandMacro=function(t){return this.macros.has(t)?this.expandTokens([new n(t)]):void 0},e.expandTokens=function(t){var e=[],r=this.stack.length;for(this.pushTokens(t);this.stack.length>r;){var a=this.expandOnce(!0);a instanceof n&&(a.treatAsRelax&&(a.noexpand=!1,a.treatAsRelax=!1),e.push(this.stack.pop()))}return e},e.expandMacroAsText=function(t){var e=this.expandMacro(t);return e?e.map(function(t){return t.text}).join(""):e},e._getExpansion=function(t){var e=this.macros.get(t);if(null==e)return e;var r="function"==typeof e?e(this):e;if("string"==typeof r){var a=0;if(-1!==r.indexOf("#"))for(var n=r.replace(/##/g,"");-1!==n.indexOf("#"+(a+1));)++a;for(var i=new ha(r,this.settings),o=[],s=i.lex();"EOF"!==s.text;)o.push(s),s=i.lex();return o.reverse(),{tokens:o,numArgs:a}}return r},e.isDefined=function(t){return this.macros.has(t)||ia.hasOwnProperty(t)||j.math.hasOwnProperty(t)||j.text.hasOwnProperty(t)||ba.hasOwnProperty(t)},e.isExpandable=function(t){var e=this.macros.get(t);return null!=e?"string"==typeof e||"function"==typeof e||!e.unexpandable:ia.hasOwnProperty(t)},t}(),wa={"\u0301":{text:"\\'",math:"\\acute"},"\u0300":{text:"\\`",math:"\\grave"},"\u0308":{text:'\\"',math:"\\ddot"},"\u0303":{text:"\\~",math:"\\tilde"},"\u0304":{text:"\\=",math:"\\bar"},"\u0306":{text:"\\u",math:"\\breve"},"\u030c":{text:"\\v",math:"\\check"},"\u0302":{text:"\\^",math:"\\hat"},"\u0307":{text:"\\.",math:"\\dot"},"\u030a":{text:"\\r",math:"\\mathring"},"\u030b":{text:"\\H"}},ka={"\xe1":"a\u0301","\xe0":"a\u0300","\xe4":"a\u0308","\u01df":"a\u0308\u0304","\xe3":"a\u0303","\u0101":"a\u0304","\u0103":"a\u0306","\u1eaf":"a\u0306\u0301","\u1eb1":"a\u0306\u0300","\u1eb5":"a\u0306\u0303","\u01ce":"a\u030c","\xe2":"a\u0302","\u1ea5":"a\u0302\u0301","\u1ea7":"a\u0302\u0300","\u1eab":"a\u0302\u0303","\u0227":"a\u0307","\u01e1":"a\u0307\u0304","\xe5":"a\u030a","\u01fb":"a\u030a\u0301","\u1e03":"b\u0307","\u0107":"c\u0301","\u010d":"c\u030c","\u0109":"c\u0302","\u010b":"c\u0307","\u010f":"d\u030c","\u1e0b":"d\u0307","\xe9":"e\u0301","\xe8":"e\u0300","\xeb":"e\u0308","\u1ebd":"e\u0303","\u0113":"e\u0304","\u1e17":"e\u0304\u0301","\u1e15":"e\u0304\u0300","\u0115":"e\u0306","\u011b":"e\u030c","\xea":"e\u0302","\u1ebf":"e\u0302\u0301","\u1ec1":"e\u0302\u0300","\u1ec5":"e\u0302\u0303","\u0117":"e\u0307","\u1e1f":"f\u0307","\u01f5":"g\u0301","\u1e21":"g\u0304","\u011f":"g\u0306","\u01e7":"g\u030c","\u011d":"g\u0302","\u0121":"g\u0307","\u1e27":"h\u0308","\u021f":"h\u030c","\u0125":"h\u0302","\u1e23":"h\u0307","\xed":"i\u0301","\xec":"i\u0300","\xef":"i\u0308","\u1e2f":"i\u0308\u0301","\u0129":"i\u0303","\u012b":"i\u0304","\u012d":"i\u0306","\u01d0":"i\u030c","\xee":"i\u0302","\u01f0":"j\u030c","\u0135":"j\u0302","\u1e31":"k\u0301","\u01e9":"k\u030c","\u013a":"l\u0301","\u013e":"l\u030c","\u1e3f":"m\u0301","\u1e41":"m\u0307","\u0144":"n\u0301","\u01f9":"n\u0300","\xf1":"n\u0303","\u0148":"n\u030c","\u1e45":"n\u0307","\xf3":"o\u0301","\xf2":"o\u0300","\xf6":"o\u0308","\u022b":"o\u0308\u0304","\xf5":"o\u0303","\u1e4d":"o\u0303\u0301","\u1e4f":"o\u0303\u0308","\u022d":"o\u0303\u0304","\u014d":"o\u0304","\u1e53":"o\u0304\u0301","\u1e51":"o\u0304\u0300","\u014f":"o\u0306","\u01d2":"o\u030c","\xf4":"o\u0302","\u1ed1":"o\u0302\u0301","\u1ed3":"o\u0302\u0300","\u1ed7":"o\u0302\u0303","\u022f":"o\u0307","\u0231":"o\u0307\u0304","\u0151":"o\u030b","\u1e55":"p\u0301","\u1e57":"p\u0307","\u0155":"r\u0301","\u0159":"r\u030c","\u1e59":"r\u0307","\u015b":"s\u0301","\u1e65":"s\u0301\u0307","\u0161":"s\u030c","\u1e67":"s\u030c\u0307","\u015d":"s\u0302","\u1e61":"s\u0307","\u1e97":"t\u0308","\u0165":"t\u030c","\u1e6b":"t\u0307","\xfa":"u\u0301","\xf9":"u\u0300","\xfc":"u\u0308","\u01d8":"u\u0308\u0301","\u01dc":"u\u0308\u0300","\u01d6":"u\u0308\u0304","\u01da":"u\u0308\u030c","\u0169":"u\u0303","\u1e79":"u\u0303\u0301","\u016b":"u\u0304","\u1e7b":"u\u0304\u0308","\u016d":"u\u0306","\u01d4":"u\u030c","\xfb":"u\u0302","\u016f":"u\u030a","\u0171":"u\u030b","\u1e7d":"v\u0303","\u1e83":"w\u0301","\u1e81":"w\u0300","\u1e85":"w\u0308","\u0175":"w\u0302","\u1e87":"w\u0307","\u1e98":"w\u030a","\u1e8d":"x\u0308","\u1e8b":"x\u0307","\xfd":"y\u0301","\u1ef3":"y\u0300","\xff":"y\u0308","\u1ef9":"y\u0303","\u0233":"y\u0304","\u0177":"y\u0302","\u1e8f":"y\u0307","\u1e99":"y\u030a","\u017a":"z\u0301","\u017e":"z\u030c","\u1e91":"z\u0302","\u017c":"z\u0307","\xc1":"A\u0301","\xc0":"A\u0300","\xc4":"A\u0308","\u01de":"A\u0308\u0304","\xc3":"A\u0303","\u0100":"A\u0304","\u0102":"A\u0306","\u1eae":"A\u0306\u0301","\u1eb0":"A\u0306\u0300","\u1eb4":"A\u0306\u0303","\u01cd":"A\u030c","\xc2":"A\u0302","\u1ea4":"A\u0302\u0301","\u1ea6":"A\u0302\u0300","\u1eaa":"A\u0302\u0303","\u0226":"A\u0307","\u01e0":"A\u0307\u0304","\xc5":"A\u030a","\u01fa":"A\u030a\u0301","\u1e02":"B\u0307","\u0106":"C\u0301","\u010c":"C\u030c","\u0108":"C\u0302","\u010a":"C\u0307","\u010e":"D\u030c","\u1e0a":"D\u0307","\xc9":"E\u0301","\xc8":"E\u0300","\xcb":"E\u0308","\u1ebc":"E\u0303","\u0112":"E\u0304","\u1e16":"E\u0304\u0301","\u1e14":"E\u0304\u0300","\u0114":"E\u0306","\u011a":"E\u030c","\xca":"E\u0302","\u1ebe":"E\u0302\u0301","\u1ec0":"E\u0302\u0300","\u1ec4":"E\u0302\u0303","\u0116":"E\u0307","\u1e1e":"F\u0307","\u01f4":"G\u0301","\u1e20":"G\u0304","\u011e":"G\u0306","\u01e6":"G\u030c","\u011c":"G\u0302","\u0120":"G\u0307","\u1e26":"H\u0308","\u021e":"H\u030c","\u0124":"H\u0302","\u1e22":"H\u0307","\xcd":"I\u0301","\xcc":"I\u0300","\xcf":"I\u0308","\u1e2e":"I\u0308\u0301","\u0128":"I\u0303","\u012a":"I\u0304","\u012c":"I\u0306","\u01cf":"I\u030c","\xce":"I\u0302","\u0130":"I\u0307","\u0134":"J\u0302","\u1e30":"K\u0301","\u01e8":"K\u030c","\u0139":"L\u0301","\u013d":"L\u030c","\u1e3e":"M\u0301","\u1e40":"M\u0307","\u0143":"N\u0301","\u01f8":"N\u0300","\xd1":"N\u0303","\u0147":"N\u030c","\u1e44":"N\u0307","\xd3":"O\u0301","\xd2":"O\u0300","\xd6":"O\u0308","\u022a":"O\u0308\u0304","\xd5":"O\u0303","\u1e4c":"O\u0303\u0301","\u1e4e":"O\u0303\u0308","\u022c":"O\u0303\u0304","\u014c":"O\u0304","\u1e52":"O\u0304\u0301","\u1e50":"O\u0304\u0300","\u014e":"O\u0306","\u01d1":"O\u030c","\xd4":"O\u0302","\u1ed0":"O\u0302\u0301","\u1ed2":"O\u0302\u0300","\u1ed6":"O\u0302\u0303","\u022e":"O\u0307","\u0230":"O\u0307\u0304","\u0150":"O\u030b","\u1e54":"P\u0301","\u1e56":"P\u0307","\u0154":"R\u0301","\u0158":"R\u030c","\u1e58":"R\u0307","\u015a":"S\u0301","\u1e64":"S\u0301\u0307","\u0160":"S\u030c","\u1e66":"S\u030c\u0307","\u015c":"S\u0302","\u1e60":"S\u0307","\u0164":"T\u030c","\u1e6a":"T\u0307","\xda":"U\u0301","\xd9":"U\u0300","\xdc":"U\u0308","\u01d7":"U\u0308\u0301","\u01db":"U\u0308\u0300","\u01d5":"U\u0308\u0304","\u01d9":"U\u0308\u030c","\u0168":"U\u0303","\u1e78":"U\u0303\u0301","\u016a":"U\u0304","\u1e7a":"U\u0304\u0308","\u016c":"U\u0306","\u01d3":"U\u030c","\xdb":"U\u0302","\u016e":"U\u030a","\u0170":"U\u030b","\u1e7c":"V\u0303","\u1e82":"W\u0301","\u1e80":"W\u0300","\u1e84":"W\u0308","\u0174":"W\u0302","\u1e86":"W\u0307","\u1e8c":"X\u0308","\u1e8a":"X\u0307","\xdd":"Y\u0301","\u1ef2":"Y\u0300","\u0178":"Y\u0308","\u1ef8":"Y\u0303","\u0232":"Y\u0304","\u0176":"Y\u0302","\u1e8e":"Y\u0307","\u0179":"Z\u0301","\u017d":"Z\u030c","\u1e90":"Z\u0302","\u017b":"Z\u0307","\u03ac":"\u03b1\u0301","\u1f70":"\u03b1\u0300","\u1fb1":"\u03b1\u0304","\u1fb0":"\u03b1\u0306","\u03ad":"\u03b5\u0301","\u1f72":"\u03b5\u0300","\u03ae":"\u03b7\u0301","\u1f74":"\u03b7\u0300","\u03af":"\u03b9\u0301","\u1f76":"\u03b9\u0300","\u03ca":"\u03b9\u0308","\u0390":"\u03b9\u0308\u0301","\u1fd2":"\u03b9\u0308\u0300","\u1fd1":"\u03b9\u0304","\u1fd0":"\u03b9\u0306","\u03cc":"\u03bf\u0301","\u1f78":"\u03bf\u0300","\u03cd":"\u03c5\u0301","\u1f7a":"\u03c5\u0300","\u03cb":"\u03c5\u0308","\u03b0":"\u03c5\u0308\u0301","\u1fe2":"\u03c5\u0308\u0300","\u1fe1":"\u03c5\u0304","\u1fe0":"\u03c5\u0306","\u03ce":"\u03c9\u0301","\u1f7c":"\u03c9\u0300","\u038e":"\u03a5\u0301","\u1fea":"\u03a5\u0300","\u03ab":"\u03a5\u0308","\u1fe9":"\u03a5\u0304","\u1fe8":"\u03a5\u0306","\u038f":"\u03a9\u0301","\u1ffa":"\u03a9\u0300"},Sa=function(){function t(t,e){this.mode=void 0,this.gullet=void 0,this.settings=void 0,this.leftrightDepth=void 0,this.nextToken=void 0,this.mode="math",this.gullet=new ya(t,e,this.mode),this.settings=e,this.leftrightDepth=0}var e=t.prototype;return e.expect=function(t,e){if(void 0===e&&(e=!0),this.fetch().text!==t)throw new o("Expected '"+t+"', got '"+this.fetch().text+"'",this.fetch());e&&this.consume()},e.consume=function(){this.nextToken=null},e.fetch=function(){return null==this.nextToken&&(this.nextToken=this.gullet.expandNextToken()),this.nextToken},e.switchMode=function(t){this.mode=t,this.gullet.switchMode(t)},e.parse=function(){this.settings.globalGroup||this.gullet.beginGroup(),this.settings.colorIsTextColor&&this.gullet.macros.set("\\color","\\textcolor");var t=this.parseExpression(!1);return this.expect("EOF"),this.settings.globalGroup||this.gullet.endGroup(),t},e.parseExpression=function(e,r){for(var a=[];;){"math"===this.mode&&this.consumeSpaces();var n=this.fetch();if(-1!==t.endOfExpression.indexOf(n.text))break;if(r&&n.text===r)break;if(e&&ia[n.text]&&ia[n.text].infix)break;var i=this.parseAtom(r);if(!i)break;"internal"!==i.type&&a.push(i)}return"text"===this.mode&&this.formLigatures(a),this.handleInfixNodes(a)},e.handleInfixNodes=function(t){for(var e,r=-1,a=0;a<t.length;a++)if("infix"===t[a].type){if(-1!==r)throw new o("only one infix operator per group",t[a].token);r=a,e=t[a].replaceWith}if(-1!==r&&e){var n,i,s=t.slice(0,r),l=t.slice(r+1);return n=1===s.length&&"ordgroup"===s[0].type?s[0]:{type:"ordgroup",mode:this.mode,body:s},i=1===l.length&&"ordgroup"===l[0].type?l[0]:{type:"ordgroup",mode:this.mode,body:l},["\\\\abovefrac"===e?this.callFunction(e,[n,t[r],i],[]):this.callFunction(e,[n,i],[])]}return t},e.handleSupSubscript=function(e){var r=this.fetch(),a=r.text;this.consume();var n=this.parseGroup(e,!1,t.SUPSUB_GREEDINESS,void 0,void 0,!0);if(!n)throw new o("Expected group after '"+a+"'",r);return n},e.formatUnsupportedCmd=function(t){for(var e=[],r=0;r<t.length;r++)e.push({type:"textord",mode:"text",text:t[r]});var a={type:"text",mode:this.mode,body:e};return{type:"color",mode:this.mode,color:this.settings.errorColor,body:[a]}},e.parseAtom=function(t){var e,r,a=this.parseGroup("atom",!1,null,t);if("text"===this.mode)return a;for(;;){this.consumeSpaces();var n=this.fetch();if("\\limits"===n.text||"\\nolimits"===n.text){if(a&&"op"===a.type){var i="\\limits"===n.text;a.limits=i,a.alwaysHandleSupSub=!0}else{if(!a||"operatorname"!==a.type||!a.alwaysHandleSupSub)throw new o("Limit controls must follow a math operator",n);var s="\\limits"===n.text;a.limits=s}this.consume()}else if("^"===n.text){if(e)throw new o("Double superscript",n);e=this.handleSupSubscript("superscript")}else if("_"===n.text){if(r)throw new o("Double subscript",n);r=this.handleSupSubscript("subscript")}else{if("'"!==n.text)break;if(e)throw new o("Double superscript",n);var l={type:"textord",mode:this.mode,text:"\\prime"},h=[l];for(this.consume();"'"===this.fetch().text;)h.push(l),this.consume();"^"===this.fetch().text&&h.push(this.handleSupSubscript("superscript")),e={type:"ordgroup",mode:this.mode,body:h}}}return e||r?{type:"supsub",mode:this.mode,base:a,sup:e,sub:r}:a},e.parseFunction=function(t,e,r){var a=this.fetch(),n=a.text,i=ia[n];if(!i)return null;if(this.consume(),null!=r&&i.greediness<=r)throw new o("Got function '"+n+"' with no arguments"+(e?" as "+e:""),a);if("text"===this.mode&&!i.allowedInText)throw new o("Can't use function '"+n+"' in text mode",a);if("math"===this.mode&&!1===i.allowedInMath)throw new o("Can't use function '"+n+"' in math mode",a);var s=this.parseArguments(n,i),l=s.args,h=s.optArgs;return this.callFunction(n,l,h,a,t)},e.callFunction=function(t,e,r,a,n){var i={funcName:t,parser:this,token:a,breakOnTokenText:n},s=ia[t];if(s&&s.handler)return s.handler(i,e,r);throw new o("No function handler for "+t)},e.parseArguments=function(t,e){var r=e.numArgs+e.numOptionalArgs;if(0===r)return{args:[],optArgs:[]};for(var a=e.greediness,n=[],i=[],s=0;s<r;s++){var l=e.argTypes&&e.argTypes[s],h=s<e.numOptionalArgs,m=s>0&&!h||0===s&&!h&&"math"===this.mode,c=this.parseGroupOfType("argument to '"+t+"'",l,h,a,m);if(!c){if(h){i.push(null);continue}throw new o("Expected group after '"+t+"'",this.fetch())}(h?i:n).push(c)}return{args:n,optArgs:i}},e.parseGroupOfType=function(t,e,r,a,n){switch(e){case"color":return n&&this.consumeSpaces(),this.parseColorGroup(r);case"size":return n&&this.consumeSpaces(),this.parseSizeGroup(r);case"url":return this.parseUrlGroup(r,n);case"math":case"text":return this.parseGroup(t,r,a,void 0,e,n);case"hbox":var i=this.parseGroup(t,r,a,void 0,"text",n);return i?{type:"styling",mode:i.mode,body:[i],style:"text"}:i;case"raw":if(n&&this.consumeSpaces(),r&&"{"===this.fetch().text)return null;var s=this.parseStringGroup("raw",r,!0);if(s)return{type:"raw",mode:"text",string:s.text};throw new o("Expected raw group",this.fetch());case"original":case null:case void 0:return this.parseGroup(t,r,a,void 0,void 0,n);default:throw new o("Unknown group type as "+t,this.fetch())}},e.consumeSpaces=function(){for(;" "===this.fetch().text;)this.consume()},e.parseStringGroup=function(t,e,r){var a=e?"[":"{",n=e?"]":"}",i=this.fetch();if(i.text!==a){if(e)return null;if(r&&"EOF"!==i.text&&/[^{}[\]]/.test(i.text))return this.consume(),i}var s=this.mode;this.mode="text",this.expect(a);for(var l,h="",m=this.fetch(),c=0,u=m;(l=this.fetch()).text!==n||r&&c>0;){switch(l.text){case"EOF":throw new o("Unexpected end of input in "+t,m.range(u,h));case a:c++;break;case n:c--}h+=(u=l).text,this.consume()}return this.expect(n),this.mode=s,m.range(u,h)},e.parseRegexGroup=function(t,e){var r=this.mode;this.mode="text";for(var a,n=this.fetch(),i=n,s="";"EOF"!==(a=this.fetch()).text&&t.test(s+a.text);)s+=(i=a).text,this.consume();if(""===s)throw new o("Invalid "+e+": '"+n.text+"'",n);return this.mode=r,n.range(i,s)},e.parseColorGroup=function(t){var e=this.parseStringGroup("color",t);if(!e)return null;var r=/^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i.exec(e.text);if(!r)throw new o("Invalid color: '"+e.text+"'",e);var a=r[0];return/^[0-9a-f]{6}$/i.test(a)&&(a="#"+a),{type:"color-token",mode:this.mode,color:a}},e.parseSizeGroup=function(t){var e,r=!1;if(!(e=t||"{"===this.fetch().text?this.parseStringGroup("size",t):this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/,"size")))return null;t||0!==e.text.length||(e.text="0pt",r=!0);var a=/([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e.text);if(!a)throw new o("Invalid size: '"+e.text+"'",e);var n={number:+(a[1]+a[2]),unit:a[3]};if(!At(n))throw new o("Invalid unit: '"+n.unit+"'",e);return{type:"size",mode:this.mode,value:n,isBlank:r}},e.parseUrlGroup=function(t,e){this.gullet.lexer.setCatcode("%",13);var r=this.parseStringGroup("url",t,!0);if(this.gullet.lexer.setCatcode("%",14),!r)return null;var a=r.text.replace(/\\([#$%&~_^{}])/g,"$1");return{type:"url",mode:this.mode,url:a}},e.parseGroup=function(e,r,n,i,s,l){var h=this.mode;s&&this.switchMode(s),l&&this.consumeSpaces();var m,c=this.fetch(),u=c.text;if(r?"["===u:"{"===u||"\\begingroup"===u){this.consume();var p=t.endOfGroup[u];this.gullet.beginGroup();var d=this.parseExpression(!1,p),f=this.fetch();this.expect(p),this.gullet.endGroup(),m={type:"ordgroup",mode:this.mode,loc:a.range(c,f),body:d,semisimple:"\\begingroup"===u||void 0}}else if(r)m=null;else if(null==(m=this.parseFunction(i,e,n)||this.parseSymbol())&&"\\"===u[0]&&!ba.hasOwnProperty(u)){if(this.settings.throwOnError)throw new o("Undefined control sequence: "+u,c);m=this.formatUnsupportedCmd(u),this.consume()}return s&&this.switchMode(h),m},e.formLigatures=function(t){for(var e=t.length-1,r=0;r<e;++r){var n=t[r],i=n.text;"-"===i&&"-"===t[r+1].text&&(r+1<e&&"-"===t[r+2].text?(t.splice(r,3,{type:"textord",mode:"text",loc:a.range(n,t[r+2]),text:"---"}),e-=2):(t.splice(r,2,{type:"textord",mode:"text",loc:a.range(n,t[r+1]),text:"--"}),e-=1)),"'"!==i&&"`"!==i||t[r+1].text!==i||(t.splice(r,2,{type:"textord",mode:"text",loc:a.range(n,t[r+1]),text:i+i}),e-=1)}},e.parseSymbol=function(){var t=this.fetch(),e=t.text;if(/^\\verb[^a-zA-Z]/.test(e)){this.consume();var r=e.slice(5),n="*"===r.charAt(0);if(n&&(r=r.slice(1)),r.length<2||r.charAt(0)!==r.slice(-1))throw new o("\\verb assertion failed --\n please report what input caused this bug");return{type:"verb",mode:"text",body:r=r.slice(1,-1),star:n}}ka.hasOwnProperty(e[0])&&!j[this.mode][e[0]]&&(this.settings.strict&&"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Accented Unicode text character "'+e[0]+'" used in math mode',t),e=ka[e[0]]+e.substr(1));var i,s=sa.exec(e);if(s&&("i"===(e=e.substring(0,s.index))?e="\u0131":"j"===e&&(e="\u0237")),j[this.mode][e]){this.settings.strict&&"math"===this.mode&&"\xc7\xd0\xde\xe7\xfe".indexOf(e)>=0&&this.settings.reportNonstrict("unicodeTextInMathMode",'Latin-1/Unicode text character "'+e[0]+'" used in math mode',t);var l,h=j[this.mode][e].group,m=a.range(t);if(W.hasOwnProperty(h)){var c=h;l={type:"atom",mode:this.mode,family:c,loc:m,text:e}}else l={type:h,mode:this.mode,loc:m,text:e};i=l}else{if(!(e.charCodeAt(0)>=128))return null;this.settings.strict&&(M(e.charCodeAt(0))?"math"===this.mode&&this.settings.reportNonstrict("unicodeTextInMathMode",'Unicode text character "'+e[0]+'" used in math mode',t):this.settings.reportNonstrict("unknownSymbol",'Unrecognized Unicode character "'+e[0]+'" ('+e.charCodeAt(0)+")",t)),i={type:"textord",mode:"text",loc:a.range(t),text:e}}if(this.consume(),s)for(var u=0;u<s[0].length;u++){var p=s[0][u];if(!wa[p])throw new o("Unknown accent ' "+p+"'",t);var d=wa[p][this.mode];if(!d)throw new o("Accent "+p+" unsupported in "+this.mode+" mode",t);i={type:"accent",mode:this.mode,loc:a.range(t),label:d,isStretchy:!1,isShifty:!0,base:i}}return i},t}();Sa.endOfExpression=["}","\\endgroup","\\end","\\right","&"],Sa.endOfGroup={"[":"]","{":"}","\\begingroup":"\\endgroup"},Sa.SUPSUB_GREEDINESS=1;var Ma=function(t,e){if(!("string"==typeof t||t instanceof String))throw new TypeError("KaTeX can only parse string typed expression");var r=new Sa(t,e);delete r.gullet.macros.current["\\df@tag"];var a=r.parse();if(r.gullet.macros.get("\\df@tag")){if(!e.displayMode)throw new o("\\tag works only in display equations");r.gullet.feed("\\df@tag"),a=[{type:"tag",mode:"text",body:a,tag:r.parse()}]}return a},za=function(t,e,r){e.textContent="";var a=Ta(t,r).toNode();e.appendChild(a)};"undefined"!=typeof document&&"CSS1Compat"!==document.compatMode&&("undefined"!=typeof console&&console.warn("Warning: KaTeX doesn't work in quirks mode. Make sure your website has a suitable doctype."),za=function(){throw new o("KaTeX doesn't work in quirks mode.")});var Aa=function(t,e,r){if(r.throwOnError||!(t instanceof o))throw t;var a=Dt.makeSpan(["katex-error"],[new E(e)]);return a.setAttribute("title",t.toString()),a.setAttribute("style","color:"+r.errorColor),a},Ta=function(t,e){var r=new u(e);try{var a=Ma(t,r);return ke(a,t,r)}catch(e){return Aa(e,t,r)}},Ba={version:"0.12.0",render:za,renderToString:function(t,e){return Ta(t,e).toMarkup()},ParseError:o,__parse:function(t,e){var r=new u(e);return Ma(t,r)},__renderToDomTree:Ta,__renderToHTMLTree:function(t,e){var r=new u(e);try{return function(t,e,r){var a=le(t,ye(r)),n=Dt.makeSpan(["katex"],[a]);return we(n,r)}(Ma(t,r),0,r)}catch(e){return Aa(e,t,r)}},__setFontMetrics:function(t,e){F[t]=e},__defineSymbol:$,__defineMacro:pa,__domTree:{Span:N,Anchor:I,SymbolNode:E,SvgNode:L,PathNode:P,LineNode:D}};e.default=Ba}]).default}); \ No newline at end of file +!(function (t, e) { + 'object' == typeof exports && 'object' == typeof module + ? (module.exports = e()) + : 'function' == typeof define && define.amd + ? define([], e) + : 'object' == typeof exports + ? (exports.katex = e()) + : (t.katex = e()); +})('undefined' != typeof self ? self : this, function () { + return (function (t) { + var e = {}; + function r(a) { + if (e[a]) return e[a].exports; + var n = (e[a] = { i: a, l: !1, exports: {} }); + return t[a].call(n.exports, n, n.exports, r), (n.l = !0), n.exports; + } + return ( + (r.m = t), + (r.c = e), + (r.d = function (t, e, a) { + r.o(t, e) || Object.defineProperty(t, e, { enumerable: !0, get: a }); + }), + (r.r = function (t) { + 'undefined' != typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, { value: 'Module' }), + Object.defineProperty(t, '__esModule', { value: !0 }); + }), + (r.t = function (t, e) { + if ((1 & e && (t = r(t)), 8 & e)) return t; + if (4 & e && 'object' == typeof t && t && t.__esModule) return t; + var a = Object.create(null); + if ((r.r(a), Object.defineProperty(a, 'default', { enumerable: !0, value: t }), 2 & e && 'string' != typeof t)) + for (var n in t) + r.d( + a, + n, + function (e) { + return t[e]; + }.bind(null, n) + ); + return a; + }), + (r.n = function (t) { + var e = + t && t.__esModule + ? function () { + return t.default; + } + : function () { + return t; + }; + return r.d(e, 'a', e), e; + }), + (r.o = function (t, e) { + return Object.prototype.hasOwnProperty.call(t, e); + }), + (r.p = ''), + r((r.s = 1)) + ); + })([ + function (t, e, r) {}, + function (t, e, r) { + 'use strict'; + r.r(e); + r(0); + var a = (function () { + function t(t, e, r) { + (this.lexer = void 0), (this.start = void 0), (this.end = void 0), (this.lexer = t), (this.start = e), (this.end = r); + } + return ( + (t.range = function (e, r) { + return r + ? e && e.loc && r.loc && e.loc.lexer === r.loc.lexer + ? new t(e.loc.lexer, e.loc.start, r.loc.end) + : null + : e && e.loc; + }), + t + ); + })(), + n = (function () { + function t(t, e) { + (this.text = void 0), + (this.loc = void 0), + (this.noexpand = void 0), + (this.treatAsRelax = void 0), + (this.text = t), + (this.loc = e); + } + return ( + (t.prototype.range = function (e, r) { + return new t(r, a.range(this, e)); + }), + t + ); + })(), + i = function t(e, r) { + this.position = void 0; + var a, + n = 'KaTeX parse error: ' + e, + i = r && r.loc; + if (i && i.start <= i.end) { + var o = i.lexer.input; + a = i.start; + var s = i.end; + a === o.length ? (n += ' at end of input: ') : (n += ' at position ' + (a + 1) + ': '); + var l = o.slice(a, s).replace(/[^]/g, '$&\u0332'); + n += + (a > 15 ? '\u2026' + o.slice(a - 15, a) : o.slice(0, a)) + + l + + (s + 15 < o.length ? o.slice(s, s + 15) + '\u2026' : o.slice(s)); + } + var h = new Error(n); + return (h.name = 'ParseError'), (h.__proto__ = t.prototype), (h.position = a), h; + }; + i.prototype.__proto__ = Error.prototype; + var o = i, + s = /([A-Z])/g, + l = { '&': '&', '>': '>', '<': '<', '"': '"', "'": ''' }, + h = /[&><"']/g; + var m = function t(e) { + return 'ordgroup' === e.type + ? 1 === e.body.length + ? t(e.body[0]) + : e + : 'color' === e.type + ? 1 === e.body.length + ? t(e.body[0]) + : e + : 'font' === e.type + ? t(e.body) + : e; + }, + c = { + contains: function (t, e) { + return -1 !== t.indexOf(e); + }, + deflt: function (t, e) { + return void 0 === t ? e : t; + }, + escape: function (t) { + return String(t).replace(h, function (t) { + return l[t]; + }); + }, + hyphenate: function (t) { + return t.replace(s, '-$1').toLowerCase(); + }, + getBaseElem: m, + isCharacterBox: function (t) { + var e = m(t); + return 'mathord' === e.type || 'textord' === e.type || 'atom' === e.type; + }, + protocolFromUrl: function (t) { + var e = /^\s*([^\\/#]*?)(?::|�*58|�*3a)/i.exec(t); + return null != e ? e[1] : '_relative'; + }, + }, + u = (function () { + function t(t) { + (this.displayMode = void 0), + (this.output = void 0), + (this.leqno = void 0), + (this.fleqn = void 0), + (this.throwOnError = void 0), + (this.errorColor = void 0), + (this.macros = void 0), + (this.minRuleThickness = void 0), + (this.colorIsTextColor = void 0), + (this.strict = void 0), + (this.trust = void 0), + (this.maxSize = void 0), + (this.maxExpand = void 0), + (this.globalGroup = void 0), + (t = t || {}), + (this.displayMode = c.deflt(t.displayMode, !1)), + (this.output = c.deflt(t.output, 'htmlAndMathml')), + (this.leqno = c.deflt(t.leqno, !1)), + (this.fleqn = c.deflt(t.fleqn, !1)), + (this.throwOnError = c.deflt(t.throwOnError, !0)), + (this.errorColor = c.deflt(t.errorColor, '#cc0000')), + (this.macros = t.macros || {}), + (this.minRuleThickness = Math.max(0, c.deflt(t.minRuleThickness, 0))), + (this.colorIsTextColor = c.deflt(t.colorIsTextColor, !1)), + (this.strict = c.deflt(t.strict, 'warn')), + (this.trust = c.deflt(t.trust, !1)), + (this.maxSize = Math.max(0, c.deflt(t.maxSize, 1 / 0))), + (this.maxExpand = Math.max(0, c.deflt(t.maxExpand, 1e3))), + (this.globalGroup = c.deflt(t.globalGroup, !1)); + } + var e = t.prototype; + return ( + (e.reportNonstrict = function (t, e, r) { + var a = this.strict; + if (('function' == typeof a && (a = a(t, e, r)), a && 'ignore' !== a)) { + if (!0 === a || 'error' === a) + throw new o("LaTeX-incompatible input and strict mode is set to 'error': " + e + ' [' + t + ']', r); + 'warn' === a + ? 'undefined' != typeof console && + console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + e + ' [' + t + ']') + : 'undefined' != typeof console && + console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '" + a + "': " + e + ' [' + t + ']'); + } + }), + (e.useStrictBehavior = function (t, e, r) { + var a = this.strict; + if ('function' == typeof a) + try { + a = a(t, e, r); + } catch (t) { + a = 'error'; + } + return ( + !(!a || 'ignore' === a) && + (!0 === a || + 'error' === a || + ('warn' === a + ? ('undefined' != typeof console && + console.warn("LaTeX-incompatible input and strict mode is set to 'warn': " + e + ' [' + t + ']'), + !1) + : ('undefined' != typeof console && + console.warn("LaTeX-incompatible input and strict mode is set to unrecognized '" + a + "': " + e + ' [' + t + ']'), + !1))) + ); + }), + (e.isTrusted = function (t) { + t.url && !t.protocol && (t.protocol = c.protocolFromUrl(t.url)); + var e = 'function' == typeof this.trust ? this.trust(t) : this.trust; + return Boolean(e); + }), + t + ); + })(), + p = (function () { + function t(t, e, r) { + (this.id = void 0), (this.size = void 0), (this.cramped = void 0), (this.id = t), (this.size = e), (this.cramped = r); + } + var e = t.prototype; + return ( + (e.sup = function () { + return d[f[this.id]]; + }), + (e.sub = function () { + return d[g[this.id]]; + }), + (e.fracNum = function () { + return d[x[this.id]]; + }), + (e.fracDen = function () { + return d[v[this.id]]; + }), + (e.cramp = function () { + return d[b[this.id]]; + }), + (e.text = function () { + return d[y[this.id]]; + }), + (e.isTight = function () { + return this.size >= 2; + }), + t + ); + })(), + d = [ + new p(0, 0, !1), + new p(1, 0, !0), + new p(2, 1, !1), + new p(3, 1, !0), + new p(4, 2, !1), + new p(5, 2, !0), + new p(6, 3, !1), + new p(7, 3, !0), + ], + f = [4, 5, 4, 5, 6, 7, 6, 7], + g = [5, 5, 5, 5, 7, 7, 7, 7], + x = [2, 3, 4, 5, 6, 7, 6, 7], + v = [3, 3, 5, 5, 7, 7, 7, 7], + b = [1, 1, 3, 3, 5, 5, 7, 7], + y = [0, 1, 2, 3, 2, 3, 2, 3], + w = { DISPLAY: d[0], TEXT: d[2], SCRIPT: d[4], SCRIPTSCRIPT: d[6] }, + k = [ + { + name: 'latin', + blocks: [ + [256, 591], + [768, 879], + ], + }, + { name: 'cyrillic', blocks: [[1024, 1279]] }, + { name: 'brahmic', blocks: [[2304, 4255]] }, + { name: 'georgian', blocks: [[4256, 4351]] }, + { + name: 'cjk', + blocks: [ + [12288, 12543], + [19968, 40879], + [65280, 65376], + ], + }, + { name: 'hangul', blocks: [[44032, 55215]] }, + ]; + var S = []; + function M(t) { + for (var e = 0; e < S.length; e += 2) if (t >= S[e] && t <= S[e + 1]) return !0; + return !1; + } + k.forEach(function (t) { + return t.blocks.forEach(function (t) { + return S.push.apply(S, t); + }); + }); + var z = { + leftParenInner: 'M291 0 H417 V300 H291 z', + rightParenInner: 'M457 0 H583 V300 H457 z', + doubleleftarrow: + 'M262 157\nl10-10c34-36 62.7-77 86-123 3.3-8 5-13.3 5-16 0-5.3-6.7-8-20-8-7.3\n 0-12.2.5-14.5 1.5-2.3 1-4.8 4.5-7.5 10.5-49.3 97.3-121.7 169.3-217 216-28\n 14-57.3 25-88 33-6.7 2-11 3.8-13 5.5-2 1.7-3 4.2-3 7.5s1 5.8 3 7.5\nc2 1.7 6.3 3.5 13 5.5 68 17.3 128.2 47.8 180.5 91.5 52.3 43.7 93.8 96.2 124.5\n 157.5 9.3 8 15.3 12.3 18 13h6c12-.7 18-4 18-10 0-2-1.7-7-5-15-23.3-46-52-87\n-86-123l-10-10h399738v-40H218c328 0 0 0 0 0l-10-8c-26.7-20-65.7-43-117-69 2.7\n-2 6-3.7 10-5 36.7-16 72.3-37.3 107-64l10-8h399782v-40z\nm8 0v40h399730v-40zm0 194v40h399730v-40z', + doublerightarrow: + 'M399738 392l\n-10 10c-34 36-62.7 77-86 123-3.3 8-5 13.3-5 16 0 5.3 6.7 8 20 8 7.3 0 12.2-.5\n 14.5-1.5 2.3-1 4.8-4.5 7.5-10.5 49.3-97.3 121.7-169.3 217-216 28-14 57.3-25 88\n-33 6.7-2 11-3.8 13-5.5 2-1.7 3-4.2 3-7.5s-1-5.8-3-7.5c-2-1.7-6.3-3.5-13-5.5-68\n-17.3-128.2-47.8-180.5-91.5-52.3-43.7-93.8-96.2-124.5-157.5-9.3-8-15.3-12.3-18\n-13h-6c-12 .7-18 4-18 10 0 2 1.7 7 5 15 23.3 46 52 87 86 123l10 10H0v40h399782\nc-328 0 0 0 0 0l10 8c26.7 20 65.7 43 117 69-2.7 2-6 3.7-10 5-36.7 16-72.3 37.3\n-107 64l-10 8H0v40zM0 157v40h399730v-40zm0 194v40h399730v-40z', + leftarrow: + 'M400000 241H110l3-3c68.7-52.7 113.7-120\n 135-202 4-14.7 6-23 6-25 0-7.3-7-11-21-11-8 0-13.2.8-15.5 2.5-2.3 1.7-4.2 5.8\n-5.5 12.5-1.3 4.7-2.7 10.3-4 17-12 48.7-34.8 92-68.5 130S65.3 228.3 18 247\nc-10 4-16 7.7-18 11 0 8.7 6 14.3 18 17 47.3 18.7 87.8 47 121.5 85S196 441.3 208\n 490c.7 2 1.3 5 2 9s1.2 6.7 1.5 8c.3 1.3 1 3.3 2 6s2.2 4.5 3.5 5.5c1.3 1 3.3\n 1.8 6 2.5s6 1 10 1c14 0 21-3.7 21-11 0-2-2-10.3-6-25-20-79.3-65-146.7-135-202\n l-3-3h399890zM100 241v40h399900v-40z', + leftbrace: + 'M6 548l-6-6v-35l6-11c56-104 135.3-181.3 238-232 57.3-28.7 117\n-45 179-50h399577v120H403c-43.3 7-81 15-113 26-100.7 33-179.7 91-237 174-2.7\n 5-6 9-10 13-.7 1-7.3 1-20 1H6z', + leftbraceunder: + 'M0 6l6-6h17c12.688 0 19.313.3 20 1 4 4 7.313 8.3 10 13\n 35.313 51.3 80.813 93.8 136.5 127.5 55.688 33.7 117.188 55.8 184.5 66.5.688\n 0 2 .3 4 1 18.688 2.7 76 4.3 172 5h399450v120H429l-6-1c-124.688-8-235-61.7\n-331-161C60.687 138.7 32.312 99.3 7 54L0 41V6z', + leftgroup: 'M400000 80\nH435C64 80 168.3 229.4 21 260c-5.9 1.2-18 0-18 0-2 0-3-1-3-3v-38C76 61 257 0\n 435 0h399565z', + leftgroupunder: 'M400000 262\nH435C64 262 168.3 112.6 21 82c-5.9-1.2-18 0-18 0-2 0-3 1-3 3v38c76 158 257 219\n 435 219h399565z', + leftharpoon: + 'M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3\n-3.3 10.2-9.5 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5\n-18.3 3-21-1.3-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7\n-196 228-6.7 4.7-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40z', + leftharpoonplus: + 'M0 267c.7 5.3 3 10 7 14h399993v-40H93c3.3-3.3 10.2-9.5\n 20.5-18.5s17.8-15.8 22.5-20.5c50.7-52 88-110.3 112-175 4-11.3 5-18.3 3-21-1.3\n-4-7.3-6-18-6-8 0-13 .7-15 2s-4.7 6.7-8 16c-42 98.7-107.3 174.7-196 228-6.7 4.7\n-10.7 8-12 10-1.3 2-2 5.7-2 11zm100-26v40h399900v-40zM0 435v40h400000v-40z\nm0 0v40h400000v-40z', + leftharpoondown: + 'M7 241c-4 4-6.333 8.667-7 14 0 5.333.667 9 2 11s5.333\n 5.333 12 10c90.667 54 156 130 196 228 3.333 10.667 6.333 16.333 9 17 2 .667 5\n 1 9 1h5c10.667 0 16.667-2 18-6 2-2.667 1-9.667-3-21-32-87.333-82.667-157.667\n-152-211l-3-3h399907v-40zM93 281 H400000 v-40L7 241z', + leftharpoondownplus: + 'M7 435c-4 4-6.3 8.7-7 14 0 5.3.7 9 2 11s5.3 5.3 12\n 10c90.7 54 156 130 196 228 3.3 10.7 6.3 16.3 9 17 2 .7 5 1 9 1h5c10.7 0 16.7\n-2 18-6 2-2.7 1-9.7-3-21-32-87.3-82.7-157.7-152-211l-3-3h399907v-40H7zm93 0\nv40h399900v-40zM0 241v40h399900v-40zm0 0v40h399900v-40z', + lefthook: + 'M400000 281 H103s-33-11.2-61-33.5S0 197.3 0 164s14.2-61.2 42.5\n-83.5C70.8 58.2 104 47 142 47 c16.7 0 25 6.7 25 20 0 12-8.7 18.7-26 20-40 3.3\n-68.7 15.7-86 37-10 12-15 25.3-15 40 0 22.7 9.8 40.7 29.5 54 19.7 13.3 43.5 21\n 71.5 23h399859zM103 281v-40h399897v40z', + leftlinesegment: 'M40 281 V428 H0 V94 H40 V241 H400000 v40z\nM40 281 V428 H0 V94 H40 V241 H400000 v40z', + leftmapsto: 'M40 281 V448H0V74H40V241H400000v40z\nM40 281 V448H0V74H40V241H400000v40z', + leftToFrom: + 'M0 147h400000v40H0zm0 214c68 40 115.7 95.7 143 167h22c15.3 0 23\n-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69-70-101l-7-8h399905v-40H95l7-8\nc28.7-32 52-65.7 70-101 10.7-23.3 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 265.3\n 68 321 0 361zm0-174v-40h399900v40zm100 154v40h399900v-40z', + longequal: 'M0 50 h400000 v40H0z m0 194h40000v40H0z\nM0 50 h400000 v40H0z m0 194h40000v40H0z', + midbrace: + 'M200428 334\nc-100.7-8.3-195.3-44-280-108-55.3-42-101.7-93-139-153l-9-14c-2.7 4-5.7 8.7-9 14\n-53.3 86.7-123.7 153-211 199-66.7 36-137.3 56.3-212 62H0V214h199568c178.3-11.7\n 311.7-78.3 403-201 6-8 9.7-12 11-12 .7-.7 6.7-1 18-1s17.3.3 18 1c1.3 0 5 4 11\n 12 44.7 59.3 101.3 106.3 170 141s145.3 54.3 229 60h199572v120z', + midbraceunder: + 'M199572 214\nc100.7 8.3 195.3 44 280 108 55.3 42 101.7 93 139 153l9 14c2.7-4 5.7-8.7 9-14\n 53.3-86.7 123.7-153 211-199 66.7-36 137.3-56.3 212-62h199568v120H200432c-178.3\n 11.7-311.7 78.3-403 201-6 8-9.7 12-11 12-.7.7-6.7 1-18 1s-17.3-.3-18-1c-1.3 0\n-5-4-11-12-44.7-59.3-101.3-106.3-170-141s-145.3-54.3-229-60H0V214z', + oiintSize1: + 'M512.6 71.6c272.6 0 320.3 106.8 320.3 178.2 0 70.8-47.7 177.6\n-320.3 177.6S193.1 320.6 193.1 249.8c0-71.4 46.9-178.2 319.5-178.2z\nm368.1 178.2c0-86.4-60.9-215.4-368.1-215.4-306.4 0-367.3 129-367.3 215.4 0 85.8\n60.9 214.8 367.3 214.8 307.2 0 368.1-129 368.1-214.8z', + oiintSize2: + 'M757.8 100.1c384.7 0 451.1 137.6 451.1 230 0 91.3-66.4 228.8\n-451.1 228.8-386.3 0-452.7-137.5-452.7-228.8 0-92.4 66.4-230 452.7-230z\nm502.4 230c0-111.2-82.4-277.2-502.4-277.2s-504 166-504 277.2\nc0 110 84 276 504 276s502.4-166 502.4-276z', + oiiintSize1: + 'M681.4 71.6c408.9 0 480.5 106.8 480.5 178.2 0 70.8-71.6 177.6\n-480.5 177.6S202.1 320.6 202.1 249.8c0-71.4 70.5-178.2 479.3-178.2z\nm525.8 178.2c0-86.4-86.8-215.4-525.7-215.4-437.9 0-524.7 129-524.7 215.4 0\n85.8 86.8 214.8 524.7 214.8 438.9 0 525.7-129 525.7-214.8z', + oiiintSize2: + 'M1021.2 53c603.6 0 707.8 165.8 707.8 277.2 0 110-104.2 275.8\n-707.8 275.8-606 0-710.2-165.8-710.2-275.8C311 218.8 415.2 53 1021.2 53z\nm770.4 277.1c0-131.2-126.4-327.6-770.5-327.6S248.4 198.9 248.4 330.1\nc0 130 128.8 326.4 772.7 326.4s770.5-196.4 770.5-326.4z', + rightarrow: + 'M0 241v40h399891c-47.3 35.3-84 78-110 128\n-16.7 32-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20\n 11 8 0 13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7\n 39-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85\n-40.5-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n 151.7 139 205zm0 0v40h399900v-40z', + rightbrace: + 'M400000 542l\n-6 6h-17c-12.7 0-19.3-.3-20-1-4-4-7.3-8.3-10-13-35.3-51.3-80.8-93.8-136.5-127.5\ns-117.2-55.8-184.5-66.5c-.7 0-2-.3-4-1-18.7-2.7-76-4.3-172-5H0V214h399571l6 1\nc124.7 8 235 61.7 331 161 31.3 33.3 59.7 72.7 85 118l7 13v35z', + rightbraceunder: + 'M399994 0l6 6v35l-6 11c-56 104-135.3 181.3-238 232-57.3\n 28.7-117 45-179 50H-300V214h399897c43.3-7 81-15 113-26 100.7-33 179.7-91 237\n-174 2.7-5 6-9 10-13 .7-1 7.3-1 20-1h17z', + rightgroup: 'M0 80h399565c371 0 266.7 149.4 414 180 5.9 1.2 18 0 18 0 2 0\n 3-1 3-3v-38c-76-158-257-219-435-219H0z', + rightgroupunder: 'M0 262h399565c371 0 266.7-149.4 414-180 5.9-1.2 18 0 18\n 0 2 0 3 1 3 3v38c-76 158-257 219-435 219H0z', + rightharpoon: + 'M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3\n-3.7-15.3-11-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2\n-10.7 0-16.7 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58\n 69.2 92 94.5zm0 0v40h399900v-40z', + rightharpoonplus: + 'M0 241v40h399993c4.7-4.7 7-9.3 7-14 0-9.3-3.7-15.3-11\n-18-92.7-56.7-159-133.7-199-231-3.3-9.3-6-14.7-8-16-2-1.3-7-2-15-2-10.7 0-16.7\n 2-18 6-2 2.7-1 9.7 3 21 15.3 42 36.7 81.8 64 119.5 27.3 37.7 58 69.2 92 94.5z\nm0 0v40h399900v-40z m100 194v40h399900v-40zm0 0v40h399900v-40z', + rightharpoondown: + 'M399747 511c0 7.3 6.7 11 20 11 8 0 13-.8 15-2.5s4.7-6.8\n 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3 8.5-5.8 9.5\n-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3-64.7 57-92 95\n-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 241v40h399900v-40z', + rightharpoondownplus: + 'M399747 705c0 7.3 6.7 11 20 11 8 0 13-.8\n 15-2.5s4.7-6.8 8-15.5c40-94 99.3-166.3 178-217 13.3-8 20.3-12.3 21-13 5.3-3.3\n 8.5-5.8 9.5-7.5 1-1.7 1.5-5.2 1.5-10.5s-2.3-10.3-7-15H0v40h399908c-34 25.3\n-64.7 57-92 95-27.3 38-48.7 77.7-64 119-3.3 8.7-5 14-5 16zM0 435v40h399900v-40z\nm0-194v40h400000v-40zm0 0v40h400000v-40z', + righthook: + 'M399859 241c-764 0 0 0 0 0 40-3.3 68.7-15.7 86-37 10-12 15-25.3\n 15-40 0-22.7-9.8-40.7-29.5-54-19.7-13.3-43.5-21-71.5-23-17.3-1.3-26-8-26-20 0\n-13.3 8.7-20 26-20 38 0 71 11.2 99 33.5 0 0 7 5.6 21 16.7 14 11.2 21 33.5 21\n 66.8s-14 61.2-42 83.5c-28 22.3-61 33.5-99 33.5L0 241z M0 281v-40h399859v40z', + rightlinesegment: 'M399960 241 V94 h40 V428 h-40 V281 H0 v-40z\nM399960 241 V94 h40 V428 h-40 V281 H0 v-40z', + rightToFrom: + 'M400000 167c-70.7-42-118-97.7-142-167h-23c-15.3 0-23 .3-23\n 1 0 1.3 5.3 13.7 16 37 18 35.3 41.3 69 70 101l7 8H0v40h399905l-7 8c-28.7 32\n-52 65.7-70 101-10.7 23.3-16 35.7-16 37 0 .7 7.7 1 23 1h23c24-69.3 71.3-125 142\n-167z M100 147v40h399900v-40zM0 341v40h399900v-40z', + twoheadleftarrow: + 'M0 167c68 40\n 115.7 95.7 143 167h22c15.3 0 23-.3 23-1 0-1.3-5.3-13.7-16-37-18-35.3-41.3-69\n-70-101l-7-8h125l9 7c50.7 39.3 85 86 103 140h46c0-4.7-6.3-18.7-19-42-18-35.3\n-40-67.3-66-96l-9-9h399716v-40H284l9-9c26-28.7 48-60.7 66-96 12.7-23.333 19\n-37.333 19-42h-46c-18 54-52.3 100.7-103 140l-9 7H95l7-8c28.7-32 52-65.7 70-101\n 10.7-23.333 16-35.7 16-37 0-.7-7.7-1-23-1h-22C115.7 71.3 68 127 0 167z', + twoheadrightarrow: + 'M400000 167\nc-68-40-115.7-95.7-143-167h-22c-15.3 0-23 .3-23 1 0 1.3 5.3 13.7 16 37 18 35.3\n 41.3 69 70 101l7 8h-125l-9-7c-50.7-39.3-85-86-103-140h-46c0 4.7 6.3 18.7 19 42\n 18 35.3 40 67.3 66 96l9 9H0v40h399716l-9 9c-26 28.7-48 60.7-66 96-12.7 23.333\n-19 37.333-19 42h46c18-54 52.3-100.7 103-140l9-7h125l-7 8c-28.7 32-52 65.7-70\n 101-10.7 23.333-16 35.7-16 37 0 .7 7.7 1 23 1h22c27.3-71.3 75-127 143-167z', + tilde1: + 'M200 55.538c-77 0-168 73.953-177 73.953-3 0-7\n-2.175-9-5.437L2 97c-1-2-2-4-2-6 0-4 2-7 5-9l20-12C116 12 171 0 207 0c86 0\n 114 68 191 68 78 0 168-68 177-68 4 0 7 2 9 5l12 19c1 2.175 2 4.35 2 6.525 0\n 4.35-2 7.613-5 9.788l-19 13.05c-92 63.077-116.937 75.308-183 76.128\n-68.267.847-113-73.952-191-73.952z', + tilde2: + 'M344 55.266c-142 0-300.638 81.316-311.5 86.418\n-8.01 3.762-22.5 10.91-23.5 5.562L1 120c-1-2-1-3-1-4 0-5 3-9 8-10l18.4-9C160.9\n 31.9 283 0 358 0c148 0 188 122 331 122s314-97 326-97c4 0 8 2 10 7l7 21.114\nc1 2.14 1 3.21 1 4.28 0 5.347-3 9.626-7 10.696l-22.3 12.622C852.6 158.372 751\n 181.476 676 181.476c-149 0-189-126.21-332-126.21z', + tilde3: + 'M786 59C457 59 32 175.242 13 175.242c-6 0-10-3.457\n-11-10.37L.15 138c-1-7 3-12 10-13l19.2-6.4C378.4 40.7 634.3 0 804.3 0c337 0\n 411.8 157 746.8 157 328 0 754-112 773-112 5 0 10 3 11 9l1 14.075c1 8.066-.697\n 16.595-6.697 17.492l-21.052 7.31c-367.9 98.146-609.15 122.696-778.15 122.696\n -338 0-409-156.573-744-156.573z', + tilde4: + 'M786 58C457 58 32 177.487 13 177.487c-6 0-10-3.345\n-11-10.035L.15 143c-1-7 3-12 10-13l22-6.7C381.2 35 637.15 0 807.15 0c337 0 409\n 177 744 177 328 0 754-127 773-127 5 0 10 3 11 9l1 14.794c1 7.805-3 13.38-9\n 14.495l-20.7 5.574c-366.85 99.79-607.3 139.372-776.3 139.372-338 0-409\n -175.236-744-175.236z', + vec: 'M377 20c0-5.333 1.833-10 5.5-14S391 0 397 0c4.667 0 8.667 1.667 12 5\n3.333 2.667 6.667 9 10 19 6.667 24.667 20.333 43.667 41 57 7.333 4.667 11\n10.667 11 18 0 6-1 10-3 12s-6.667 5-14 9c-28.667 14.667-53.667 35.667-75 63\n-1.333 1.333-3.167 3.5-5.5 6.5s-4 4.833-5 5.5c-1 .667-2.5 1.333-4.5 2s-4.333 1\n-7 1c-4.667 0-9.167-1.833-13.5-5.5S337 184 337 178c0-12.667 15.667-32.333 47-59\nH213l-171-1c-8.667-6-13-12.333-13-19 0-4.667 4.333-11.333 13-20h359\nc-16-25.333-24-45-24-59z', + widehat1: + 'M529 0h5l519 115c5 1 9 5 9 10 0 1-1 2-1 3l-4 22\nc-1 5-5 9-11 9h-2L532 67 19 159h-2c-5 0-9-4-11-9l-5-22c-1-6 2-12 8-13z', + widehat2: 'M1181 0h2l1171 176c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 220h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z', + widehat3: 'M1181 0h2l1171 236c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 280h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z', + widehat4: 'M1181 0h2l1171 296c6 0 10 5 10 11l-2 23c-1 6-5 10\n-11 10h-1L1182 67 15 340h-1c-6 0-10-4-11-10l-2-23c-1-6 4-11 10-11z', + widecheck1: + 'M529,159h5l519,-115c5,-1,9,-5,9,-10c0,-1,-1,-2,-1,-3l-4,-22c-1,\n-5,-5,-9,-11,-9h-2l-512,92l-513,-92h-2c-5,0,-9,4,-11,9l-5,22c-1,6,2,12,8,13z', + widecheck2: + 'M1181,220h2l1171,-176c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,153l-1167,-153h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z', + widecheck3: + 'M1181,280h2l1171,-236c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,213l-1167,-213h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z', + widecheck4: + 'M1181,340h2l1171,-296c6,0,10,-5,10,-11l-2,-23c-1,-6,-5,-10,\n-11,-10h-1l-1168,273l-1167,-273h-1c-6,0,-10,4,-11,10l-2,23c-1,6,4,11,10,11z', + baraboveleftarrow: + 'M400000 620h-399890l3 -3c68.7 -52.7 113.7 -120 135 -202\nc4 -14.7 6 -23 6 -25c0 -7.3 -7 -11 -21 -11c-8 0 -13.2 0.8 -15.5 2.5\nc-2.3 1.7 -4.2 5.8 -5.5 12.5c-1.3 4.7 -2.7 10.3 -4 17c-12 48.7 -34.8 92 -68.5 130\ns-74.2 66.3 -121.5 85c-10 4 -16 7.7 -18 11c0 8.7 6 14.3 18 17c47.3 18.7 87.8 47\n121.5 85s56.5 81.3 68.5 130c0.7 2 1.3 5 2 9s1.2 6.7 1.5 8c0.3 1.3 1 3.3 2 6\ns2.2 4.5 3.5 5.5c1.3 1 3.3 1.8 6 2.5s6 1 10 1c14 0 21 -3.7 21 -11\nc0 -2 -2 -10.3 -6 -25c-20 -79.3 -65 -146.7 -135 -202l-3 -3h399890z\nM100 620v40h399900v-40z M0 241v40h399900v-40zM0 241v40h399900v-40z', + rightarrowabovebar: + 'M0 241v40h399891c-47.3 35.3-84 78-110 128-16.7 32\n-27.7 63.7-33 95 0 1.3-.2 2.7-.5 4-.3 1.3-.5 2.3-.5 3 0 7.3 6.7 11 20 11 8 0\n13.2-.8 15.5-2.5 2.3-1.7 4.2-5.5 5.5-11.5 2-13.3 5.7-27 11-41 14.7-44.7 39\n-84.5 73-119.5s73.7-60.2 119-75.5c6-2 9-5.7 9-11s-3-9-9-11c-45.3-15.3-85-40.5\n-119-75.5s-58.3-74.8-73-119.5c-4.7-14-8.3-27.3-11-40-1.3-6.7-3.2-10.8-5.5\n-12.5-2.3-1.7-7.5-2.5-15.5-2.5-14 0-21 3.7-21 11 0 2 2 10.3 6 25 20.7 83.3 67\n151.7 139 205zm96 379h399894v40H0zm0 0h399904v40H0z', + baraboveshortleftharpoon: + 'M507,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17\nc2,0.7,5,1,9,1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21\nc-32,-87.3,-82.7,-157.7,-152,-211c0,0,-3,-3,-3,-3l399351,0l0,-40\nc-398570,0,-399437,0,-399437,0z M593 435 v40 H399500 v-40z\nM0 281 v-40 H399908 v40z M0 281 v-40 H399908 v40z', + rightharpoonaboveshortbar: + 'M0,241 l0,40c399126,0,399993,0,399993,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM0 241 v40 H399908 v-40z M0 475 v-40 H399500 v40z M0 475 v-40 H399500 v40z', + shortbaraboveleftharpoon: + 'M7,435c-4,4,-6.3,8.7,-7,14c0,5.3,0.7,9,2,11\nc1.3,2,5.3,5.3,12,10c90.7,54,156,130,196,228c3.3,10.7,6.3,16.3,9,17c2,0.7,5,1,9,\n1c0,0,5,0,5,0c10.7,0,16.7,-2,18,-6c2,-2.7,1,-9.7,-3,-21c-32,-87.3,-82.7,-157.7,\n-152,-211c0,0,-3,-3,-3,-3l399907,0l0,-40c-399126,0,-399993,0,-399993,0z\nM93 435 v40 H400000 v-40z M500 241 v40 H400000 v-40z M500 241 v40 H400000 v-40z', + shortrightharpoonabovebar: + 'M53,241l0,40c398570,0,399437,0,399437,0\nc4.7,-4.7,7,-9.3,7,-14c0,-9.3,-3.7,-15.3,-11,-18c-92.7,-56.7,-159,-133.7,-199,\n-231c-3.3,-9.3,-6,-14.7,-8,-16c-2,-1.3,-7,-2,-15,-2c-10.7,0,-16.7,2,-18,6\nc-2,2.7,-1,9.7,3,21c15.3,42,36.7,81.8,64,119.5c27.3,37.7,58,69.2,92,94.5z\nM500 241 v40 H399408 v-40z M500 435 v40 H400000 v-40z', + }, + A = (function () { + function t(t) { + (this.children = void 0), + (this.classes = void 0), + (this.height = void 0), + (this.depth = void 0), + (this.maxFontSize = void 0), + (this.style = void 0), + (this.children = t), + (this.classes = []), + (this.height = 0), + (this.depth = 0), + (this.maxFontSize = 0), + (this.style = {}); + } + var e = t.prototype; + return ( + (e.hasClass = function (t) { + return c.contains(this.classes, t); + }), + (e.toNode = function () { + for (var t = document.createDocumentFragment(), e = 0; e < this.children.length; e++) + t.appendChild(this.children[e].toNode()); + return t; + }), + (e.toMarkup = function () { + for (var t = '', e = 0; e < this.children.length; e++) t += this.children[e].toMarkup(); + return t; + }), + (e.toText = function () { + var t = function (t) { + return t.toText(); + }; + return this.children.map(t).join(''); + }), + t + ); + })(), + T = function (t) { + return t + .filter(function (t) { + return t; + }) + .join(' '); + }, + B = function (t, e, r) { + if ( + ((this.classes = t || []), + (this.attributes = {}), + (this.height = 0), + (this.depth = 0), + (this.maxFontSize = 0), + (this.style = r || {}), + e) + ) { + e.style.isTight() && this.classes.push('mtight'); + var a = e.getColor(); + a && (this.style.color = a); + } + }, + C = function (t) { + var e = document.createElement(t); + for (var r in ((e.className = T(this.classes)), this.style)) this.style.hasOwnProperty(r) && (e.style[r] = this.style[r]); + for (var a in this.attributes) this.attributes.hasOwnProperty(a) && e.setAttribute(a, this.attributes[a]); + for (var n = 0; n < this.children.length; n++) e.appendChild(this.children[n].toNode()); + return e; + }, + q = function (t) { + var e = '<' + t; + this.classes.length && (e += ' class="' + c.escape(T(this.classes)) + '"'); + var r = ''; + for (var a in this.style) this.style.hasOwnProperty(a) && (r += c.hyphenate(a) + ':' + this.style[a] + ';'); + for (var n in (r && (e += ' style="' + c.escape(r) + '"'), this.attributes)) + this.attributes.hasOwnProperty(n) && (e += ' ' + n + '="' + c.escape(this.attributes[n]) + '"'); + e += '>'; + for (var i = 0; i < this.children.length; i++) e += this.children[i].toMarkup(); + return (e += '</' + t + '>'); + }, + N = (function () { + function t(t, e, r, a) { + (this.children = void 0), + (this.attributes = void 0), + (this.classes = void 0), + (this.height = void 0), + (this.depth = void 0), + (this.width = void 0), + (this.maxFontSize = void 0), + (this.style = void 0), + B.call(this, t, r, a), + (this.children = e || []); + } + var e = t.prototype; + return ( + (e.setAttribute = function (t, e) { + this.attributes[t] = e; + }), + (e.hasClass = function (t) { + return c.contains(this.classes, t); + }), + (e.toNode = function () { + return C.call(this, 'span'); + }), + (e.toMarkup = function () { + return q.call(this, 'span'); + }), + t + ); + })(), + I = (function () { + function t(t, e, r, a) { + (this.children = void 0), + (this.attributes = void 0), + (this.classes = void 0), + (this.height = void 0), + (this.depth = void 0), + (this.maxFontSize = void 0), + (this.style = void 0), + B.call(this, e, a), + (this.children = r || []), + this.setAttribute('href', t); + } + var e = t.prototype; + return ( + (e.setAttribute = function (t, e) { + this.attributes[t] = e; + }), + (e.hasClass = function (t) { + return c.contains(this.classes, t); + }), + (e.toNode = function () { + return C.call(this, 'a'); + }), + (e.toMarkup = function () { + return q.call(this, 'a'); + }), + t + ); + })(), + O = (function () { + function t(t, e, r) { + (this.src = void 0), + (this.alt = void 0), + (this.classes = void 0), + (this.height = void 0), + (this.depth = void 0), + (this.maxFontSize = void 0), + (this.style = void 0), + (this.alt = e), + (this.src = t), + (this.classes = ['mord']), + (this.style = r); + } + var e = t.prototype; + return ( + (e.hasClass = function (t) { + return c.contains(this.classes, t); + }), + (e.toNode = function () { + var t = document.createElement('img'); + for (var e in ((t.src = this.src), (t.alt = this.alt), (t.className = 'mord'), this.style)) + this.style.hasOwnProperty(e) && (t.style[e] = this.style[e]); + return t; + }), + (e.toMarkup = function () { + var t = "<img src='" + this.src + " 'alt='" + this.alt + "' ", + e = ''; + for (var r in this.style) this.style.hasOwnProperty(r) && (e += c.hyphenate(r) + ':' + this.style[r] + ';'); + return e && (t += ' style="' + c.escape(e) + '"'), (t += "'/>"); + }), + t + ); + })(), + R = { '\xee': '\u0131\u0302', '\xef': '\u0131\u0308', '\xed': '\u0131\u0301', '\xec': '\u0131\u0300' }, + E = (function () { + function t(t, e, r, a, n, i, o, s) { + (this.text = void 0), + (this.height = void 0), + (this.depth = void 0), + (this.italic = void 0), + (this.skew = void 0), + (this.width = void 0), + (this.maxFontSize = void 0), + (this.classes = void 0), + (this.style = void 0), + (this.text = t), + (this.height = e || 0), + (this.depth = r || 0), + (this.italic = a || 0), + (this.skew = n || 0), + (this.width = i || 0), + (this.classes = o || []), + (this.style = s || {}), + (this.maxFontSize = 0); + var l = (function (t) { + for (var e = 0; e < k.length; e++) + for (var r = k[e], a = 0; a < r.blocks.length; a++) { + var n = r.blocks[a]; + if (t >= n[0] && t <= n[1]) return r.name; + } + return null; + })(this.text.charCodeAt(0)); + l && this.classes.push(l + '_fallback'), /[\xee\xef\xed\xec]/.test(this.text) && (this.text = R[this.text]); + } + var e = t.prototype; + return ( + (e.hasClass = function (t) { + return c.contains(this.classes, t); + }), + (e.toNode = function () { + var t = document.createTextNode(this.text), + e = null; + for (var r in (this.italic > 0 && ((e = document.createElement('span')).style.marginRight = this.italic + 'em'), + this.classes.length > 0 && ((e = e || document.createElement('span')).className = T(this.classes)), + this.style)) + this.style.hasOwnProperty(r) && ((e = e || document.createElement('span')).style[r] = this.style[r]); + return e ? (e.appendChild(t), e) : t; + }), + (e.toMarkup = function () { + var t = !1, + e = '<span'; + this.classes.length && ((t = !0), (e += ' class="'), (e += c.escape(T(this.classes))), (e += '"')); + var r = ''; + for (var a in (this.italic > 0 && (r += 'margin-right:' + this.italic + 'em;'), this.style)) + this.style.hasOwnProperty(a) && (r += c.hyphenate(a) + ':' + this.style[a] + ';'); + r && ((t = !0), (e += ' style="' + c.escape(r) + '"')); + var n = c.escape(this.text); + return t ? ((e += '>'), (e += n), (e += '</span>')) : n; + }), + t + ); + })(), + L = (function () { + function t(t, e) { + (this.children = void 0), (this.attributes = void 0), (this.children = t || []), (this.attributes = e || {}); + } + var e = t.prototype; + return ( + (e.toNode = function () { + var t = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + for (var e in this.attributes) + Object.prototype.hasOwnProperty.call(this.attributes, e) && t.setAttribute(e, this.attributes[e]); + for (var r = 0; r < this.children.length; r++) t.appendChild(this.children[r].toNode()); + return t; + }), + (e.toMarkup = function () { + var t = '<svg'; + for (var e in this.attributes) + Object.prototype.hasOwnProperty.call(this.attributes, e) && (t += ' ' + e + "='" + this.attributes[e] + "'"); + t += '>'; + for (var r = 0; r < this.children.length; r++) t += this.children[r].toMarkup(); + return (t += '</svg>'); + }), + t + ); + })(), + P = (function () { + function t(t, e) { + (this.pathName = void 0), (this.alternate = void 0), (this.pathName = t), (this.alternate = e); + } + var e = t.prototype; + return ( + (e.toNode = function () { + var t = document.createElementNS('http://www.w3.org/2000/svg', 'path'); + return this.alternate ? t.setAttribute('d', this.alternate) : t.setAttribute('d', z[this.pathName]), t; + }), + (e.toMarkup = function () { + return this.alternate ? "<path d='" + this.alternate + "'/>" : "<path d='" + z[this.pathName] + "'/>"; + }), + t + ); + })(), + D = (function () { + function t(t) { + (this.attributes = void 0), (this.attributes = t || {}); + } + var e = t.prototype; + return ( + (e.toNode = function () { + var t = document.createElementNS('http://www.w3.org/2000/svg', 'line'); + for (var e in this.attributes) + Object.prototype.hasOwnProperty.call(this.attributes, e) && t.setAttribute(e, this.attributes[e]); + return t; + }), + (e.toMarkup = function () { + var t = '<line'; + for (var e in this.attributes) + Object.prototype.hasOwnProperty.call(this.attributes, e) && (t += ' ' + e + "='" + this.attributes[e] + "'"); + return (t += '/>'); + }), + t + ); + })(); + function H(t) { + if (t instanceof E) return t; + throw new Error('Expected symbolNode but got ' + String(t) + '.'); + } + var F = { + 'AMS-Regular': { + 32: [0, 0, 0, 0, 0.25], + 65: [0, 0.68889, 0, 0, 0.72222], + 66: [0, 0.68889, 0, 0, 0.66667], + 67: [0, 0.68889, 0, 0, 0.72222], + 68: [0, 0.68889, 0, 0, 0.72222], + 69: [0, 0.68889, 0, 0, 0.66667], + 70: [0, 0.68889, 0, 0, 0.61111], + 71: [0, 0.68889, 0, 0, 0.77778], + 72: [0, 0.68889, 0, 0, 0.77778], + 73: [0, 0.68889, 0, 0, 0.38889], + 74: [0.16667, 0.68889, 0, 0, 0.5], + 75: [0, 0.68889, 0, 0, 0.77778], + 76: [0, 0.68889, 0, 0, 0.66667], + 77: [0, 0.68889, 0, 0, 0.94445], + 78: [0, 0.68889, 0, 0, 0.72222], + 79: [0.16667, 0.68889, 0, 0, 0.77778], + 80: [0, 0.68889, 0, 0, 0.61111], + 81: [0.16667, 0.68889, 0, 0, 0.77778], + 82: [0, 0.68889, 0, 0, 0.72222], + 83: [0, 0.68889, 0, 0, 0.55556], + 84: [0, 0.68889, 0, 0, 0.66667], + 85: [0, 0.68889, 0, 0, 0.72222], + 86: [0, 0.68889, 0, 0, 0.72222], + 87: [0, 0.68889, 0, 0, 1], + 88: [0, 0.68889, 0, 0, 0.72222], + 89: [0, 0.68889, 0, 0, 0.72222], + 90: [0, 0.68889, 0, 0, 0.66667], + 107: [0, 0.68889, 0, 0, 0.55556], + 160: [0, 0, 0, 0, 0.25], + 165: [0, 0.675, 0.025, 0, 0.75], + 174: [0.15559, 0.69224, 0, 0, 0.94666], + 240: [0, 0.68889, 0, 0, 0.55556], + 295: [0, 0.68889, 0, 0, 0.54028], + 710: [0, 0.825, 0, 0, 2.33334], + 732: [0, 0.9, 0, 0, 2.33334], + 770: [0, 0.825, 0, 0, 2.33334], + 771: [0, 0.9, 0, 0, 2.33334], + 989: [0.08167, 0.58167, 0, 0, 0.77778], + 1008: [0, 0.43056, 0.04028, 0, 0.66667], + 8245: [0, 0.54986, 0, 0, 0.275], + 8463: [0, 0.68889, 0, 0, 0.54028], + 8487: [0, 0.68889, 0, 0, 0.72222], + 8498: [0, 0.68889, 0, 0, 0.55556], + 8502: [0, 0.68889, 0, 0, 0.66667], + 8503: [0, 0.68889, 0, 0, 0.44445], + 8504: [0, 0.68889, 0, 0, 0.66667], + 8513: [0, 0.68889, 0, 0, 0.63889], + 8592: [-0.03598, 0.46402, 0, 0, 0.5], + 8594: [-0.03598, 0.46402, 0, 0, 0.5], + 8602: [-0.13313, 0.36687, 0, 0, 1], + 8603: [-0.13313, 0.36687, 0, 0, 1], + 8606: [0.01354, 0.52239, 0, 0, 1], + 8608: [0.01354, 0.52239, 0, 0, 1], + 8610: [0.01354, 0.52239, 0, 0, 1.11111], + 8611: [0.01354, 0.52239, 0, 0, 1.11111], + 8619: [0, 0.54986, 0, 0, 1], + 8620: [0, 0.54986, 0, 0, 1], + 8621: [-0.13313, 0.37788, 0, 0, 1.38889], + 8622: [-0.13313, 0.36687, 0, 0, 1], + 8624: [0, 0.69224, 0, 0, 0.5], + 8625: [0, 0.69224, 0, 0, 0.5], + 8630: [0, 0.43056, 0, 0, 1], + 8631: [0, 0.43056, 0, 0, 1], + 8634: [0.08198, 0.58198, 0, 0, 0.77778], + 8635: [0.08198, 0.58198, 0, 0, 0.77778], + 8638: [0.19444, 0.69224, 0, 0, 0.41667], + 8639: [0.19444, 0.69224, 0, 0, 0.41667], + 8642: [0.19444, 0.69224, 0, 0, 0.41667], + 8643: [0.19444, 0.69224, 0, 0, 0.41667], + 8644: [0.1808, 0.675, 0, 0, 1], + 8646: [0.1808, 0.675, 0, 0, 1], + 8647: [0.1808, 0.675, 0, 0, 1], + 8648: [0.19444, 0.69224, 0, 0, 0.83334], + 8649: [0.1808, 0.675, 0, 0, 1], + 8650: [0.19444, 0.69224, 0, 0, 0.83334], + 8651: [0.01354, 0.52239, 0, 0, 1], + 8652: [0.01354, 0.52239, 0, 0, 1], + 8653: [-0.13313, 0.36687, 0, 0, 1], + 8654: [-0.13313, 0.36687, 0, 0, 1], + 8655: [-0.13313, 0.36687, 0, 0, 1], + 8666: [0.13667, 0.63667, 0, 0, 1], + 8667: [0.13667, 0.63667, 0, 0, 1], + 8669: [-0.13313, 0.37788, 0, 0, 1], + 8672: [-0.064, 0.437, 0, 0, 1.334], + 8674: [-0.064, 0.437, 0, 0, 1.334], + 8705: [0, 0.825, 0, 0, 0.5], + 8708: [0, 0.68889, 0, 0, 0.55556], + 8709: [0.08167, 0.58167, 0, 0, 0.77778], + 8717: [0, 0.43056, 0, 0, 0.42917], + 8722: [-0.03598, 0.46402, 0, 0, 0.5], + 8724: [0.08198, 0.69224, 0, 0, 0.77778], + 8726: [0.08167, 0.58167, 0, 0, 0.77778], + 8733: [0, 0.69224, 0, 0, 0.77778], + 8736: [0, 0.69224, 0, 0, 0.72222], + 8737: [0, 0.69224, 0, 0, 0.72222], + 8738: [0.03517, 0.52239, 0, 0, 0.72222], + 8739: [0.08167, 0.58167, 0, 0, 0.22222], + 8740: [0.25142, 0.74111, 0, 0, 0.27778], + 8741: [0.08167, 0.58167, 0, 0, 0.38889], + 8742: [0.25142, 0.74111, 0, 0, 0.5], + 8756: [0, 0.69224, 0, 0, 0.66667], + 8757: [0, 0.69224, 0, 0, 0.66667], + 8764: [-0.13313, 0.36687, 0, 0, 0.77778], + 8765: [-0.13313, 0.37788, 0, 0, 0.77778], + 8769: [-0.13313, 0.36687, 0, 0, 0.77778], + 8770: [-0.03625, 0.46375, 0, 0, 0.77778], + 8774: [0.30274, 0.79383, 0, 0, 0.77778], + 8776: [-0.01688, 0.48312, 0, 0, 0.77778], + 8778: [0.08167, 0.58167, 0, 0, 0.77778], + 8782: [0.06062, 0.54986, 0, 0, 0.77778], + 8783: [0.06062, 0.54986, 0, 0, 0.77778], + 8785: [0.08198, 0.58198, 0, 0, 0.77778], + 8786: [0.08198, 0.58198, 0, 0, 0.77778], + 8787: [0.08198, 0.58198, 0, 0, 0.77778], + 8790: [0, 0.69224, 0, 0, 0.77778], + 8791: [0.22958, 0.72958, 0, 0, 0.77778], + 8796: [0.08198, 0.91667, 0, 0, 0.77778], + 8806: [0.25583, 0.75583, 0, 0, 0.77778], + 8807: [0.25583, 0.75583, 0, 0, 0.77778], + 8808: [0.25142, 0.75726, 0, 0, 0.77778], + 8809: [0.25142, 0.75726, 0, 0, 0.77778], + 8812: [0.25583, 0.75583, 0, 0, 0.5], + 8814: [0.20576, 0.70576, 0, 0, 0.77778], + 8815: [0.20576, 0.70576, 0, 0, 0.77778], + 8816: [0.30274, 0.79383, 0, 0, 0.77778], + 8817: [0.30274, 0.79383, 0, 0, 0.77778], + 8818: [0.22958, 0.72958, 0, 0, 0.77778], + 8819: [0.22958, 0.72958, 0, 0, 0.77778], + 8822: [0.1808, 0.675, 0, 0, 0.77778], + 8823: [0.1808, 0.675, 0, 0, 0.77778], + 8828: [0.13667, 0.63667, 0, 0, 0.77778], + 8829: [0.13667, 0.63667, 0, 0, 0.77778], + 8830: [0.22958, 0.72958, 0, 0, 0.77778], + 8831: [0.22958, 0.72958, 0, 0, 0.77778], + 8832: [0.20576, 0.70576, 0, 0, 0.77778], + 8833: [0.20576, 0.70576, 0, 0, 0.77778], + 8840: [0.30274, 0.79383, 0, 0, 0.77778], + 8841: [0.30274, 0.79383, 0, 0, 0.77778], + 8842: [0.13597, 0.63597, 0, 0, 0.77778], + 8843: [0.13597, 0.63597, 0, 0, 0.77778], + 8847: [0.03517, 0.54986, 0, 0, 0.77778], + 8848: [0.03517, 0.54986, 0, 0, 0.77778], + 8858: [0.08198, 0.58198, 0, 0, 0.77778], + 8859: [0.08198, 0.58198, 0, 0, 0.77778], + 8861: [0.08198, 0.58198, 0, 0, 0.77778], + 8862: [0, 0.675, 0, 0, 0.77778], + 8863: [0, 0.675, 0, 0, 0.77778], + 8864: [0, 0.675, 0, 0, 0.77778], + 8865: [0, 0.675, 0, 0, 0.77778], + 8872: [0, 0.69224, 0, 0, 0.61111], + 8873: [0, 0.69224, 0, 0, 0.72222], + 8874: [0, 0.69224, 0, 0, 0.88889], + 8876: [0, 0.68889, 0, 0, 0.61111], + 8877: [0, 0.68889, 0, 0, 0.61111], + 8878: [0, 0.68889, 0, 0, 0.72222], + 8879: [0, 0.68889, 0, 0, 0.72222], + 8882: [0.03517, 0.54986, 0, 0, 0.77778], + 8883: [0.03517, 0.54986, 0, 0, 0.77778], + 8884: [0.13667, 0.63667, 0, 0, 0.77778], + 8885: [0.13667, 0.63667, 0, 0, 0.77778], + 8888: [0, 0.54986, 0, 0, 1.11111], + 8890: [0.19444, 0.43056, 0, 0, 0.55556], + 8891: [0.19444, 0.69224, 0, 0, 0.61111], + 8892: [0.19444, 0.69224, 0, 0, 0.61111], + 8901: [0, 0.54986, 0, 0, 0.27778], + 8903: [0.08167, 0.58167, 0, 0, 0.77778], + 8905: [0.08167, 0.58167, 0, 0, 0.77778], + 8906: [0.08167, 0.58167, 0, 0, 0.77778], + 8907: [0, 0.69224, 0, 0, 0.77778], + 8908: [0, 0.69224, 0, 0, 0.77778], + 8909: [-0.03598, 0.46402, 0, 0, 0.77778], + 8910: [0, 0.54986, 0, 0, 0.76042], + 8911: [0, 0.54986, 0, 0, 0.76042], + 8912: [0.03517, 0.54986, 0, 0, 0.77778], + 8913: [0.03517, 0.54986, 0, 0, 0.77778], + 8914: [0, 0.54986, 0, 0, 0.66667], + 8915: [0, 0.54986, 0, 0, 0.66667], + 8916: [0, 0.69224, 0, 0, 0.66667], + 8918: [0.0391, 0.5391, 0, 0, 0.77778], + 8919: [0.0391, 0.5391, 0, 0, 0.77778], + 8920: [0.03517, 0.54986, 0, 0, 1.33334], + 8921: [0.03517, 0.54986, 0, 0, 1.33334], + 8922: [0.38569, 0.88569, 0, 0, 0.77778], + 8923: [0.38569, 0.88569, 0, 0, 0.77778], + 8926: [0.13667, 0.63667, 0, 0, 0.77778], + 8927: [0.13667, 0.63667, 0, 0, 0.77778], + 8928: [0.30274, 0.79383, 0, 0, 0.77778], + 8929: [0.30274, 0.79383, 0, 0, 0.77778], + 8934: [0.23222, 0.74111, 0, 0, 0.77778], + 8935: [0.23222, 0.74111, 0, 0, 0.77778], + 8936: [0.23222, 0.74111, 0, 0, 0.77778], + 8937: [0.23222, 0.74111, 0, 0, 0.77778], + 8938: [0.20576, 0.70576, 0, 0, 0.77778], + 8939: [0.20576, 0.70576, 0, 0, 0.77778], + 8940: [0.30274, 0.79383, 0, 0, 0.77778], + 8941: [0.30274, 0.79383, 0, 0, 0.77778], + 8994: [0.19444, 0.69224, 0, 0, 0.77778], + 8995: [0.19444, 0.69224, 0, 0, 0.77778], + 9416: [0.15559, 0.69224, 0, 0, 0.90222], + 9484: [0, 0.69224, 0, 0, 0.5], + 9488: [0, 0.69224, 0, 0, 0.5], + 9492: [0, 0.37788, 0, 0, 0.5], + 9496: [0, 0.37788, 0, 0, 0.5], + 9585: [0.19444, 0.68889, 0, 0, 0.88889], + 9586: [0.19444, 0.74111, 0, 0, 0.88889], + 9632: [0, 0.675, 0, 0, 0.77778], + 9633: [0, 0.675, 0, 0, 0.77778], + 9650: [0, 0.54986, 0, 0, 0.72222], + 9651: [0, 0.54986, 0, 0, 0.72222], + 9654: [0.03517, 0.54986, 0, 0, 0.77778], + 9660: [0, 0.54986, 0, 0, 0.72222], + 9661: [0, 0.54986, 0, 0, 0.72222], + 9664: [0.03517, 0.54986, 0, 0, 0.77778], + 9674: [0.11111, 0.69224, 0, 0, 0.66667], + 9733: [0.19444, 0.69224, 0, 0, 0.94445], + 10003: [0, 0.69224, 0, 0, 0.83334], + 10016: [0, 0.69224, 0, 0, 0.83334], + 10731: [0.11111, 0.69224, 0, 0, 0.66667], + 10846: [0.19444, 0.75583, 0, 0, 0.61111], + 10877: [0.13667, 0.63667, 0, 0, 0.77778], + 10878: [0.13667, 0.63667, 0, 0, 0.77778], + 10885: [0.25583, 0.75583, 0, 0, 0.77778], + 10886: [0.25583, 0.75583, 0, 0, 0.77778], + 10887: [0.13597, 0.63597, 0, 0, 0.77778], + 10888: [0.13597, 0.63597, 0, 0, 0.77778], + 10889: [0.26167, 0.75726, 0, 0, 0.77778], + 10890: [0.26167, 0.75726, 0, 0, 0.77778], + 10891: [0.48256, 0.98256, 0, 0, 0.77778], + 10892: [0.48256, 0.98256, 0, 0, 0.77778], + 10901: [0.13667, 0.63667, 0, 0, 0.77778], + 10902: [0.13667, 0.63667, 0, 0, 0.77778], + 10933: [0.25142, 0.75726, 0, 0, 0.77778], + 10934: [0.25142, 0.75726, 0, 0, 0.77778], + 10935: [0.26167, 0.75726, 0, 0, 0.77778], + 10936: [0.26167, 0.75726, 0, 0, 0.77778], + 10937: [0.26167, 0.75726, 0, 0, 0.77778], + 10938: [0.26167, 0.75726, 0, 0, 0.77778], + 10949: [0.25583, 0.75583, 0, 0, 0.77778], + 10950: [0.25583, 0.75583, 0, 0, 0.77778], + 10955: [0.28481, 0.79383, 0, 0, 0.77778], + 10956: [0.28481, 0.79383, 0, 0, 0.77778], + 57350: [0.08167, 0.58167, 0, 0, 0.22222], + 57351: [0.08167, 0.58167, 0, 0, 0.38889], + 57352: [0.08167, 0.58167, 0, 0, 0.77778], + 57353: [0, 0.43056, 0.04028, 0, 0.66667], + 57356: [0.25142, 0.75726, 0, 0, 0.77778], + 57357: [0.25142, 0.75726, 0, 0, 0.77778], + 57358: [0.41951, 0.91951, 0, 0, 0.77778], + 57359: [0.30274, 0.79383, 0, 0, 0.77778], + 57360: [0.30274, 0.79383, 0, 0, 0.77778], + 57361: [0.41951, 0.91951, 0, 0, 0.77778], + 57366: [0.25142, 0.75726, 0, 0, 0.77778], + 57367: [0.25142, 0.75726, 0, 0, 0.77778], + 57368: [0.25142, 0.75726, 0, 0, 0.77778], + 57369: [0.25142, 0.75726, 0, 0, 0.77778], + 57370: [0.13597, 0.63597, 0, 0, 0.77778], + 57371: [0.13597, 0.63597, 0, 0, 0.77778], + }, + 'Caligraphic-Regular': { + 32: [0, 0, 0, 0, 0.25], + 65: [0, 0.68333, 0, 0.19445, 0.79847], + 66: [0, 0.68333, 0.03041, 0.13889, 0.65681], + 67: [0, 0.68333, 0.05834, 0.13889, 0.52653], + 68: [0, 0.68333, 0.02778, 0.08334, 0.77139], + 69: [0, 0.68333, 0.08944, 0.11111, 0.52778], + 70: [0, 0.68333, 0.09931, 0.11111, 0.71875], + 71: [0.09722, 0.68333, 0.0593, 0.11111, 0.59487], + 72: [0, 0.68333, 0.00965, 0.11111, 0.84452], + 73: [0, 0.68333, 0.07382, 0, 0.54452], + 74: [0.09722, 0.68333, 0.18472, 0.16667, 0.67778], + 75: [0, 0.68333, 0.01445, 0.05556, 0.76195], + 76: [0, 0.68333, 0, 0.13889, 0.68972], + 77: [0, 0.68333, 0, 0.13889, 1.2009], + 78: [0, 0.68333, 0.14736, 0.08334, 0.82049], + 79: [0, 0.68333, 0.02778, 0.11111, 0.79611], + 80: [0, 0.68333, 0.08222, 0.08334, 0.69556], + 81: [0.09722, 0.68333, 0, 0.11111, 0.81667], + 82: [0, 0.68333, 0, 0.08334, 0.8475], + 83: [0, 0.68333, 0.075, 0.13889, 0.60556], + 84: [0, 0.68333, 0.25417, 0, 0.54464], + 85: [0, 0.68333, 0.09931, 0.08334, 0.62583], + 86: [0, 0.68333, 0.08222, 0, 0.61278], + 87: [0, 0.68333, 0.08222, 0.08334, 0.98778], + 88: [0, 0.68333, 0.14643, 0.13889, 0.7133], + 89: [0.09722, 0.68333, 0.08222, 0.08334, 0.66834], + 90: [0, 0.68333, 0.07944, 0.13889, 0.72473], + 160: [0, 0, 0, 0, 0.25], + }, + 'Fraktur-Regular': { + 32: [0, 0, 0, 0, 0.25], + 33: [0, 0.69141, 0, 0, 0.29574], + 34: [0, 0.69141, 0, 0, 0.21471], + 38: [0, 0.69141, 0, 0, 0.73786], + 39: [0, 0.69141, 0, 0, 0.21201], + 40: [0.24982, 0.74947, 0, 0, 0.38865], + 41: [0.24982, 0.74947, 0, 0, 0.38865], + 42: [0, 0.62119, 0, 0, 0.27764], + 43: [0.08319, 0.58283, 0, 0, 0.75623], + 44: [0, 0.10803, 0, 0, 0.27764], + 45: [0.08319, 0.58283, 0, 0, 0.75623], + 46: [0, 0.10803, 0, 0, 0.27764], + 47: [0.24982, 0.74947, 0, 0, 0.50181], + 48: [0, 0.47534, 0, 0, 0.50181], + 49: [0, 0.47534, 0, 0, 0.50181], + 50: [0, 0.47534, 0, 0, 0.50181], + 51: [0.18906, 0.47534, 0, 0, 0.50181], + 52: [0.18906, 0.47534, 0, 0, 0.50181], + 53: [0.18906, 0.47534, 0, 0, 0.50181], + 54: [0, 0.69141, 0, 0, 0.50181], + 55: [0.18906, 0.47534, 0, 0, 0.50181], + 56: [0, 0.69141, 0, 0, 0.50181], + 57: [0.18906, 0.47534, 0, 0, 0.50181], + 58: [0, 0.47534, 0, 0, 0.21606], + 59: [0.12604, 0.47534, 0, 0, 0.21606], + 61: [-0.13099, 0.36866, 0, 0, 0.75623], + 63: [0, 0.69141, 0, 0, 0.36245], + 65: [0, 0.69141, 0, 0, 0.7176], + 66: [0, 0.69141, 0, 0, 0.88397], + 67: [0, 0.69141, 0, 0, 0.61254], + 68: [0, 0.69141, 0, 0, 0.83158], + 69: [0, 0.69141, 0, 0, 0.66278], + 70: [0.12604, 0.69141, 0, 0, 0.61119], + 71: [0, 0.69141, 0, 0, 0.78539], + 72: [0.06302, 0.69141, 0, 0, 0.7203], + 73: [0, 0.69141, 0, 0, 0.55448], + 74: [0.12604, 0.69141, 0, 0, 0.55231], + 75: [0, 0.69141, 0, 0, 0.66845], + 76: [0, 0.69141, 0, 0, 0.66602], + 77: [0, 0.69141, 0, 0, 1.04953], + 78: [0, 0.69141, 0, 0, 0.83212], + 79: [0, 0.69141, 0, 0, 0.82699], + 80: [0.18906, 0.69141, 0, 0, 0.82753], + 81: [0.03781, 0.69141, 0, 0, 0.82699], + 82: [0, 0.69141, 0, 0, 0.82807], + 83: [0, 0.69141, 0, 0, 0.82861], + 84: [0, 0.69141, 0, 0, 0.66899], + 85: [0, 0.69141, 0, 0, 0.64576], + 86: [0, 0.69141, 0, 0, 0.83131], + 87: [0, 0.69141, 0, 0, 1.04602], + 88: [0, 0.69141, 0, 0, 0.71922], + 89: [0.18906, 0.69141, 0, 0, 0.83293], + 90: [0.12604, 0.69141, 0, 0, 0.60201], + 91: [0.24982, 0.74947, 0, 0, 0.27764], + 93: [0.24982, 0.74947, 0, 0, 0.27764], + 94: [0, 0.69141, 0, 0, 0.49965], + 97: [0, 0.47534, 0, 0, 0.50046], + 98: [0, 0.69141, 0, 0, 0.51315], + 99: [0, 0.47534, 0, 0, 0.38946], + 100: [0, 0.62119, 0, 0, 0.49857], + 101: [0, 0.47534, 0, 0, 0.40053], + 102: [0.18906, 0.69141, 0, 0, 0.32626], + 103: [0.18906, 0.47534, 0, 0, 0.5037], + 104: [0.18906, 0.69141, 0, 0, 0.52126], + 105: [0, 0.69141, 0, 0, 0.27899], + 106: [0, 0.69141, 0, 0, 0.28088], + 107: [0, 0.69141, 0, 0, 0.38946], + 108: [0, 0.69141, 0, 0, 0.27953], + 109: [0, 0.47534, 0, 0, 0.76676], + 110: [0, 0.47534, 0, 0, 0.52666], + 111: [0, 0.47534, 0, 0, 0.48885], + 112: [0.18906, 0.52396, 0, 0, 0.50046], + 113: [0.18906, 0.47534, 0, 0, 0.48912], + 114: [0, 0.47534, 0, 0, 0.38919], + 115: [0, 0.47534, 0, 0, 0.44266], + 116: [0, 0.62119, 0, 0, 0.33301], + 117: [0, 0.47534, 0, 0, 0.5172], + 118: [0, 0.52396, 0, 0, 0.5118], + 119: [0, 0.52396, 0, 0, 0.77351], + 120: [0.18906, 0.47534, 0, 0, 0.38865], + 121: [0.18906, 0.47534, 0, 0, 0.49884], + 122: [0.18906, 0.47534, 0, 0, 0.39054], + 160: [0, 0, 0, 0, 0.25], + 8216: [0, 0.69141, 0, 0, 0.21471], + 8217: [0, 0.69141, 0, 0, 0.21471], + 58112: [0, 0.62119, 0, 0, 0.49749], + 58113: [0, 0.62119, 0, 0, 0.4983], + 58114: [0.18906, 0.69141, 0, 0, 0.33328], + 58115: [0.18906, 0.69141, 0, 0, 0.32923], + 58116: [0.18906, 0.47534, 0, 0, 0.50343], + 58117: [0, 0.69141, 0, 0, 0.33301], + 58118: [0, 0.62119, 0, 0, 0.33409], + 58119: [0, 0.47534, 0, 0, 0.50073], + }, + 'Main-Bold': { + 32: [0, 0, 0, 0, 0.25], + 33: [0, 0.69444, 0, 0, 0.35], + 34: [0, 0.69444, 0, 0, 0.60278], + 35: [0.19444, 0.69444, 0, 0, 0.95833], + 36: [0.05556, 0.75, 0, 0, 0.575], + 37: [0.05556, 0.75, 0, 0, 0.95833], + 38: [0, 0.69444, 0, 0, 0.89444], + 39: [0, 0.69444, 0, 0, 0.31944], + 40: [0.25, 0.75, 0, 0, 0.44722], + 41: [0.25, 0.75, 0, 0, 0.44722], + 42: [0, 0.75, 0, 0, 0.575], + 43: [0.13333, 0.63333, 0, 0, 0.89444], + 44: [0.19444, 0.15556, 0, 0, 0.31944], + 45: [0, 0.44444, 0, 0, 0.38333], + 46: [0, 0.15556, 0, 0, 0.31944], + 47: [0.25, 0.75, 0, 0, 0.575], + 48: [0, 0.64444, 0, 0, 0.575], + 49: [0, 0.64444, 0, 0, 0.575], + 50: [0, 0.64444, 0, 0, 0.575], + 51: [0, 0.64444, 0, 0, 0.575], + 52: [0, 0.64444, 0, 0, 0.575], + 53: [0, 0.64444, 0, 0, 0.575], + 54: [0, 0.64444, 0, 0, 0.575], + 55: [0, 0.64444, 0, 0, 0.575], + 56: [0, 0.64444, 0, 0, 0.575], + 57: [0, 0.64444, 0, 0, 0.575], + 58: [0, 0.44444, 0, 0, 0.31944], + 59: [0.19444, 0.44444, 0, 0, 0.31944], + 60: [0.08556, 0.58556, 0, 0, 0.89444], + 61: [-0.10889, 0.39111, 0, 0, 0.89444], + 62: [0.08556, 0.58556, 0, 0, 0.89444], + 63: [0, 0.69444, 0, 0, 0.54305], + 64: [0, 0.69444, 0, 0, 0.89444], + 65: [0, 0.68611, 0, 0, 0.86944], + 66: [0, 0.68611, 0, 0, 0.81805], + 67: [0, 0.68611, 0, 0, 0.83055], + 68: [0, 0.68611, 0, 0, 0.88194], + 69: [0, 0.68611, 0, 0, 0.75555], + 70: [0, 0.68611, 0, 0, 0.72361], + 71: [0, 0.68611, 0, 0, 0.90416], + 72: [0, 0.68611, 0, 0, 0.9], + 73: [0, 0.68611, 0, 0, 0.43611], + 74: [0, 0.68611, 0, 0, 0.59444], + 75: [0, 0.68611, 0, 0, 0.90138], + 76: [0, 0.68611, 0, 0, 0.69166], + 77: [0, 0.68611, 0, 0, 1.09166], + 78: [0, 0.68611, 0, 0, 0.9], + 79: [0, 0.68611, 0, 0, 0.86388], + 80: [0, 0.68611, 0, 0, 0.78611], + 81: [0.19444, 0.68611, 0, 0, 0.86388], + 82: [0, 0.68611, 0, 0, 0.8625], + 83: [0, 0.68611, 0, 0, 0.63889], + 84: [0, 0.68611, 0, 0, 0.8], + 85: [0, 0.68611, 0, 0, 0.88472], + 86: [0, 0.68611, 0.01597, 0, 0.86944], + 87: [0, 0.68611, 0.01597, 0, 1.18888], + 88: [0, 0.68611, 0, 0, 0.86944], + 89: [0, 0.68611, 0.02875, 0, 0.86944], + 90: [0, 0.68611, 0, 0, 0.70277], + 91: [0.25, 0.75, 0, 0, 0.31944], + 92: [0.25, 0.75, 0, 0, 0.575], + 93: [0.25, 0.75, 0, 0, 0.31944], + 94: [0, 0.69444, 0, 0, 0.575], + 95: [0.31, 0.13444, 0.03194, 0, 0.575], + 97: [0, 0.44444, 0, 0, 0.55902], + 98: [0, 0.69444, 0, 0, 0.63889], + 99: [0, 0.44444, 0, 0, 0.51111], + 100: [0, 0.69444, 0, 0, 0.63889], + 101: [0, 0.44444, 0, 0, 0.52708], + 102: [0, 0.69444, 0.10903, 0, 0.35139], + 103: [0.19444, 0.44444, 0.01597, 0, 0.575], + 104: [0, 0.69444, 0, 0, 0.63889], + 105: [0, 0.69444, 0, 0, 0.31944], + 106: [0.19444, 0.69444, 0, 0, 0.35139], + 107: [0, 0.69444, 0, 0, 0.60694], + 108: [0, 0.69444, 0, 0, 0.31944], + 109: [0, 0.44444, 0, 0, 0.95833], + 110: [0, 0.44444, 0, 0, 0.63889], + 111: [0, 0.44444, 0, 0, 0.575], + 112: [0.19444, 0.44444, 0, 0, 0.63889], + 113: [0.19444, 0.44444, 0, 0, 0.60694], + 114: [0, 0.44444, 0, 0, 0.47361], + 115: [0, 0.44444, 0, 0, 0.45361], + 116: [0, 0.63492, 0, 0, 0.44722], + 117: [0, 0.44444, 0, 0, 0.63889], + 118: [0, 0.44444, 0.01597, 0, 0.60694], + 119: [0, 0.44444, 0.01597, 0, 0.83055], + 120: [0, 0.44444, 0, 0, 0.60694], + 121: [0.19444, 0.44444, 0.01597, 0, 0.60694], + 122: [0, 0.44444, 0, 0, 0.51111], + 123: [0.25, 0.75, 0, 0, 0.575], + 124: [0.25, 0.75, 0, 0, 0.31944], + 125: [0.25, 0.75, 0, 0, 0.575], + 126: [0.35, 0.34444, 0, 0, 0.575], + 160: [0, 0, 0, 0, 0.25], + 163: [0, 0.69444, 0, 0, 0.86853], + 168: [0, 0.69444, 0, 0, 0.575], + 172: [0, 0.44444, 0, 0, 0.76666], + 176: [0, 0.69444, 0, 0, 0.86944], + 177: [0.13333, 0.63333, 0, 0, 0.89444], + 184: [0.17014, 0, 0, 0, 0.51111], + 198: [0, 0.68611, 0, 0, 1.04166], + 215: [0.13333, 0.63333, 0, 0, 0.89444], + 216: [0.04861, 0.73472, 0, 0, 0.89444], + 223: [0, 0.69444, 0, 0, 0.59722], + 230: [0, 0.44444, 0, 0, 0.83055], + 247: [0.13333, 0.63333, 0, 0, 0.89444], + 248: [0.09722, 0.54167, 0, 0, 0.575], + 305: [0, 0.44444, 0, 0, 0.31944], + 338: [0, 0.68611, 0, 0, 1.16944], + 339: [0, 0.44444, 0, 0, 0.89444], + 567: [0.19444, 0.44444, 0, 0, 0.35139], + 710: [0, 0.69444, 0, 0, 0.575], + 711: [0, 0.63194, 0, 0, 0.575], + 713: [0, 0.59611, 0, 0, 0.575], + 714: [0, 0.69444, 0, 0, 0.575], + 715: [0, 0.69444, 0, 0, 0.575], + 728: [0, 0.69444, 0, 0, 0.575], + 729: [0, 0.69444, 0, 0, 0.31944], + 730: [0, 0.69444, 0, 0, 0.86944], + 732: [0, 0.69444, 0, 0, 0.575], + 733: [0, 0.69444, 0, 0, 0.575], + 915: [0, 0.68611, 0, 0, 0.69166], + 916: [0, 0.68611, 0, 0, 0.95833], + 920: [0, 0.68611, 0, 0, 0.89444], + 923: [0, 0.68611, 0, 0, 0.80555], + 926: [0, 0.68611, 0, 0, 0.76666], + 928: [0, 0.68611, 0, 0, 0.9], + 931: [0, 0.68611, 0, 0, 0.83055], + 933: [0, 0.68611, 0, 0, 0.89444], + 934: [0, 0.68611, 0, 0, 0.83055], + 936: [0, 0.68611, 0, 0, 0.89444], + 937: [0, 0.68611, 0, 0, 0.83055], + 8211: [0, 0.44444, 0.03194, 0, 0.575], + 8212: [0, 0.44444, 0.03194, 0, 1.14999], + 8216: [0, 0.69444, 0, 0, 0.31944], + 8217: [0, 0.69444, 0, 0, 0.31944], + 8220: [0, 0.69444, 0, 0, 0.60278], + 8221: [0, 0.69444, 0, 0, 0.60278], + 8224: [0.19444, 0.69444, 0, 0, 0.51111], + 8225: [0.19444, 0.69444, 0, 0, 0.51111], + 8242: [0, 0.55556, 0, 0, 0.34444], + 8407: [0, 0.72444, 0.15486, 0, 0.575], + 8463: [0, 0.69444, 0, 0, 0.66759], + 8465: [0, 0.69444, 0, 0, 0.83055], + 8467: [0, 0.69444, 0, 0, 0.47361], + 8472: [0.19444, 0.44444, 0, 0, 0.74027], + 8476: [0, 0.69444, 0, 0, 0.83055], + 8501: [0, 0.69444, 0, 0, 0.70277], + 8592: [-0.10889, 0.39111, 0, 0, 1.14999], + 8593: [0.19444, 0.69444, 0, 0, 0.575], + 8594: [-0.10889, 0.39111, 0, 0, 1.14999], + 8595: [0.19444, 0.69444, 0, 0, 0.575], + 8596: [-0.10889, 0.39111, 0, 0, 1.14999], + 8597: [0.25, 0.75, 0, 0, 0.575], + 8598: [0.19444, 0.69444, 0, 0, 1.14999], + 8599: [0.19444, 0.69444, 0, 0, 1.14999], + 8600: [0.19444, 0.69444, 0, 0, 1.14999], + 8601: [0.19444, 0.69444, 0, 0, 1.14999], + 8636: [-0.10889, 0.39111, 0, 0, 1.14999], + 8637: [-0.10889, 0.39111, 0, 0, 1.14999], + 8640: [-0.10889, 0.39111, 0, 0, 1.14999], + 8641: [-0.10889, 0.39111, 0, 0, 1.14999], + 8656: [-0.10889, 0.39111, 0, 0, 1.14999], + 8657: [0.19444, 0.69444, 0, 0, 0.70277], + 8658: [-0.10889, 0.39111, 0, 0, 1.14999], + 8659: [0.19444, 0.69444, 0, 0, 0.70277], + 8660: [-0.10889, 0.39111, 0, 0, 1.14999], + 8661: [0.25, 0.75, 0, 0, 0.70277], + 8704: [0, 0.69444, 0, 0, 0.63889], + 8706: [0, 0.69444, 0.06389, 0, 0.62847], + 8707: [0, 0.69444, 0, 0, 0.63889], + 8709: [0.05556, 0.75, 0, 0, 0.575], + 8711: [0, 0.68611, 0, 0, 0.95833], + 8712: [0.08556, 0.58556, 0, 0, 0.76666], + 8715: [0.08556, 0.58556, 0, 0, 0.76666], + 8722: [0.13333, 0.63333, 0, 0, 0.89444], + 8723: [0.13333, 0.63333, 0, 0, 0.89444], + 8725: [0.25, 0.75, 0, 0, 0.575], + 8726: [0.25, 0.75, 0, 0, 0.575], + 8727: [-0.02778, 0.47222, 0, 0, 0.575], + 8728: [-0.02639, 0.47361, 0, 0, 0.575], + 8729: [-0.02639, 0.47361, 0, 0, 0.575], + 8730: [0.18, 0.82, 0, 0, 0.95833], + 8733: [0, 0.44444, 0, 0, 0.89444], + 8734: [0, 0.44444, 0, 0, 1.14999], + 8736: [0, 0.69224, 0, 0, 0.72222], + 8739: [0.25, 0.75, 0, 0, 0.31944], + 8741: [0.25, 0.75, 0, 0, 0.575], + 8743: [0, 0.55556, 0, 0, 0.76666], + 8744: [0, 0.55556, 0, 0, 0.76666], + 8745: [0, 0.55556, 0, 0, 0.76666], + 8746: [0, 0.55556, 0, 0, 0.76666], + 8747: [0.19444, 0.69444, 0.12778, 0, 0.56875], + 8764: [-0.10889, 0.39111, 0, 0, 0.89444], + 8768: [0.19444, 0.69444, 0, 0, 0.31944], + 8771: [0.00222, 0.50222, 0, 0, 0.89444], + 8776: [0.02444, 0.52444, 0, 0, 0.89444], + 8781: [0.00222, 0.50222, 0, 0, 0.89444], + 8801: [0.00222, 0.50222, 0, 0, 0.89444], + 8804: [0.19667, 0.69667, 0, 0, 0.89444], + 8805: [0.19667, 0.69667, 0, 0, 0.89444], + 8810: [0.08556, 0.58556, 0, 0, 1.14999], + 8811: [0.08556, 0.58556, 0, 0, 1.14999], + 8826: [0.08556, 0.58556, 0, 0, 0.89444], + 8827: [0.08556, 0.58556, 0, 0, 0.89444], + 8834: [0.08556, 0.58556, 0, 0, 0.89444], + 8835: [0.08556, 0.58556, 0, 0, 0.89444], + 8838: [0.19667, 0.69667, 0, 0, 0.89444], + 8839: [0.19667, 0.69667, 0, 0, 0.89444], + 8846: [0, 0.55556, 0, 0, 0.76666], + 8849: [0.19667, 0.69667, 0, 0, 0.89444], + 8850: [0.19667, 0.69667, 0, 0, 0.89444], + 8851: [0, 0.55556, 0, 0, 0.76666], + 8852: [0, 0.55556, 0, 0, 0.76666], + 8853: [0.13333, 0.63333, 0, 0, 0.89444], + 8854: [0.13333, 0.63333, 0, 0, 0.89444], + 8855: [0.13333, 0.63333, 0, 0, 0.89444], + 8856: [0.13333, 0.63333, 0, 0, 0.89444], + 8857: [0.13333, 0.63333, 0, 0, 0.89444], + 8866: [0, 0.69444, 0, 0, 0.70277], + 8867: [0, 0.69444, 0, 0, 0.70277], + 8868: [0, 0.69444, 0, 0, 0.89444], + 8869: [0, 0.69444, 0, 0, 0.89444], + 8900: [-0.02639, 0.47361, 0, 0, 0.575], + 8901: [-0.02639, 0.47361, 0, 0, 0.31944], + 8902: [-0.02778, 0.47222, 0, 0, 0.575], + 8968: [0.25, 0.75, 0, 0, 0.51111], + 8969: [0.25, 0.75, 0, 0, 0.51111], + 8970: [0.25, 0.75, 0, 0, 0.51111], + 8971: [0.25, 0.75, 0, 0, 0.51111], + 8994: [-0.13889, 0.36111, 0, 0, 1.14999], + 8995: [-0.13889, 0.36111, 0, 0, 1.14999], + 9651: [0.19444, 0.69444, 0, 0, 1.02222], + 9657: [-0.02778, 0.47222, 0, 0, 0.575], + 9661: [0.19444, 0.69444, 0, 0, 1.02222], + 9667: [-0.02778, 0.47222, 0, 0, 0.575], + 9711: [0.19444, 0.69444, 0, 0, 1.14999], + 9824: [0.12963, 0.69444, 0, 0, 0.89444], + 9825: [0.12963, 0.69444, 0, 0, 0.89444], + 9826: [0.12963, 0.69444, 0, 0, 0.89444], + 9827: [0.12963, 0.69444, 0, 0, 0.89444], + 9837: [0, 0.75, 0, 0, 0.44722], + 9838: [0.19444, 0.69444, 0, 0, 0.44722], + 9839: [0.19444, 0.69444, 0, 0, 0.44722], + 10216: [0.25, 0.75, 0, 0, 0.44722], + 10217: [0.25, 0.75, 0, 0, 0.44722], + 10815: [0, 0.68611, 0, 0, 0.9], + 10927: [0.19667, 0.69667, 0, 0, 0.89444], + 10928: [0.19667, 0.69667, 0, 0, 0.89444], + 57376: [0.19444, 0.69444, 0, 0, 0], + }, + 'Main-BoldItalic': { + 32: [0, 0, 0, 0, 0.25], + 33: [0, 0.69444, 0.11417, 0, 0.38611], + 34: [0, 0.69444, 0.07939, 0, 0.62055], + 35: [0.19444, 0.69444, 0.06833, 0, 0.94444], + 37: [0.05556, 0.75, 0.12861, 0, 0.94444], + 38: [0, 0.69444, 0.08528, 0, 0.88555], + 39: [0, 0.69444, 0.12945, 0, 0.35555], + 40: [0.25, 0.75, 0.15806, 0, 0.47333], + 41: [0.25, 0.75, 0.03306, 0, 0.47333], + 42: [0, 0.75, 0.14333, 0, 0.59111], + 43: [0.10333, 0.60333, 0.03306, 0, 0.88555], + 44: [0.19444, 0.14722, 0, 0, 0.35555], + 45: [0, 0.44444, 0.02611, 0, 0.41444], + 46: [0, 0.14722, 0, 0, 0.35555], + 47: [0.25, 0.75, 0.15806, 0, 0.59111], + 48: [0, 0.64444, 0.13167, 0, 0.59111], + 49: [0, 0.64444, 0.13167, 0, 0.59111], + 50: [0, 0.64444, 0.13167, 0, 0.59111], + 51: [0, 0.64444, 0.13167, 0, 0.59111], + 52: [0.19444, 0.64444, 0.13167, 0, 0.59111], + 53: [0, 0.64444, 0.13167, 0, 0.59111], + 54: [0, 0.64444, 0.13167, 0, 0.59111], + 55: [0.19444, 0.64444, 0.13167, 0, 0.59111], + 56: [0, 0.64444, 0.13167, 0, 0.59111], + 57: [0, 0.64444, 0.13167, 0, 0.59111], + 58: [0, 0.44444, 0.06695, 0, 0.35555], + 59: [0.19444, 0.44444, 0.06695, 0, 0.35555], + 61: [-0.10889, 0.39111, 0.06833, 0, 0.88555], + 63: [0, 0.69444, 0.11472, 0, 0.59111], + 64: [0, 0.69444, 0.09208, 0, 0.88555], + 65: [0, 0.68611, 0, 0, 0.86555], + 66: [0, 0.68611, 0.0992, 0, 0.81666], + 67: [0, 0.68611, 0.14208, 0, 0.82666], + 68: [0, 0.68611, 0.09062, 0, 0.87555], + 69: [0, 0.68611, 0.11431, 0, 0.75666], + 70: [0, 0.68611, 0.12903, 0, 0.72722], + 71: [0, 0.68611, 0.07347, 0, 0.89527], + 72: [0, 0.68611, 0.17208, 0, 0.8961], + 73: [0, 0.68611, 0.15681, 0, 0.47166], + 74: [0, 0.68611, 0.145, 0, 0.61055], + 75: [0, 0.68611, 0.14208, 0, 0.89499], + 76: [0, 0.68611, 0, 0, 0.69777], + 77: [0, 0.68611, 0.17208, 0, 1.07277], + 78: [0, 0.68611, 0.17208, 0, 0.8961], + 79: [0, 0.68611, 0.09062, 0, 0.85499], + 80: [0, 0.68611, 0.0992, 0, 0.78721], + 81: [0.19444, 0.68611, 0.09062, 0, 0.85499], + 82: [0, 0.68611, 0.02559, 0, 0.85944], + 83: [0, 0.68611, 0.11264, 0, 0.64999], + 84: [0, 0.68611, 0.12903, 0, 0.7961], + 85: [0, 0.68611, 0.17208, 0, 0.88083], + 86: [0, 0.68611, 0.18625, 0, 0.86555], + 87: [0, 0.68611, 0.18625, 0, 1.15999], + 88: [0, 0.68611, 0.15681, 0, 0.86555], + 89: [0, 0.68611, 0.19803, 0, 0.86555], + 90: [0, 0.68611, 0.14208, 0, 0.70888], + 91: [0.25, 0.75, 0.1875, 0, 0.35611], + 93: [0.25, 0.75, 0.09972, 0, 0.35611], + 94: [0, 0.69444, 0.06709, 0, 0.59111], + 95: [0.31, 0.13444, 0.09811, 0, 0.59111], + 97: [0, 0.44444, 0.09426, 0, 0.59111], + 98: [0, 0.69444, 0.07861, 0, 0.53222], + 99: [0, 0.44444, 0.05222, 0, 0.53222], + 100: [0, 0.69444, 0.10861, 0, 0.59111], + 101: [0, 0.44444, 0.085, 0, 0.53222], + 102: [0.19444, 0.69444, 0.21778, 0, 0.4], + 103: [0.19444, 0.44444, 0.105, 0, 0.53222], + 104: [0, 0.69444, 0.09426, 0, 0.59111], + 105: [0, 0.69326, 0.11387, 0, 0.35555], + 106: [0.19444, 0.69326, 0.1672, 0, 0.35555], + 107: [0, 0.69444, 0.11111, 0, 0.53222], + 108: [0, 0.69444, 0.10861, 0, 0.29666], + 109: [0, 0.44444, 0.09426, 0, 0.94444], + 110: [0, 0.44444, 0.09426, 0, 0.64999], + 111: [0, 0.44444, 0.07861, 0, 0.59111], + 112: [0.19444, 0.44444, 0.07861, 0, 0.59111], + 113: [0.19444, 0.44444, 0.105, 0, 0.53222], + 114: [0, 0.44444, 0.11111, 0, 0.50167], + 115: [0, 0.44444, 0.08167, 0, 0.48694], + 116: [0, 0.63492, 0.09639, 0, 0.385], + 117: [0, 0.44444, 0.09426, 0, 0.62055], + 118: [0, 0.44444, 0.11111, 0, 0.53222], + 119: [0, 0.44444, 0.11111, 0, 0.76777], + 120: [0, 0.44444, 0.12583, 0, 0.56055], + 121: [0.19444, 0.44444, 0.105, 0, 0.56166], + 122: [0, 0.44444, 0.13889, 0, 0.49055], + 126: [0.35, 0.34444, 0.11472, 0, 0.59111], + 160: [0, 0, 0, 0, 0.25], + 168: [0, 0.69444, 0.11473, 0, 0.59111], + 176: [0, 0.69444, 0, 0, 0.94888], + 184: [0.17014, 0, 0, 0, 0.53222], + 198: [0, 0.68611, 0.11431, 0, 1.02277], + 216: [0.04861, 0.73472, 0.09062, 0, 0.88555], + 223: [0.19444, 0.69444, 0.09736, 0, 0.665], + 230: [0, 0.44444, 0.085, 0, 0.82666], + 248: [0.09722, 0.54167, 0.09458, 0, 0.59111], + 305: [0, 0.44444, 0.09426, 0, 0.35555], + 338: [0, 0.68611, 0.11431, 0, 1.14054], + 339: [0, 0.44444, 0.085, 0, 0.82666], + 567: [0.19444, 0.44444, 0.04611, 0, 0.385], + 710: [0, 0.69444, 0.06709, 0, 0.59111], + 711: [0, 0.63194, 0.08271, 0, 0.59111], + 713: [0, 0.59444, 0.10444, 0, 0.59111], + 714: [0, 0.69444, 0.08528, 0, 0.59111], + 715: [0, 0.69444, 0, 0, 0.59111], + 728: [0, 0.69444, 0.10333, 0, 0.59111], + 729: [0, 0.69444, 0.12945, 0, 0.35555], + 730: [0, 0.69444, 0, 0, 0.94888], + 732: [0, 0.69444, 0.11472, 0, 0.59111], + 733: [0, 0.69444, 0.11472, 0, 0.59111], + 915: [0, 0.68611, 0.12903, 0, 0.69777], + 916: [0, 0.68611, 0, 0, 0.94444], + 920: [0, 0.68611, 0.09062, 0, 0.88555], + 923: [0, 0.68611, 0, 0, 0.80666], + 926: [0, 0.68611, 0.15092, 0, 0.76777], + 928: [0, 0.68611, 0.17208, 0, 0.8961], + 931: [0, 0.68611, 0.11431, 0, 0.82666], + 933: [0, 0.68611, 0.10778, 0, 0.88555], + 934: [0, 0.68611, 0.05632, 0, 0.82666], + 936: [0, 0.68611, 0.10778, 0, 0.88555], + 937: [0, 0.68611, 0.0992, 0, 0.82666], + 8211: [0, 0.44444, 0.09811, 0, 0.59111], + 8212: [0, 0.44444, 0.09811, 0, 1.18221], + 8216: [0, 0.69444, 0.12945, 0, 0.35555], + 8217: [0, 0.69444, 0.12945, 0, 0.35555], + 8220: [0, 0.69444, 0.16772, 0, 0.62055], + 8221: [0, 0.69444, 0.07939, 0, 0.62055], + }, + 'Main-Italic': { + 32: [0, 0, 0, 0, 0.25], + 33: [0, 0.69444, 0.12417, 0, 0.30667], + 34: [0, 0.69444, 0.06961, 0, 0.51444], + 35: [0.19444, 0.69444, 0.06616, 0, 0.81777], + 37: [0.05556, 0.75, 0.13639, 0, 0.81777], + 38: [0, 0.69444, 0.09694, 0, 0.76666], + 39: [0, 0.69444, 0.12417, 0, 0.30667], + 40: [0.25, 0.75, 0.16194, 0, 0.40889], + 41: [0.25, 0.75, 0.03694, 0, 0.40889], + 42: [0, 0.75, 0.14917, 0, 0.51111], + 43: [0.05667, 0.56167, 0.03694, 0, 0.76666], + 44: [0.19444, 0.10556, 0, 0, 0.30667], + 45: [0, 0.43056, 0.02826, 0, 0.35778], + 46: [0, 0.10556, 0, 0, 0.30667], + 47: [0.25, 0.75, 0.16194, 0, 0.51111], + 48: [0, 0.64444, 0.13556, 0, 0.51111], + 49: [0, 0.64444, 0.13556, 0, 0.51111], + 50: [0, 0.64444, 0.13556, 0, 0.51111], + 51: [0, 0.64444, 0.13556, 0, 0.51111], + 52: [0.19444, 0.64444, 0.13556, 0, 0.51111], + 53: [0, 0.64444, 0.13556, 0, 0.51111], + 54: [0, 0.64444, 0.13556, 0, 0.51111], + 55: [0.19444, 0.64444, 0.13556, 0, 0.51111], + 56: [0, 0.64444, 0.13556, 0, 0.51111], + 57: [0, 0.64444, 0.13556, 0, 0.51111], + 58: [0, 0.43056, 0.0582, 0, 0.30667], + 59: [0.19444, 0.43056, 0.0582, 0, 0.30667], + 61: [-0.13313, 0.36687, 0.06616, 0, 0.76666], + 63: [0, 0.69444, 0.1225, 0, 0.51111], + 64: [0, 0.69444, 0.09597, 0, 0.76666], + 65: [0, 0.68333, 0, 0, 0.74333], + 66: [0, 0.68333, 0.10257, 0, 0.70389], + 67: [0, 0.68333, 0.14528, 0, 0.71555], + 68: [0, 0.68333, 0.09403, 0, 0.755], + 69: [0, 0.68333, 0.12028, 0, 0.67833], + 70: [0, 0.68333, 0.13305, 0, 0.65277], + 71: [0, 0.68333, 0.08722, 0, 0.77361], + 72: [0, 0.68333, 0.16389, 0, 0.74333], + 73: [0, 0.68333, 0.15806, 0, 0.38555], + 74: [0, 0.68333, 0.14028, 0, 0.525], + 75: [0, 0.68333, 0.14528, 0, 0.76888], + 76: [0, 0.68333, 0, 0, 0.62722], + 77: [0, 0.68333, 0.16389, 0, 0.89666], + 78: [0, 0.68333, 0.16389, 0, 0.74333], + 79: [0, 0.68333, 0.09403, 0, 0.76666], + 80: [0, 0.68333, 0.10257, 0, 0.67833], + 81: [0.19444, 0.68333, 0.09403, 0, 0.76666], + 82: [0, 0.68333, 0.03868, 0, 0.72944], + 83: [0, 0.68333, 0.11972, 0, 0.56222], + 84: [0, 0.68333, 0.13305, 0, 0.71555], + 85: [0, 0.68333, 0.16389, 0, 0.74333], + 86: [0, 0.68333, 0.18361, 0, 0.74333], + 87: [0, 0.68333, 0.18361, 0, 0.99888], + 88: [0, 0.68333, 0.15806, 0, 0.74333], + 89: [0, 0.68333, 0.19383, 0, 0.74333], + 90: [0, 0.68333, 0.14528, 0, 0.61333], + 91: [0.25, 0.75, 0.1875, 0, 0.30667], + 93: [0.25, 0.75, 0.10528, 0, 0.30667], + 94: [0, 0.69444, 0.06646, 0, 0.51111], + 95: [0.31, 0.12056, 0.09208, 0, 0.51111], + 97: [0, 0.43056, 0.07671, 0, 0.51111], + 98: [0, 0.69444, 0.06312, 0, 0.46], + 99: [0, 0.43056, 0.05653, 0, 0.46], + 100: [0, 0.69444, 0.10333, 0, 0.51111], + 101: [0, 0.43056, 0.07514, 0, 0.46], + 102: [0.19444, 0.69444, 0.21194, 0, 0.30667], + 103: [0.19444, 0.43056, 0.08847, 0, 0.46], + 104: [0, 0.69444, 0.07671, 0, 0.51111], + 105: [0, 0.65536, 0.1019, 0, 0.30667], + 106: [0.19444, 0.65536, 0.14467, 0, 0.30667], + 107: [0, 0.69444, 0.10764, 0, 0.46], + 108: [0, 0.69444, 0.10333, 0, 0.25555], + 109: [0, 0.43056, 0.07671, 0, 0.81777], + 110: [0, 0.43056, 0.07671, 0, 0.56222], + 111: [0, 0.43056, 0.06312, 0, 0.51111], + 112: [0.19444, 0.43056, 0.06312, 0, 0.51111], + 113: [0.19444, 0.43056, 0.08847, 0, 0.46], + 114: [0, 0.43056, 0.10764, 0, 0.42166], + 115: [0, 0.43056, 0.08208, 0, 0.40889], + 116: [0, 0.61508, 0.09486, 0, 0.33222], + 117: [0, 0.43056, 0.07671, 0, 0.53666], + 118: [0, 0.43056, 0.10764, 0, 0.46], + 119: [0, 0.43056, 0.10764, 0, 0.66444], + 120: [0, 0.43056, 0.12042, 0, 0.46389], + 121: [0.19444, 0.43056, 0.08847, 0, 0.48555], + 122: [0, 0.43056, 0.12292, 0, 0.40889], + 126: [0.35, 0.31786, 0.11585, 0, 0.51111], + 160: [0, 0, 0, 0, 0.25], + 168: [0, 0.66786, 0.10474, 0, 0.51111], + 176: [0, 0.69444, 0, 0, 0.83129], + 184: [0.17014, 0, 0, 0, 0.46], + 198: [0, 0.68333, 0.12028, 0, 0.88277], + 216: [0.04861, 0.73194, 0.09403, 0, 0.76666], + 223: [0.19444, 0.69444, 0.10514, 0, 0.53666], + 230: [0, 0.43056, 0.07514, 0, 0.71555], + 248: [0.09722, 0.52778, 0.09194, 0, 0.51111], + 338: [0, 0.68333, 0.12028, 0, 0.98499], + 339: [0, 0.43056, 0.07514, 0, 0.71555], + 710: [0, 0.69444, 0.06646, 0, 0.51111], + 711: [0, 0.62847, 0.08295, 0, 0.51111], + 713: [0, 0.56167, 0.10333, 0, 0.51111], + 714: [0, 0.69444, 0.09694, 0, 0.51111], + 715: [0, 0.69444, 0, 0, 0.51111], + 728: [0, 0.69444, 0.10806, 0, 0.51111], + 729: [0, 0.66786, 0.11752, 0, 0.30667], + 730: [0, 0.69444, 0, 0, 0.83129], + 732: [0, 0.66786, 0.11585, 0, 0.51111], + 733: [0, 0.69444, 0.1225, 0, 0.51111], + 915: [0, 0.68333, 0.13305, 0, 0.62722], + 916: [0, 0.68333, 0, 0, 0.81777], + 920: [0, 0.68333, 0.09403, 0, 0.76666], + 923: [0, 0.68333, 0, 0, 0.69222], + 926: [0, 0.68333, 0.15294, 0, 0.66444], + 928: [0, 0.68333, 0.16389, 0, 0.74333], + 931: [0, 0.68333, 0.12028, 0, 0.71555], + 933: [0, 0.68333, 0.11111, 0, 0.76666], + 934: [0, 0.68333, 0.05986, 0, 0.71555], + 936: [0, 0.68333, 0.11111, 0, 0.76666], + 937: [0, 0.68333, 0.10257, 0, 0.71555], + 8211: [0, 0.43056, 0.09208, 0, 0.51111], + 8212: [0, 0.43056, 0.09208, 0, 1.02222], + 8216: [0, 0.69444, 0.12417, 0, 0.30667], + 8217: [0, 0.69444, 0.12417, 0, 0.30667], + 8220: [0, 0.69444, 0.1685, 0, 0.51444], + 8221: [0, 0.69444, 0.06961, 0, 0.51444], + 8463: [0, 0.68889, 0, 0, 0.54028], + }, + 'Main-Regular': { + 32: [0, 0, 0, 0, 0.25], + 33: [0, 0.69444, 0, 0, 0.27778], + 34: [0, 0.69444, 0, 0, 0.5], + 35: [0.19444, 0.69444, 0, 0, 0.83334], + 36: [0.05556, 0.75, 0, 0, 0.5], + 37: [0.05556, 0.75, 0, 0, 0.83334], + 38: [0, 0.69444, 0, 0, 0.77778], + 39: [0, 0.69444, 0, 0, 0.27778], + 40: [0.25, 0.75, 0, 0, 0.38889], + 41: [0.25, 0.75, 0, 0, 0.38889], + 42: [0, 0.75, 0, 0, 0.5], + 43: [0.08333, 0.58333, 0, 0, 0.77778], + 44: [0.19444, 0.10556, 0, 0, 0.27778], + 45: [0, 0.43056, 0, 0, 0.33333], + 46: [0, 0.10556, 0, 0, 0.27778], + 47: [0.25, 0.75, 0, 0, 0.5], + 48: [0, 0.64444, 0, 0, 0.5], + 49: [0, 0.64444, 0, 0, 0.5], + 50: [0, 0.64444, 0, 0, 0.5], + 51: [0, 0.64444, 0, 0, 0.5], + 52: [0, 0.64444, 0, 0, 0.5], + 53: [0, 0.64444, 0, 0, 0.5], + 54: [0, 0.64444, 0, 0, 0.5], + 55: [0, 0.64444, 0, 0, 0.5], + 56: [0, 0.64444, 0, 0, 0.5], + 57: [0, 0.64444, 0, 0, 0.5], + 58: [0, 0.43056, 0, 0, 0.27778], + 59: [0.19444, 0.43056, 0, 0, 0.27778], + 60: [0.0391, 0.5391, 0, 0, 0.77778], + 61: [-0.13313, 0.36687, 0, 0, 0.77778], + 62: [0.0391, 0.5391, 0, 0, 0.77778], + 63: [0, 0.69444, 0, 0, 0.47222], + 64: [0, 0.69444, 0, 0, 0.77778], + 65: [0, 0.68333, 0, 0, 0.75], + 66: [0, 0.68333, 0, 0, 0.70834], + 67: [0, 0.68333, 0, 0, 0.72222], + 68: [0, 0.68333, 0, 0, 0.76389], + 69: [0, 0.68333, 0, 0, 0.68056], + 70: [0, 0.68333, 0, 0, 0.65278], + 71: [0, 0.68333, 0, 0, 0.78472], + 72: [0, 0.68333, 0, 0, 0.75], + 73: [0, 0.68333, 0, 0, 0.36111], + 74: [0, 0.68333, 0, 0, 0.51389], + 75: [0, 0.68333, 0, 0, 0.77778], + 76: [0, 0.68333, 0, 0, 0.625], + 77: [0, 0.68333, 0, 0, 0.91667], + 78: [0, 0.68333, 0, 0, 0.75], + 79: [0, 0.68333, 0, 0, 0.77778], + 80: [0, 0.68333, 0, 0, 0.68056], + 81: [0.19444, 0.68333, 0, 0, 0.77778], + 82: [0, 0.68333, 0, 0, 0.73611], + 83: [0, 0.68333, 0, 0, 0.55556], + 84: [0, 0.68333, 0, 0, 0.72222], + 85: [0, 0.68333, 0, 0, 0.75], + 86: [0, 0.68333, 0.01389, 0, 0.75], + 87: [0, 0.68333, 0.01389, 0, 1.02778], + 88: [0, 0.68333, 0, 0, 0.75], + 89: [0, 0.68333, 0.025, 0, 0.75], + 90: [0, 0.68333, 0, 0, 0.61111], + 91: [0.25, 0.75, 0, 0, 0.27778], + 92: [0.25, 0.75, 0, 0, 0.5], + 93: [0.25, 0.75, 0, 0, 0.27778], + 94: [0, 0.69444, 0, 0, 0.5], + 95: [0.31, 0.12056, 0.02778, 0, 0.5], + 97: [0, 0.43056, 0, 0, 0.5], + 98: [0, 0.69444, 0, 0, 0.55556], + 99: [0, 0.43056, 0, 0, 0.44445], + 100: [0, 0.69444, 0, 0, 0.55556], + 101: [0, 0.43056, 0, 0, 0.44445], + 102: [0, 0.69444, 0.07778, 0, 0.30556], + 103: [0.19444, 0.43056, 0.01389, 0, 0.5], + 104: [0, 0.69444, 0, 0, 0.55556], + 105: [0, 0.66786, 0, 0, 0.27778], + 106: [0.19444, 0.66786, 0, 0, 0.30556], + 107: [0, 0.69444, 0, 0, 0.52778], + 108: [0, 0.69444, 0, 0, 0.27778], + 109: [0, 0.43056, 0, 0, 0.83334], + 110: [0, 0.43056, 0, 0, 0.55556], + 111: [0, 0.43056, 0, 0, 0.5], + 112: [0.19444, 0.43056, 0, 0, 0.55556], + 113: [0.19444, 0.43056, 0, 0, 0.52778], + 114: [0, 0.43056, 0, 0, 0.39167], + 115: [0, 0.43056, 0, 0, 0.39445], + 116: [0, 0.61508, 0, 0, 0.38889], + 117: [0, 0.43056, 0, 0, 0.55556], + 118: [0, 0.43056, 0.01389, 0, 0.52778], + 119: [0, 0.43056, 0.01389, 0, 0.72222], + 120: [0, 0.43056, 0, 0, 0.52778], + 121: [0.19444, 0.43056, 0.01389, 0, 0.52778], + 122: [0, 0.43056, 0, 0, 0.44445], + 123: [0.25, 0.75, 0, 0, 0.5], + 124: [0.25, 0.75, 0, 0, 0.27778], + 125: [0.25, 0.75, 0, 0, 0.5], + 126: [0.35, 0.31786, 0, 0, 0.5], + 160: [0, 0, 0, 0, 0.25], + 163: [0, 0.69444, 0, 0, 0.76909], + 167: [0.19444, 0.69444, 0, 0, 0.44445], + 168: [0, 0.66786, 0, 0, 0.5], + 172: [0, 0.43056, 0, 0, 0.66667], + 176: [0, 0.69444, 0, 0, 0.75], + 177: [0.08333, 0.58333, 0, 0, 0.77778], + 182: [0.19444, 0.69444, 0, 0, 0.61111], + 184: [0.17014, 0, 0, 0, 0.44445], + 198: [0, 0.68333, 0, 0, 0.90278], + 215: [0.08333, 0.58333, 0, 0, 0.77778], + 216: [0.04861, 0.73194, 0, 0, 0.77778], + 223: [0, 0.69444, 0, 0, 0.5], + 230: [0, 0.43056, 0, 0, 0.72222], + 247: [0.08333, 0.58333, 0, 0, 0.77778], + 248: [0.09722, 0.52778, 0, 0, 0.5], + 305: [0, 0.43056, 0, 0, 0.27778], + 338: [0, 0.68333, 0, 0, 1.01389], + 339: [0, 0.43056, 0, 0, 0.77778], + 567: [0.19444, 0.43056, 0, 0, 0.30556], + 710: [0, 0.69444, 0, 0, 0.5], + 711: [0, 0.62847, 0, 0, 0.5], + 713: [0, 0.56778, 0, 0, 0.5], + 714: [0, 0.69444, 0, 0, 0.5], + 715: [0, 0.69444, 0, 0, 0.5], + 728: [0, 0.69444, 0, 0, 0.5], + 729: [0, 0.66786, 0, 0, 0.27778], + 730: [0, 0.69444, 0, 0, 0.75], + 732: [0, 0.66786, 0, 0, 0.5], + 733: [0, 0.69444, 0, 0, 0.5], + 915: [0, 0.68333, 0, 0, 0.625], + 916: [0, 0.68333, 0, 0, 0.83334], + 920: [0, 0.68333, 0, 0, 0.77778], + 923: [0, 0.68333, 0, 0, 0.69445], + 926: [0, 0.68333, 0, 0, 0.66667], + 928: [0, 0.68333, 0, 0, 0.75], + 931: [0, 0.68333, 0, 0, 0.72222], + 933: [0, 0.68333, 0, 0, 0.77778], + 934: [0, 0.68333, 0, 0, 0.72222], + 936: [0, 0.68333, 0, 0, 0.77778], + 937: [0, 0.68333, 0, 0, 0.72222], + 8211: [0, 0.43056, 0.02778, 0, 0.5], + 8212: [0, 0.43056, 0.02778, 0, 1], + 8216: [0, 0.69444, 0, 0, 0.27778], + 8217: [0, 0.69444, 0, 0, 0.27778], + 8220: [0, 0.69444, 0, 0, 0.5], + 8221: [0, 0.69444, 0, 0, 0.5], + 8224: [0.19444, 0.69444, 0, 0, 0.44445], + 8225: [0.19444, 0.69444, 0, 0, 0.44445], + 8230: [0, 0.12, 0, 0, 1.172], + 8242: [0, 0.55556, 0, 0, 0.275], + 8407: [0, 0.71444, 0.15382, 0, 0.5], + 8463: [0, 0.68889, 0, 0, 0.54028], + 8465: [0, 0.69444, 0, 0, 0.72222], + 8467: [0, 0.69444, 0, 0.11111, 0.41667], + 8472: [0.19444, 0.43056, 0, 0.11111, 0.63646], + 8476: [0, 0.69444, 0, 0, 0.72222], + 8501: [0, 0.69444, 0, 0, 0.61111], + 8592: [-0.13313, 0.36687, 0, 0, 1], + 8593: [0.19444, 0.69444, 0, 0, 0.5], + 8594: [-0.13313, 0.36687, 0, 0, 1], + 8595: [0.19444, 0.69444, 0, 0, 0.5], + 8596: [-0.13313, 0.36687, 0, 0, 1], + 8597: [0.25, 0.75, 0, 0, 0.5], + 8598: [0.19444, 0.69444, 0, 0, 1], + 8599: [0.19444, 0.69444, 0, 0, 1], + 8600: [0.19444, 0.69444, 0, 0, 1], + 8601: [0.19444, 0.69444, 0, 0, 1], + 8614: [0.011, 0.511, 0, 0, 1], + 8617: [0.011, 0.511, 0, 0, 1.126], + 8618: [0.011, 0.511, 0, 0, 1.126], + 8636: [-0.13313, 0.36687, 0, 0, 1], + 8637: [-0.13313, 0.36687, 0, 0, 1], + 8640: [-0.13313, 0.36687, 0, 0, 1], + 8641: [-0.13313, 0.36687, 0, 0, 1], + 8652: [0.011, 0.671, 0, 0, 1], + 8656: [-0.13313, 0.36687, 0, 0, 1], + 8657: [0.19444, 0.69444, 0, 0, 0.61111], + 8658: [-0.13313, 0.36687, 0, 0, 1], + 8659: [0.19444, 0.69444, 0, 0, 0.61111], + 8660: [-0.13313, 0.36687, 0, 0, 1], + 8661: [0.25, 0.75, 0, 0, 0.61111], + 8704: [0, 0.69444, 0, 0, 0.55556], + 8706: [0, 0.69444, 0.05556, 0.08334, 0.5309], + 8707: [0, 0.69444, 0, 0, 0.55556], + 8709: [0.05556, 0.75, 0, 0, 0.5], + 8711: [0, 0.68333, 0, 0, 0.83334], + 8712: [0.0391, 0.5391, 0, 0, 0.66667], + 8715: [0.0391, 0.5391, 0, 0, 0.66667], + 8722: [0.08333, 0.58333, 0, 0, 0.77778], + 8723: [0.08333, 0.58333, 0, 0, 0.77778], + 8725: [0.25, 0.75, 0, 0, 0.5], + 8726: [0.25, 0.75, 0, 0, 0.5], + 8727: [-0.03472, 0.46528, 0, 0, 0.5], + 8728: [-0.05555, 0.44445, 0, 0, 0.5], + 8729: [-0.05555, 0.44445, 0, 0, 0.5], + 8730: [0.2, 0.8, 0, 0, 0.83334], + 8733: [0, 0.43056, 0, 0, 0.77778], + 8734: [0, 0.43056, 0, 0, 1], + 8736: [0, 0.69224, 0, 0, 0.72222], + 8739: [0.25, 0.75, 0, 0, 0.27778], + 8741: [0.25, 0.75, 0, 0, 0.5], + 8743: [0, 0.55556, 0, 0, 0.66667], + 8744: [0, 0.55556, 0, 0, 0.66667], + 8745: [0, 0.55556, 0, 0, 0.66667], + 8746: [0, 0.55556, 0, 0, 0.66667], + 8747: [0.19444, 0.69444, 0.11111, 0, 0.41667], + 8764: [-0.13313, 0.36687, 0, 0, 0.77778], + 8768: [0.19444, 0.69444, 0, 0, 0.27778], + 8771: [-0.03625, 0.46375, 0, 0, 0.77778], + 8773: [-0.022, 0.589, 0, 0, 1], + 8776: [-0.01688, 0.48312, 0, 0, 0.77778], + 8781: [-0.03625, 0.46375, 0, 0, 0.77778], + 8784: [-0.133, 0.67, 0, 0, 0.778], + 8801: [-0.03625, 0.46375, 0, 0, 0.77778], + 8804: [0.13597, 0.63597, 0, 0, 0.77778], + 8805: [0.13597, 0.63597, 0, 0, 0.77778], + 8810: [0.0391, 0.5391, 0, 0, 1], + 8811: [0.0391, 0.5391, 0, 0, 1], + 8826: [0.0391, 0.5391, 0, 0, 0.77778], + 8827: [0.0391, 0.5391, 0, 0, 0.77778], + 8834: [0.0391, 0.5391, 0, 0, 0.77778], + 8835: [0.0391, 0.5391, 0, 0, 0.77778], + 8838: [0.13597, 0.63597, 0, 0, 0.77778], + 8839: [0.13597, 0.63597, 0, 0, 0.77778], + 8846: [0, 0.55556, 0, 0, 0.66667], + 8849: [0.13597, 0.63597, 0, 0, 0.77778], + 8850: [0.13597, 0.63597, 0, 0, 0.77778], + 8851: [0, 0.55556, 0, 0, 0.66667], + 8852: [0, 0.55556, 0, 0, 0.66667], + 8853: [0.08333, 0.58333, 0, 0, 0.77778], + 8854: [0.08333, 0.58333, 0, 0, 0.77778], + 8855: [0.08333, 0.58333, 0, 0, 0.77778], + 8856: [0.08333, 0.58333, 0, 0, 0.77778], + 8857: [0.08333, 0.58333, 0, 0, 0.77778], + 8866: [0, 0.69444, 0, 0, 0.61111], + 8867: [0, 0.69444, 0, 0, 0.61111], + 8868: [0, 0.69444, 0, 0, 0.77778], + 8869: [0, 0.69444, 0, 0, 0.77778], + 8872: [0.249, 0.75, 0, 0, 0.867], + 8900: [-0.05555, 0.44445, 0, 0, 0.5], + 8901: [-0.05555, 0.44445, 0, 0, 0.27778], + 8902: [-0.03472, 0.46528, 0, 0, 0.5], + 8904: [0.005, 0.505, 0, 0, 0.9], + 8942: [0.03, 0.9, 0, 0, 0.278], + 8943: [-0.19, 0.31, 0, 0, 1.172], + 8945: [-0.1, 0.82, 0, 0, 1.282], + 8968: [0.25, 0.75, 0, 0, 0.44445], + 8969: [0.25, 0.75, 0, 0, 0.44445], + 8970: [0.25, 0.75, 0, 0, 0.44445], + 8971: [0.25, 0.75, 0, 0, 0.44445], + 8994: [-0.14236, 0.35764, 0, 0, 1], + 8995: [-0.14236, 0.35764, 0, 0, 1], + 9136: [0.244, 0.744, 0, 0, 0.412], + 9137: [0.244, 0.744, 0, 0, 0.412], + 9651: [0.19444, 0.69444, 0, 0, 0.88889], + 9657: [-0.03472, 0.46528, 0, 0, 0.5], + 9661: [0.19444, 0.69444, 0, 0, 0.88889], + 9667: [-0.03472, 0.46528, 0, 0, 0.5], + 9711: [0.19444, 0.69444, 0, 0, 1], + 9824: [0.12963, 0.69444, 0, 0, 0.77778], + 9825: [0.12963, 0.69444, 0, 0, 0.77778], + 9826: [0.12963, 0.69444, 0, 0, 0.77778], + 9827: [0.12963, 0.69444, 0, 0, 0.77778], + 9837: [0, 0.75, 0, 0, 0.38889], + 9838: [0.19444, 0.69444, 0, 0, 0.38889], + 9839: [0.19444, 0.69444, 0, 0, 0.38889], + 10216: [0.25, 0.75, 0, 0, 0.38889], + 10217: [0.25, 0.75, 0, 0, 0.38889], + 10222: [0.244, 0.744, 0, 0, 0.412], + 10223: [0.244, 0.744, 0, 0, 0.412], + 10229: [0.011, 0.511, 0, 0, 1.609], + 10230: [0.011, 0.511, 0, 0, 1.638], + 10231: [0.011, 0.511, 0, 0, 1.859], + 10232: [0.024, 0.525, 0, 0, 1.609], + 10233: [0.024, 0.525, 0, 0, 1.638], + 10234: [0.024, 0.525, 0, 0, 1.858], + 10236: [0.011, 0.511, 0, 0, 1.638], + 10815: [0, 0.68333, 0, 0, 0.75], + 10927: [0.13597, 0.63597, 0, 0, 0.77778], + 10928: [0.13597, 0.63597, 0, 0, 0.77778], + 57376: [0.19444, 0.69444, 0, 0, 0], + }, + 'Math-BoldItalic': { + 32: [0, 0, 0, 0, 0.25], + 48: [0, 0.44444, 0, 0, 0.575], + 49: [0, 0.44444, 0, 0, 0.575], + 50: [0, 0.44444, 0, 0, 0.575], + 51: [0.19444, 0.44444, 0, 0, 0.575], + 52: [0.19444, 0.44444, 0, 0, 0.575], + 53: [0.19444, 0.44444, 0, 0, 0.575], + 54: [0, 0.64444, 0, 0, 0.575], + 55: [0.19444, 0.44444, 0, 0, 0.575], + 56: [0, 0.64444, 0, 0, 0.575], + 57: [0.19444, 0.44444, 0, 0, 0.575], + 65: [0, 0.68611, 0, 0, 0.86944], + 66: [0, 0.68611, 0.04835, 0, 0.8664], + 67: [0, 0.68611, 0.06979, 0, 0.81694], + 68: [0, 0.68611, 0.03194, 0, 0.93812], + 69: [0, 0.68611, 0.05451, 0, 0.81007], + 70: [0, 0.68611, 0.15972, 0, 0.68889], + 71: [0, 0.68611, 0, 0, 0.88673], + 72: [0, 0.68611, 0.08229, 0, 0.98229], + 73: [0, 0.68611, 0.07778, 0, 0.51111], + 74: [0, 0.68611, 0.10069, 0, 0.63125], + 75: [0, 0.68611, 0.06979, 0, 0.97118], + 76: [0, 0.68611, 0, 0, 0.75555], + 77: [0, 0.68611, 0.11424, 0, 1.14201], + 78: [0, 0.68611, 0.11424, 0, 0.95034], + 79: [0, 0.68611, 0.03194, 0, 0.83666], + 80: [0, 0.68611, 0.15972, 0, 0.72309], + 81: [0.19444, 0.68611, 0, 0, 0.86861], + 82: [0, 0.68611, 0.00421, 0, 0.87235], + 83: [0, 0.68611, 0.05382, 0, 0.69271], + 84: [0, 0.68611, 0.15972, 0, 0.63663], + 85: [0, 0.68611, 0.11424, 0, 0.80027], + 86: [0, 0.68611, 0.25555, 0, 0.67778], + 87: [0, 0.68611, 0.15972, 0, 1.09305], + 88: [0, 0.68611, 0.07778, 0, 0.94722], + 89: [0, 0.68611, 0.25555, 0, 0.67458], + 90: [0, 0.68611, 0.06979, 0, 0.77257], + 97: [0, 0.44444, 0, 0, 0.63287], + 98: [0, 0.69444, 0, 0, 0.52083], + 99: [0, 0.44444, 0, 0, 0.51342], + 100: [0, 0.69444, 0, 0, 0.60972], + 101: [0, 0.44444, 0, 0, 0.55361], + 102: [0.19444, 0.69444, 0.11042, 0, 0.56806], + 103: [0.19444, 0.44444, 0.03704, 0, 0.5449], + 104: [0, 0.69444, 0, 0, 0.66759], + 105: [0, 0.69326, 0, 0, 0.4048], + 106: [0.19444, 0.69326, 0.0622, 0, 0.47083], + 107: [0, 0.69444, 0.01852, 0, 0.6037], + 108: [0, 0.69444, 0.0088, 0, 0.34815], + 109: [0, 0.44444, 0, 0, 1.0324], + 110: [0, 0.44444, 0, 0, 0.71296], + 111: [0, 0.44444, 0, 0, 0.58472], + 112: [0.19444, 0.44444, 0, 0, 0.60092], + 113: [0.19444, 0.44444, 0.03704, 0, 0.54213], + 114: [0, 0.44444, 0.03194, 0, 0.5287], + 115: [0, 0.44444, 0, 0, 0.53125], + 116: [0, 0.63492, 0, 0, 0.41528], + 117: [0, 0.44444, 0, 0, 0.68102], + 118: [0, 0.44444, 0.03704, 0, 0.56666], + 119: [0, 0.44444, 0.02778, 0, 0.83148], + 120: [0, 0.44444, 0, 0, 0.65903], + 121: [0.19444, 0.44444, 0.03704, 0, 0.59028], + 122: [0, 0.44444, 0.04213, 0, 0.55509], + 160: [0, 0, 0, 0, 0.25], + 915: [0, 0.68611, 0.15972, 0, 0.65694], + 916: [0, 0.68611, 0, 0, 0.95833], + 920: [0, 0.68611, 0.03194, 0, 0.86722], + 923: [0, 0.68611, 0, 0, 0.80555], + 926: [0, 0.68611, 0.07458, 0, 0.84125], + 928: [0, 0.68611, 0.08229, 0, 0.98229], + 931: [0, 0.68611, 0.05451, 0, 0.88507], + 933: [0, 0.68611, 0.15972, 0, 0.67083], + 934: [0, 0.68611, 0, 0, 0.76666], + 936: [0, 0.68611, 0.11653, 0, 0.71402], + 937: [0, 0.68611, 0.04835, 0, 0.8789], + 945: [0, 0.44444, 0, 0, 0.76064], + 946: [0.19444, 0.69444, 0.03403, 0, 0.65972], + 947: [0.19444, 0.44444, 0.06389, 0, 0.59003], + 948: [0, 0.69444, 0.03819, 0, 0.52222], + 949: [0, 0.44444, 0, 0, 0.52882], + 950: [0.19444, 0.69444, 0.06215, 0, 0.50833], + 951: [0.19444, 0.44444, 0.03704, 0, 0.6], + 952: [0, 0.69444, 0.03194, 0, 0.5618], + 953: [0, 0.44444, 0, 0, 0.41204], + 954: [0, 0.44444, 0, 0, 0.66759], + 955: [0, 0.69444, 0, 0, 0.67083], + 956: [0.19444, 0.44444, 0, 0, 0.70787], + 957: [0, 0.44444, 0.06898, 0, 0.57685], + 958: [0.19444, 0.69444, 0.03021, 0, 0.50833], + 959: [0, 0.44444, 0, 0, 0.58472], + 960: [0, 0.44444, 0.03704, 0, 0.68241], + 961: [0.19444, 0.44444, 0, 0, 0.6118], + 962: [0.09722, 0.44444, 0.07917, 0, 0.42361], + 963: [0, 0.44444, 0.03704, 0, 0.68588], + 964: [0, 0.44444, 0.13472, 0, 0.52083], + 965: [0, 0.44444, 0.03704, 0, 0.63055], + 966: [0.19444, 0.44444, 0, 0, 0.74722], + 967: [0.19444, 0.44444, 0, 0, 0.71805], + 968: [0.19444, 0.69444, 0.03704, 0, 0.75833], + 969: [0, 0.44444, 0.03704, 0, 0.71782], + 977: [0, 0.69444, 0, 0, 0.69155], + 981: [0.19444, 0.69444, 0, 0, 0.7125], + 982: [0, 0.44444, 0.03194, 0, 0.975], + 1009: [0.19444, 0.44444, 0, 0, 0.6118], + 1013: [0, 0.44444, 0, 0, 0.48333], + 57649: [0, 0.44444, 0, 0, 0.39352], + 57911: [0.19444, 0.44444, 0, 0, 0.43889], + }, + 'Math-Italic': { + 32: [0, 0, 0, 0, 0.25], + 48: [0, 0.43056, 0, 0, 0.5], + 49: [0, 0.43056, 0, 0, 0.5], + 50: [0, 0.43056, 0, 0, 0.5], + 51: [0.19444, 0.43056, 0, 0, 0.5], + 52: [0.19444, 0.43056, 0, 0, 0.5], + 53: [0.19444, 0.43056, 0, 0, 0.5], + 54: [0, 0.64444, 0, 0, 0.5], + 55: [0.19444, 0.43056, 0, 0, 0.5], + 56: [0, 0.64444, 0, 0, 0.5], + 57: [0.19444, 0.43056, 0, 0, 0.5], + 65: [0, 0.68333, 0, 0.13889, 0.75], + 66: [0, 0.68333, 0.05017, 0.08334, 0.75851], + 67: [0, 0.68333, 0.07153, 0.08334, 0.71472], + 68: [0, 0.68333, 0.02778, 0.05556, 0.82792], + 69: [0, 0.68333, 0.05764, 0.08334, 0.7382], + 70: [0, 0.68333, 0.13889, 0.08334, 0.64306], + 71: [0, 0.68333, 0, 0.08334, 0.78625], + 72: [0, 0.68333, 0.08125, 0.05556, 0.83125], + 73: [0, 0.68333, 0.07847, 0.11111, 0.43958], + 74: [0, 0.68333, 0.09618, 0.16667, 0.55451], + 75: [0, 0.68333, 0.07153, 0.05556, 0.84931], + 76: [0, 0.68333, 0, 0.02778, 0.68056], + 77: [0, 0.68333, 0.10903, 0.08334, 0.97014], + 78: [0, 0.68333, 0.10903, 0.08334, 0.80347], + 79: [0, 0.68333, 0.02778, 0.08334, 0.76278], + 80: [0, 0.68333, 0.13889, 0.08334, 0.64201], + 81: [0.19444, 0.68333, 0, 0.08334, 0.79056], + 82: [0, 0.68333, 0.00773, 0.08334, 0.75929], + 83: [0, 0.68333, 0.05764, 0.08334, 0.6132], + 84: [0, 0.68333, 0.13889, 0.08334, 0.58438], + 85: [0, 0.68333, 0.10903, 0.02778, 0.68278], + 86: [0, 0.68333, 0.22222, 0, 0.58333], + 87: [0, 0.68333, 0.13889, 0, 0.94445], + 88: [0, 0.68333, 0.07847, 0.08334, 0.82847], + 89: [0, 0.68333, 0.22222, 0, 0.58056], + 90: [0, 0.68333, 0.07153, 0.08334, 0.68264], + 97: [0, 0.43056, 0, 0, 0.52859], + 98: [0, 0.69444, 0, 0, 0.42917], + 99: [0, 0.43056, 0, 0.05556, 0.43276], + 100: [0, 0.69444, 0, 0.16667, 0.52049], + 101: [0, 0.43056, 0, 0.05556, 0.46563], + 102: [0.19444, 0.69444, 0.10764, 0.16667, 0.48959], + 103: [0.19444, 0.43056, 0.03588, 0.02778, 0.47697], + 104: [0, 0.69444, 0, 0, 0.57616], + 105: [0, 0.65952, 0, 0, 0.34451], + 106: [0.19444, 0.65952, 0.05724, 0, 0.41181], + 107: [0, 0.69444, 0.03148, 0, 0.5206], + 108: [0, 0.69444, 0.01968, 0.08334, 0.29838], + 109: [0, 0.43056, 0, 0, 0.87801], + 110: [0, 0.43056, 0, 0, 0.60023], + 111: [0, 0.43056, 0, 0.05556, 0.48472], + 112: [0.19444, 0.43056, 0, 0.08334, 0.50313], + 113: [0.19444, 0.43056, 0.03588, 0.08334, 0.44641], + 114: [0, 0.43056, 0.02778, 0.05556, 0.45116], + 115: [0, 0.43056, 0, 0.05556, 0.46875], + 116: [0, 0.61508, 0, 0.08334, 0.36111], + 117: [0, 0.43056, 0, 0.02778, 0.57246], + 118: [0, 0.43056, 0.03588, 0.02778, 0.48472], + 119: [0, 0.43056, 0.02691, 0.08334, 0.71592], + 120: [0, 0.43056, 0, 0.02778, 0.57153], + 121: [0.19444, 0.43056, 0.03588, 0.05556, 0.49028], + 122: [0, 0.43056, 0.04398, 0.05556, 0.46505], + 160: [0, 0, 0, 0, 0.25], + 915: [0, 0.68333, 0.13889, 0.08334, 0.61528], + 916: [0, 0.68333, 0, 0.16667, 0.83334], + 920: [0, 0.68333, 0.02778, 0.08334, 0.76278], + 923: [0, 0.68333, 0, 0.16667, 0.69445], + 926: [0, 0.68333, 0.07569, 0.08334, 0.74236], + 928: [0, 0.68333, 0.08125, 0.05556, 0.83125], + 931: [0, 0.68333, 0.05764, 0.08334, 0.77986], + 933: [0, 0.68333, 0.13889, 0.05556, 0.58333], + 934: [0, 0.68333, 0, 0.08334, 0.66667], + 936: [0, 0.68333, 0.11, 0.05556, 0.61222], + 937: [0, 0.68333, 0.05017, 0.08334, 0.7724], + 945: [0, 0.43056, 0.0037, 0.02778, 0.6397], + 946: [0.19444, 0.69444, 0.05278, 0.08334, 0.56563], + 947: [0.19444, 0.43056, 0.05556, 0, 0.51773], + 948: [0, 0.69444, 0.03785, 0.05556, 0.44444], + 949: [0, 0.43056, 0, 0.08334, 0.46632], + 950: [0.19444, 0.69444, 0.07378, 0.08334, 0.4375], + 951: [0.19444, 0.43056, 0.03588, 0.05556, 0.49653], + 952: [0, 0.69444, 0.02778, 0.08334, 0.46944], + 953: [0, 0.43056, 0, 0.05556, 0.35394], + 954: [0, 0.43056, 0, 0, 0.57616], + 955: [0, 0.69444, 0, 0, 0.58334], + 956: [0.19444, 0.43056, 0, 0.02778, 0.60255], + 957: [0, 0.43056, 0.06366, 0.02778, 0.49398], + 958: [0.19444, 0.69444, 0.04601, 0.11111, 0.4375], + 959: [0, 0.43056, 0, 0.05556, 0.48472], + 960: [0, 0.43056, 0.03588, 0, 0.57003], + 961: [0.19444, 0.43056, 0, 0.08334, 0.51702], + 962: [0.09722, 0.43056, 0.07986, 0.08334, 0.36285], + 963: [0, 0.43056, 0.03588, 0, 0.57141], + 964: [0, 0.43056, 0.1132, 0.02778, 0.43715], + 965: [0, 0.43056, 0.03588, 0.02778, 0.54028], + 966: [0.19444, 0.43056, 0, 0.08334, 0.65417], + 967: [0.19444, 0.43056, 0, 0.05556, 0.62569], + 968: [0.19444, 0.69444, 0.03588, 0.11111, 0.65139], + 969: [0, 0.43056, 0.03588, 0, 0.62245], + 977: [0, 0.69444, 0, 0.08334, 0.59144], + 981: [0.19444, 0.69444, 0, 0.08334, 0.59583], + 982: [0, 0.43056, 0.02778, 0, 0.82813], + 1009: [0.19444, 0.43056, 0, 0.08334, 0.51702], + 1013: [0, 0.43056, 0, 0.05556, 0.4059], + 57649: [0, 0.43056, 0, 0.02778, 0.32246], + 57911: [0.19444, 0.43056, 0, 0.08334, 0.38403], + }, + 'SansSerif-Bold': { + 32: [0, 0, 0, 0, 0.25], + 33: [0, 0.69444, 0, 0, 0.36667], + 34: [0, 0.69444, 0, 0, 0.55834], + 35: [0.19444, 0.69444, 0, 0, 0.91667], + 36: [0.05556, 0.75, 0, 0, 0.55], + 37: [0.05556, 0.75, 0, 0, 1.02912], + 38: [0, 0.69444, 0, 0, 0.83056], + 39: [0, 0.69444, 0, 0, 0.30556], + 40: [0.25, 0.75, 0, 0, 0.42778], + 41: [0.25, 0.75, 0, 0, 0.42778], + 42: [0, 0.75, 0, 0, 0.55], + 43: [0.11667, 0.61667, 0, 0, 0.85556], + 44: [0.10556, 0.13056, 0, 0, 0.30556], + 45: [0, 0.45833, 0, 0, 0.36667], + 46: [0, 0.13056, 0, 0, 0.30556], + 47: [0.25, 0.75, 0, 0, 0.55], + 48: [0, 0.69444, 0, 0, 0.55], + 49: [0, 0.69444, 0, 0, 0.55], + 50: [0, 0.69444, 0, 0, 0.55], + 51: [0, 0.69444, 0, 0, 0.55], + 52: [0, 0.69444, 0, 0, 0.55], + 53: [0, 0.69444, 0, 0, 0.55], + 54: [0, 0.69444, 0, 0, 0.55], + 55: [0, 0.69444, 0, 0, 0.55], + 56: [0, 0.69444, 0, 0, 0.55], + 57: [0, 0.69444, 0, 0, 0.55], + 58: [0, 0.45833, 0, 0, 0.30556], + 59: [0.10556, 0.45833, 0, 0, 0.30556], + 61: [-0.09375, 0.40625, 0, 0, 0.85556], + 63: [0, 0.69444, 0, 0, 0.51945], + 64: [0, 0.69444, 0, 0, 0.73334], + 65: [0, 0.69444, 0, 0, 0.73334], + 66: [0, 0.69444, 0, 0, 0.73334], + 67: [0, 0.69444, 0, 0, 0.70278], + 68: [0, 0.69444, 0, 0, 0.79445], + 69: [0, 0.69444, 0, 0, 0.64167], + 70: [0, 0.69444, 0, 0, 0.61111], + 71: [0, 0.69444, 0, 0, 0.73334], + 72: [0, 0.69444, 0, 0, 0.79445], + 73: [0, 0.69444, 0, 0, 0.33056], + 74: [0, 0.69444, 0, 0, 0.51945], + 75: [0, 0.69444, 0, 0, 0.76389], + 76: [0, 0.69444, 0, 0, 0.58056], + 77: [0, 0.69444, 0, 0, 0.97778], + 78: [0, 0.69444, 0, 0, 0.79445], + 79: [0, 0.69444, 0, 0, 0.79445], + 80: [0, 0.69444, 0, 0, 0.70278], + 81: [0.10556, 0.69444, 0, 0, 0.79445], + 82: [0, 0.69444, 0, 0, 0.70278], + 83: [0, 0.69444, 0, 0, 0.61111], + 84: [0, 0.69444, 0, 0, 0.73334], + 85: [0, 0.69444, 0, 0, 0.76389], + 86: [0, 0.69444, 0.01528, 0, 0.73334], + 87: [0, 0.69444, 0.01528, 0, 1.03889], + 88: [0, 0.69444, 0, 0, 0.73334], + 89: [0, 0.69444, 0.0275, 0, 0.73334], + 90: [0, 0.69444, 0, 0, 0.67223], + 91: [0.25, 0.75, 0, 0, 0.34306], + 93: [0.25, 0.75, 0, 0, 0.34306], + 94: [0, 0.69444, 0, 0, 0.55], + 95: [0.35, 0.10833, 0.03056, 0, 0.55], + 97: [0, 0.45833, 0, 0, 0.525], + 98: [0, 0.69444, 0, 0, 0.56111], + 99: [0, 0.45833, 0, 0, 0.48889], + 100: [0, 0.69444, 0, 0, 0.56111], + 101: [0, 0.45833, 0, 0, 0.51111], + 102: [0, 0.69444, 0.07639, 0, 0.33611], + 103: [0.19444, 0.45833, 0.01528, 0, 0.55], + 104: [0, 0.69444, 0, 0, 0.56111], + 105: [0, 0.69444, 0, 0, 0.25556], + 106: [0.19444, 0.69444, 0, 0, 0.28611], + 107: [0, 0.69444, 0, 0, 0.53056], + 108: [0, 0.69444, 0, 0, 0.25556], + 109: [0, 0.45833, 0, 0, 0.86667], + 110: [0, 0.45833, 0, 0, 0.56111], + 111: [0, 0.45833, 0, 0, 0.55], + 112: [0.19444, 0.45833, 0, 0, 0.56111], + 113: [0.19444, 0.45833, 0, 0, 0.56111], + 114: [0, 0.45833, 0.01528, 0, 0.37222], + 115: [0, 0.45833, 0, 0, 0.42167], + 116: [0, 0.58929, 0, 0, 0.40417], + 117: [0, 0.45833, 0, 0, 0.56111], + 118: [0, 0.45833, 0.01528, 0, 0.5], + 119: [0, 0.45833, 0.01528, 0, 0.74445], + 120: [0, 0.45833, 0, 0, 0.5], + 121: [0.19444, 0.45833, 0.01528, 0, 0.5], + 122: [0, 0.45833, 0, 0, 0.47639], + 126: [0.35, 0.34444, 0, 0, 0.55], + 160: [0, 0, 0, 0, 0.25], + 168: [0, 0.69444, 0, 0, 0.55], + 176: [0, 0.69444, 0, 0, 0.73334], + 180: [0, 0.69444, 0, 0, 0.55], + 184: [0.17014, 0, 0, 0, 0.48889], + 305: [0, 0.45833, 0, 0, 0.25556], + 567: [0.19444, 0.45833, 0, 0, 0.28611], + 710: [0, 0.69444, 0, 0, 0.55], + 711: [0, 0.63542, 0, 0, 0.55], + 713: [0, 0.63778, 0, 0, 0.55], + 728: [0, 0.69444, 0, 0, 0.55], + 729: [0, 0.69444, 0, 0, 0.30556], + 730: [0, 0.69444, 0, 0, 0.73334], + 732: [0, 0.69444, 0, 0, 0.55], + 733: [0, 0.69444, 0, 0, 0.55], + 915: [0, 0.69444, 0, 0, 0.58056], + 916: [0, 0.69444, 0, 0, 0.91667], + 920: [0, 0.69444, 0, 0, 0.85556], + 923: [0, 0.69444, 0, 0, 0.67223], + 926: [0, 0.69444, 0, 0, 0.73334], + 928: [0, 0.69444, 0, 0, 0.79445], + 931: [0, 0.69444, 0, 0, 0.79445], + 933: [0, 0.69444, 0, 0, 0.85556], + 934: [0, 0.69444, 0, 0, 0.79445], + 936: [0, 0.69444, 0, 0, 0.85556], + 937: [0, 0.69444, 0, 0, 0.79445], + 8211: [0, 0.45833, 0.03056, 0, 0.55], + 8212: [0, 0.45833, 0.03056, 0, 1.10001], + 8216: [0, 0.69444, 0, 0, 0.30556], + 8217: [0, 0.69444, 0, 0, 0.30556], + 8220: [0, 0.69444, 0, 0, 0.55834], + 8221: [0, 0.69444, 0, 0, 0.55834], + }, + 'SansSerif-Italic': { + 32: [0, 0, 0, 0, 0.25], + 33: [0, 0.69444, 0.05733, 0, 0.31945], + 34: [0, 0.69444, 0.00316, 0, 0.5], + 35: [0.19444, 0.69444, 0.05087, 0, 0.83334], + 36: [0.05556, 0.75, 0.11156, 0, 0.5], + 37: [0.05556, 0.75, 0.03126, 0, 0.83334], + 38: [0, 0.69444, 0.03058, 0, 0.75834], + 39: [0, 0.69444, 0.07816, 0, 0.27778], + 40: [0.25, 0.75, 0.13164, 0, 0.38889], + 41: [0.25, 0.75, 0.02536, 0, 0.38889], + 42: [0, 0.75, 0.11775, 0, 0.5], + 43: [0.08333, 0.58333, 0.02536, 0, 0.77778], + 44: [0.125, 0.08333, 0, 0, 0.27778], + 45: [0, 0.44444, 0.01946, 0, 0.33333], + 46: [0, 0.08333, 0, 0, 0.27778], + 47: [0.25, 0.75, 0.13164, 0, 0.5], + 48: [0, 0.65556, 0.11156, 0, 0.5], + 49: [0, 0.65556, 0.11156, 0, 0.5], + 50: [0, 0.65556, 0.11156, 0, 0.5], + 51: [0, 0.65556, 0.11156, 0, 0.5], + 52: [0, 0.65556, 0.11156, 0, 0.5], + 53: [0, 0.65556, 0.11156, 0, 0.5], + 54: [0, 0.65556, 0.11156, 0, 0.5], + 55: [0, 0.65556, 0.11156, 0, 0.5], + 56: [0, 0.65556, 0.11156, 0, 0.5], + 57: [0, 0.65556, 0.11156, 0, 0.5], + 58: [0, 0.44444, 0.02502, 0, 0.27778], + 59: [0.125, 0.44444, 0.02502, 0, 0.27778], + 61: [-0.13, 0.37, 0.05087, 0, 0.77778], + 63: [0, 0.69444, 0.11809, 0, 0.47222], + 64: [0, 0.69444, 0.07555, 0, 0.66667], + 65: [0, 0.69444, 0, 0, 0.66667], + 66: [0, 0.69444, 0.08293, 0, 0.66667], + 67: [0, 0.69444, 0.11983, 0, 0.63889], + 68: [0, 0.69444, 0.07555, 0, 0.72223], + 69: [0, 0.69444, 0.11983, 0, 0.59722], + 70: [0, 0.69444, 0.13372, 0, 0.56945], + 71: [0, 0.69444, 0.11983, 0, 0.66667], + 72: [0, 0.69444, 0.08094, 0, 0.70834], + 73: [0, 0.69444, 0.13372, 0, 0.27778], + 74: [0, 0.69444, 0.08094, 0, 0.47222], + 75: [0, 0.69444, 0.11983, 0, 0.69445], + 76: [0, 0.69444, 0, 0, 0.54167], + 77: [0, 0.69444, 0.08094, 0, 0.875], + 78: [0, 0.69444, 0.08094, 0, 0.70834], + 79: [0, 0.69444, 0.07555, 0, 0.73611], + 80: [0, 0.69444, 0.08293, 0, 0.63889], + 81: [0.125, 0.69444, 0.07555, 0, 0.73611], + 82: [0, 0.69444, 0.08293, 0, 0.64584], + 83: [0, 0.69444, 0.09205, 0, 0.55556], + 84: [0, 0.69444, 0.13372, 0, 0.68056], + 85: [0, 0.69444, 0.08094, 0, 0.6875], + 86: [0, 0.69444, 0.1615, 0, 0.66667], + 87: [0, 0.69444, 0.1615, 0, 0.94445], + 88: [0, 0.69444, 0.13372, 0, 0.66667], + 89: [0, 0.69444, 0.17261, 0, 0.66667], + 90: [0, 0.69444, 0.11983, 0, 0.61111], + 91: [0.25, 0.75, 0.15942, 0, 0.28889], + 93: [0.25, 0.75, 0.08719, 0, 0.28889], + 94: [0, 0.69444, 0.0799, 0, 0.5], + 95: [0.35, 0.09444, 0.08616, 0, 0.5], + 97: [0, 0.44444, 0.00981, 0, 0.48056], + 98: [0, 0.69444, 0.03057, 0, 0.51667], + 99: [0, 0.44444, 0.08336, 0, 0.44445], + 100: [0, 0.69444, 0.09483, 0, 0.51667], + 101: [0, 0.44444, 0.06778, 0, 0.44445], + 102: [0, 0.69444, 0.21705, 0, 0.30556], + 103: [0.19444, 0.44444, 0.10836, 0, 0.5], + 104: [0, 0.69444, 0.01778, 0, 0.51667], + 105: [0, 0.67937, 0.09718, 0, 0.23889], + 106: [0.19444, 0.67937, 0.09162, 0, 0.26667], + 107: [0, 0.69444, 0.08336, 0, 0.48889], + 108: [0, 0.69444, 0.09483, 0, 0.23889], + 109: [0, 0.44444, 0.01778, 0, 0.79445], + 110: [0, 0.44444, 0.01778, 0, 0.51667], + 111: [0, 0.44444, 0.06613, 0, 0.5], + 112: [0.19444, 0.44444, 0.0389, 0, 0.51667], + 113: [0.19444, 0.44444, 0.04169, 0, 0.51667], + 114: [0, 0.44444, 0.10836, 0, 0.34167], + 115: [0, 0.44444, 0.0778, 0, 0.38333], + 116: [0, 0.57143, 0.07225, 0, 0.36111], + 117: [0, 0.44444, 0.04169, 0, 0.51667], + 118: [0, 0.44444, 0.10836, 0, 0.46111], + 119: [0, 0.44444, 0.10836, 0, 0.68334], + 120: [0, 0.44444, 0.09169, 0, 0.46111], + 121: [0.19444, 0.44444, 0.10836, 0, 0.46111], + 122: [0, 0.44444, 0.08752, 0, 0.43472], + 126: [0.35, 0.32659, 0.08826, 0, 0.5], + 160: [0, 0, 0, 0, 0.25], + 168: [0, 0.67937, 0.06385, 0, 0.5], + 176: [0, 0.69444, 0, 0, 0.73752], + 184: [0.17014, 0, 0, 0, 0.44445], + 305: [0, 0.44444, 0.04169, 0, 0.23889], + 567: [0.19444, 0.44444, 0.04169, 0, 0.26667], + 710: [0, 0.69444, 0.0799, 0, 0.5], + 711: [0, 0.63194, 0.08432, 0, 0.5], + 713: [0, 0.60889, 0.08776, 0, 0.5], + 714: [0, 0.69444, 0.09205, 0, 0.5], + 715: [0, 0.69444, 0, 0, 0.5], + 728: [0, 0.69444, 0.09483, 0, 0.5], + 729: [0, 0.67937, 0.07774, 0, 0.27778], + 730: [0, 0.69444, 0, 0, 0.73752], + 732: [0, 0.67659, 0.08826, 0, 0.5], + 733: [0, 0.69444, 0.09205, 0, 0.5], + 915: [0, 0.69444, 0.13372, 0, 0.54167], + 916: [0, 0.69444, 0, 0, 0.83334], + 920: [0, 0.69444, 0.07555, 0, 0.77778], + 923: [0, 0.69444, 0, 0, 0.61111], + 926: [0, 0.69444, 0.12816, 0, 0.66667], + 928: [0, 0.69444, 0.08094, 0, 0.70834], + 931: [0, 0.69444, 0.11983, 0, 0.72222], + 933: [0, 0.69444, 0.09031, 0, 0.77778], + 934: [0, 0.69444, 0.04603, 0, 0.72222], + 936: [0, 0.69444, 0.09031, 0, 0.77778], + 937: [0, 0.69444, 0.08293, 0, 0.72222], + 8211: [0, 0.44444, 0.08616, 0, 0.5], + 8212: [0, 0.44444, 0.08616, 0, 1], + 8216: [0, 0.69444, 0.07816, 0, 0.27778], + 8217: [0, 0.69444, 0.07816, 0, 0.27778], + 8220: [0, 0.69444, 0.14205, 0, 0.5], + 8221: [0, 0.69444, 0.00316, 0, 0.5], + }, + 'SansSerif-Regular': { + 32: [0, 0, 0, 0, 0.25], + 33: [0, 0.69444, 0, 0, 0.31945], + 34: [0, 0.69444, 0, 0, 0.5], + 35: [0.19444, 0.69444, 0, 0, 0.83334], + 36: [0.05556, 0.75, 0, 0, 0.5], + 37: [0.05556, 0.75, 0, 0, 0.83334], + 38: [0, 0.69444, 0, 0, 0.75834], + 39: [0, 0.69444, 0, 0, 0.27778], + 40: [0.25, 0.75, 0, 0, 0.38889], + 41: [0.25, 0.75, 0, 0, 0.38889], + 42: [0, 0.75, 0, 0, 0.5], + 43: [0.08333, 0.58333, 0, 0, 0.77778], + 44: [0.125, 0.08333, 0, 0, 0.27778], + 45: [0, 0.44444, 0, 0, 0.33333], + 46: [0, 0.08333, 0, 0, 0.27778], + 47: [0.25, 0.75, 0, 0, 0.5], + 48: [0, 0.65556, 0, 0, 0.5], + 49: [0, 0.65556, 0, 0, 0.5], + 50: [0, 0.65556, 0, 0, 0.5], + 51: [0, 0.65556, 0, 0, 0.5], + 52: [0, 0.65556, 0, 0, 0.5], + 53: [0, 0.65556, 0, 0, 0.5], + 54: [0, 0.65556, 0, 0, 0.5], + 55: [0, 0.65556, 0, 0, 0.5], + 56: [0, 0.65556, 0, 0, 0.5], + 57: [0, 0.65556, 0, 0, 0.5], + 58: [0, 0.44444, 0, 0, 0.27778], + 59: [0.125, 0.44444, 0, 0, 0.27778], + 61: [-0.13, 0.37, 0, 0, 0.77778], + 63: [0, 0.69444, 0, 0, 0.47222], + 64: [0, 0.69444, 0, 0, 0.66667], + 65: [0, 0.69444, 0, 0, 0.66667], + 66: [0, 0.69444, 0, 0, 0.66667], + 67: [0, 0.69444, 0, 0, 0.63889], + 68: [0, 0.69444, 0, 0, 0.72223], + 69: [0, 0.69444, 0, 0, 0.59722], + 70: [0, 0.69444, 0, 0, 0.56945], + 71: [0, 0.69444, 0, 0, 0.66667], + 72: [0, 0.69444, 0, 0, 0.70834], + 73: [0, 0.69444, 0, 0, 0.27778], + 74: [0, 0.69444, 0, 0, 0.47222], + 75: [0, 0.69444, 0, 0, 0.69445], + 76: [0, 0.69444, 0, 0, 0.54167], + 77: [0, 0.69444, 0, 0, 0.875], + 78: [0, 0.69444, 0, 0, 0.70834], + 79: [0, 0.69444, 0, 0, 0.73611], + 80: [0, 0.69444, 0, 0, 0.63889], + 81: [0.125, 0.69444, 0, 0, 0.73611], + 82: [0, 0.69444, 0, 0, 0.64584], + 83: [0, 0.69444, 0, 0, 0.55556], + 84: [0, 0.69444, 0, 0, 0.68056], + 85: [0, 0.69444, 0, 0, 0.6875], + 86: [0, 0.69444, 0.01389, 0, 0.66667], + 87: [0, 0.69444, 0.01389, 0, 0.94445], + 88: [0, 0.69444, 0, 0, 0.66667], + 89: [0, 0.69444, 0.025, 0, 0.66667], + 90: [0, 0.69444, 0, 0, 0.61111], + 91: [0.25, 0.75, 0, 0, 0.28889], + 93: [0.25, 0.75, 0, 0, 0.28889], + 94: [0, 0.69444, 0, 0, 0.5], + 95: [0.35, 0.09444, 0.02778, 0, 0.5], + 97: [0, 0.44444, 0, 0, 0.48056], + 98: [0, 0.69444, 0, 0, 0.51667], + 99: [0, 0.44444, 0, 0, 0.44445], + 100: [0, 0.69444, 0, 0, 0.51667], + 101: [0, 0.44444, 0, 0, 0.44445], + 102: [0, 0.69444, 0.06944, 0, 0.30556], + 103: [0.19444, 0.44444, 0.01389, 0, 0.5], + 104: [0, 0.69444, 0, 0, 0.51667], + 105: [0, 0.67937, 0, 0, 0.23889], + 106: [0.19444, 0.67937, 0, 0, 0.26667], + 107: [0, 0.69444, 0, 0, 0.48889], + 108: [0, 0.69444, 0, 0, 0.23889], + 109: [0, 0.44444, 0, 0, 0.79445], + 110: [0, 0.44444, 0, 0, 0.51667], + 111: [0, 0.44444, 0, 0, 0.5], + 112: [0.19444, 0.44444, 0, 0, 0.51667], + 113: [0.19444, 0.44444, 0, 0, 0.51667], + 114: [0, 0.44444, 0.01389, 0, 0.34167], + 115: [0, 0.44444, 0, 0, 0.38333], + 116: [0, 0.57143, 0, 0, 0.36111], + 117: [0, 0.44444, 0, 0, 0.51667], + 118: [0, 0.44444, 0.01389, 0, 0.46111], + 119: [0, 0.44444, 0.01389, 0, 0.68334], + 120: [0, 0.44444, 0, 0, 0.46111], + 121: [0.19444, 0.44444, 0.01389, 0, 0.46111], + 122: [0, 0.44444, 0, 0, 0.43472], + 126: [0.35, 0.32659, 0, 0, 0.5], + 160: [0, 0, 0, 0, 0.25], + 168: [0, 0.67937, 0, 0, 0.5], + 176: [0, 0.69444, 0, 0, 0.66667], + 184: [0.17014, 0, 0, 0, 0.44445], + 305: [0, 0.44444, 0, 0, 0.23889], + 567: [0.19444, 0.44444, 0, 0, 0.26667], + 710: [0, 0.69444, 0, 0, 0.5], + 711: [0, 0.63194, 0, 0, 0.5], + 713: [0, 0.60889, 0, 0, 0.5], + 714: [0, 0.69444, 0, 0, 0.5], + 715: [0, 0.69444, 0, 0, 0.5], + 728: [0, 0.69444, 0, 0, 0.5], + 729: [0, 0.67937, 0, 0, 0.27778], + 730: [0, 0.69444, 0, 0, 0.66667], + 732: [0, 0.67659, 0, 0, 0.5], + 733: [0, 0.69444, 0, 0, 0.5], + 915: [0, 0.69444, 0, 0, 0.54167], + 916: [0, 0.69444, 0, 0, 0.83334], + 920: [0, 0.69444, 0, 0, 0.77778], + 923: [0, 0.69444, 0, 0, 0.61111], + 926: [0, 0.69444, 0, 0, 0.66667], + 928: [0, 0.69444, 0, 0, 0.70834], + 931: [0, 0.69444, 0, 0, 0.72222], + 933: [0, 0.69444, 0, 0, 0.77778], + 934: [0, 0.69444, 0, 0, 0.72222], + 936: [0, 0.69444, 0, 0, 0.77778], + 937: [0, 0.69444, 0, 0, 0.72222], + 8211: [0, 0.44444, 0.02778, 0, 0.5], + 8212: [0, 0.44444, 0.02778, 0, 1], + 8216: [0, 0.69444, 0, 0, 0.27778], + 8217: [0, 0.69444, 0, 0, 0.27778], + 8220: [0, 0.69444, 0, 0, 0.5], + 8221: [0, 0.69444, 0, 0, 0.5], + }, + 'Script-Regular': { + 32: [0, 0, 0, 0, 0.25], + 65: [0, 0.7, 0.22925, 0, 0.80253], + 66: [0, 0.7, 0.04087, 0, 0.90757], + 67: [0, 0.7, 0.1689, 0, 0.66619], + 68: [0, 0.7, 0.09371, 0, 0.77443], + 69: [0, 0.7, 0.18583, 0, 0.56162], + 70: [0, 0.7, 0.13634, 0, 0.89544], + 71: [0, 0.7, 0.17322, 0, 0.60961], + 72: [0, 0.7, 0.29694, 0, 0.96919], + 73: [0, 0.7, 0.19189, 0, 0.80907], + 74: [0.27778, 0.7, 0.19189, 0, 1.05159], + 75: [0, 0.7, 0.31259, 0, 0.91364], + 76: [0, 0.7, 0.19189, 0, 0.87373], + 77: [0, 0.7, 0.15981, 0, 1.08031], + 78: [0, 0.7, 0.3525, 0, 0.9015], + 79: [0, 0.7, 0.08078, 0, 0.73787], + 80: [0, 0.7, 0.08078, 0, 1.01262], + 81: [0, 0.7, 0.03305, 0, 0.88282], + 82: [0, 0.7, 0.06259, 0, 0.85], + 83: [0, 0.7, 0.19189, 0, 0.86767], + 84: [0, 0.7, 0.29087, 0, 0.74697], + 85: [0, 0.7, 0.25815, 0, 0.79996], + 86: [0, 0.7, 0.27523, 0, 0.62204], + 87: [0, 0.7, 0.27523, 0, 0.80532], + 88: [0, 0.7, 0.26006, 0, 0.94445], + 89: [0, 0.7, 0.2939, 0, 0.70961], + 90: [0, 0.7, 0.24037, 0, 0.8212], + 160: [0, 0, 0, 0, 0.25], + }, + 'Size1-Regular': { + 32: [0, 0, 0, 0, 0.25], + 40: [0.35001, 0.85, 0, 0, 0.45834], + 41: [0.35001, 0.85, 0, 0, 0.45834], + 47: [0.35001, 0.85, 0, 0, 0.57778], + 91: [0.35001, 0.85, 0, 0, 0.41667], + 92: [0.35001, 0.85, 0, 0, 0.57778], + 93: [0.35001, 0.85, 0, 0, 0.41667], + 123: [0.35001, 0.85, 0, 0, 0.58334], + 125: [0.35001, 0.85, 0, 0, 0.58334], + 160: [0, 0, 0, 0, 0.25], + 710: [0, 0.72222, 0, 0, 0.55556], + 732: [0, 0.72222, 0, 0, 0.55556], + 770: [0, 0.72222, 0, 0, 0.55556], + 771: [0, 0.72222, 0, 0, 0.55556], + 8214: [-99e-5, 0.601, 0, 0, 0.77778], + 8593: [1e-5, 0.6, 0, 0, 0.66667], + 8595: [1e-5, 0.6, 0, 0, 0.66667], + 8657: [1e-5, 0.6, 0, 0, 0.77778], + 8659: [1e-5, 0.6, 0, 0, 0.77778], + 8719: [0.25001, 0.75, 0, 0, 0.94445], + 8720: [0.25001, 0.75, 0, 0, 0.94445], + 8721: [0.25001, 0.75, 0, 0, 1.05556], + 8730: [0.35001, 0.85, 0, 0, 1], + 8739: [-0.00599, 0.606, 0, 0, 0.33333], + 8741: [-0.00599, 0.606, 0, 0, 0.55556], + 8747: [0.30612, 0.805, 0.19445, 0, 0.47222], + 8748: [0.306, 0.805, 0.19445, 0, 0.47222], + 8749: [0.306, 0.805, 0.19445, 0, 0.47222], + 8750: [0.30612, 0.805, 0.19445, 0, 0.47222], + 8896: [0.25001, 0.75, 0, 0, 0.83334], + 8897: [0.25001, 0.75, 0, 0, 0.83334], + 8898: [0.25001, 0.75, 0, 0, 0.83334], + 8899: [0.25001, 0.75, 0, 0, 0.83334], + 8968: [0.35001, 0.85, 0, 0, 0.47222], + 8969: [0.35001, 0.85, 0, 0, 0.47222], + 8970: [0.35001, 0.85, 0, 0, 0.47222], + 8971: [0.35001, 0.85, 0, 0, 0.47222], + 9168: [-99e-5, 0.601, 0, 0, 0.66667], + 10216: [0.35001, 0.85, 0, 0, 0.47222], + 10217: [0.35001, 0.85, 0, 0, 0.47222], + 10752: [0.25001, 0.75, 0, 0, 1.11111], + 10753: [0.25001, 0.75, 0, 0, 1.11111], + 10754: [0.25001, 0.75, 0, 0, 1.11111], + 10756: [0.25001, 0.75, 0, 0, 0.83334], + 10758: [0.25001, 0.75, 0, 0, 0.83334], + }, + 'Size2-Regular': { + 32: [0, 0, 0, 0, 0.25], + 40: [0.65002, 1.15, 0, 0, 0.59722], + 41: [0.65002, 1.15, 0, 0, 0.59722], + 47: [0.65002, 1.15, 0, 0, 0.81111], + 91: [0.65002, 1.15, 0, 0, 0.47222], + 92: [0.65002, 1.15, 0, 0, 0.81111], + 93: [0.65002, 1.15, 0, 0, 0.47222], + 123: [0.65002, 1.15, 0, 0, 0.66667], + 125: [0.65002, 1.15, 0, 0, 0.66667], + 160: [0, 0, 0, 0, 0.25], + 710: [0, 0.75, 0, 0, 1], + 732: [0, 0.75, 0, 0, 1], + 770: [0, 0.75, 0, 0, 1], + 771: [0, 0.75, 0, 0, 1], + 8719: [0.55001, 1.05, 0, 0, 1.27778], + 8720: [0.55001, 1.05, 0, 0, 1.27778], + 8721: [0.55001, 1.05, 0, 0, 1.44445], + 8730: [0.65002, 1.15, 0, 0, 1], + 8747: [0.86225, 1.36, 0.44445, 0, 0.55556], + 8748: [0.862, 1.36, 0.44445, 0, 0.55556], + 8749: [0.862, 1.36, 0.44445, 0, 0.55556], + 8750: [0.86225, 1.36, 0.44445, 0, 0.55556], + 8896: [0.55001, 1.05, 0, 0, 1.11111], + 8897: [0.55001, 1.05, 0, 0, 1.11111], + 8898: [0.55001, 1.05, 0, 0, 1.11111], + 8899: [0.55001, 1.05, 0, 0, 1.11111], + 8968: [0.65002, 1.15, 0, 0, 0.52778], + 8969: [0.65002, 1.15, 0, 0, 0.52778], + 8970: [0.65002, 1.15, 0, 0, 0.52778], + 8971: [0.65002, 1.15, 0, 0, 0.52778], + 10216: [0.65002, 1.15, 0, 0, 0.61111], + 10217: [0.65002, 1.15, 0, 0, 0.61111], + 10752: [0.55001, 1.05, 0, 0, 1.51112], + 10753: [0.55001, 1.05, 0, 0, 1.51112], + 10754: [0.55001, 1.05, 0, 0, 1.51112], + 10756: [0.55001, 1.05, 0, 0, 1.11111], + 10758: [0.55001, 1.05, 0, 0, 1.11111], + }, + 'Size3-Regular': { + 32: [0, 0, 0, 0, 0.25], + 40: [0.95003, 1.45, 0, 0, 0.73611], + 41: [0.95003, 1.45, 0, 0, 0.73611], + 47: [0.95003, 1.45, 0, 0, 1.04445], + 91: [0.95003, 1.45, 0, 0, 0.52778], + 92: [0.95003, 1.45, 0, 0, 1.04445], + 93: [0.95003, 1.45, 0, 0, 0.52778], + 123: [0.95003, 1.45, 0, 0, 0.75], + 125: [0.95003, 1.45, 0, 0, 0.75], + 160: [0, 0, 0, 0, 0.25], + 710: [0, 0.75, 0, 0, 1.44445], + 732: [0, 0.75, 0, 0, 1.44445], + 770: [0, 0.75, 0, 0, 1.44445], + 771: [0, 0.75, 0, 0, 1.44445], + 8730: [0.95003, 1.45, 0, 0, 1], + 8968: [0.95003, 1.45, 0, 0, 0.58334], + 8969: [0.95003, 1.45, 0, 0, 0.58334], + 8970: [0.95003, 1.45, 0, 0, 0.58334], + 8971: [0.95003, 1.45, 0, 0, 0.58334], + 10216: [0.95003, 1.45, 0, 0, 0.75], + 10217: [0.95003, 1.45, 0, 0, 0.75], + }, + 'Size4-Regular': { + 32: [0, 0, 0, 0, 0.25], + 40: [1.25003, 1.75, 0, 0, 0.79167], + 41: [1.25003, 1.75, 0, 0, 0.79167], + 47: [1.25003, 1.75, 0, 0, 1.27778], + 91: [1.25003, 1.75, 0, 0, 0.58334], + 92: [1.25003, 1.75, 0, 0, 1.27778], + 93: [1.25003, 1.75, 0, 0, 0.58334], + 123: [1.25003, 1.75, 0, 0, 0.80556], + 125: [1.25003, 1.75, 0, 0, 0.80556], + 160: [0, 0, 0, 0, 0.25], + 710: [0, 0.825, 0, 0, 1.8889], + 732: [0, 0.825, 0, 0, 1.8889], + 770: [0, 0.825, 0, 0, 1.8889], + 771: [0, 0.825, 0, 0, 1.8889], + 8730: [1.25003, 1.75, 0, 0, 1], + 8968: [1.25003, 1.75, 0, 0, 0.63889], + 8969: [1.25003, 1.75, 0, 0, 0.63889], + 8970: [1.25003, 1.75, 0, 0, 0.63889], + 8971: [1.25003, 1.75, 0, 0, 0.63889], + 9115: [0.64502, 1.155, 0, 0, 0.875], + 9116: [1e-5, 0.6, 0, 0, 0.875], + 9117: [0.64502, 1.155, 0, 0, 0.875], + 9118: [0.64502, 1.155, 0, 0, 0.875], + 9119: [1e-5, 0.6, 0, 0, 0.875], + 9120: [0.64502, 1.155, 0, 0, 0.875], + 9121: [0.64502, 1.155, 0, 0, 0.66667], + 9122: [-99e-5, 0.601, 0, 0, 0.66667], + 9123: [0.64502, 1.155, 0, 0, 0.66667], + 9124: [0.64502, 1.155, 0, 0, 0.66667], + 9125: [-99e-5, 0.601, 0, 0, 0.66667], + 9126: [0.64502, 1.155, 0, 0, 0.66667], + 9127: [1e-5, 0.9, 0, 0, 0.88889], + 9128: [0.65002, 1.15, 0, 0, 0.88889], + 9129: [0.90001, 0, 0, 0, 0.88889], + 9130: [0, 0.3, 0, 0, 0.88889], + 9131: [1e-5, 0.9, 0, 0, 0.88889], + 9132: [0.65002, 1.15, 0, 0, 0.88889], + 9133: [0.90001, 0, 0, 0, 0.88889], + 9143: [0.88502, 0.915, 0, 0, 1.05556], + 10216: [1.25003, 1.75, 0, 0, 0.80556], + 10217: [1.25003, 1.75, 0, 0, 0.80556], + 57344: [-0.00499, 0.605, 0, 0, 1.05556], + 57345: [-0.00499, 0.605, 0, 0, 1.05556], + 57680: [0, 0.12, 0, 0, 0.45], + 57681: [0, 0.12, 0, 0, 0.45], + 57682: [0, 0.12, 0, 0, 0.45], + 57683: [0, 0.12, 0, 0, 0.45], + }, + 'Typewriter-Regular': { + 32: [0, 0, 0, 0, 0.525], + 33: [0, 0.61111, 0, 0, 0.525], + 34: [0, 0.61111, 0, 0, 0.525], + 35: [0, 0.61111, 0, 0, 0.525], + 36: [0.08333, 0.69444, 0, 0, 0.525], + 37: [0.08333, 0.69444, 0, 0, 0.525], + 38: [0, 0.61111, 0, 0, 0.525], + 39: [0, 0.61111, 0, 0, 0.525], + 40: [0.08333, 0.69444, 0, 0, 0.525], + 41: [0.08333, 0.69444, 0, 0, 0.525], + 42: [0, 0.52083, 0, 0, 0.525], + 43: [-0.08056, 0.53055, 0, 0, 0.525], + 44: [0.13889, 0.125, 0, 0, 0.525], + 45: [-0.08056, 0.53055, 0, 0, 0.525], + 46: [0, 0.125, 0, 0, 0.525], + 47: [0.08333, 0.69444, 0, 0, 0.525], + 48: [0, 0.61111, 0, 0, 0.525], + 49: [0, 0.61111, 0, 0, 0.525], + 50: [0, 0.61111, 0, 0, 0.525], + 51: [0, 0.61111, 0, 0, 0.525], + 52: [0, 0.61111, 0, 0, 0.525], + 53: [0, 0.61111, 0, 0, 0.525], + 54: [0, 0.61111, 0, 0, 0.525], + 55: [0, 0.61111, 0, 0, 0.525], + 56: [0, 0.61111, 0, 0, 0.525], + 57: [0, 0.61111, 0, 0, 0.525], + 58: [0, 0.43056, 0, 0, 0.525], + 59: [0.13889, 0.43056, 0, 0, 0.525], + 60: [-0.05556, 0.55556, 0, 0, 0.525], + 61: [-0.19549, 0.41562, 0, 0, 0.525], + 62: [-0.05556, 0.55556, 0, 0, 0.525], + 63: [0, 0.61111, 0, 0, 0.525], + 64: [0, 0.61111, 0, 0, 0.525], + 65: [0, 0.61111, 0, 0, 0.525], + 66: [0, 0.61111, 0, 0, 0.525], + 67: [0, 0.61111, 0, 0, 0.525], + 68: [0, 0.61111, 0, 0, 0.525], + 69: [0, 0.61111, 0, 0, 0.525], + 70: [0, 0.61111, 0, 0, 0.525], + 71: [0, 0.61111, 0, 0, 0.525], + 72: [0, 0.61111, 0, 0, 0.525], + 73: [0, 0.61111, 0, 0, 0.525], + 74: [0, 0.61111, 0, 0, 0.525], + 75: [0, 0.61111, 0, 0, 0.525], + 76: [0, 0.61111, 0, 0, 0.525], + 77: [0, 0.61111, 0, 0, 0.525], + 78: [0, 0.61111, 0, 0, 0.525], + 79: [0, 0.61111, 0, 0, 0.525], + 80: [0, 0.61111, 0, 0, 0.525], + 81: [0.13889, 0.61111, 0, 0, 0.525], + 82: [0, 0.61111, 0, 0, 0.525], + 83: [0, 0.61111, 0, 0, 0.525], + 84: [0, 0.61111, 0, 0, 0.525], + 85: [0, 0.61111, 0, 0, 0.525], + 86: [0, 0.61111, 0, 0, 0.525], + 87: [0, 0.61111, 0, 0, 0.525], + 88: [0, 0.61111, 0, 0, 0.525], + 89: [0, 0.61111, 0, 0, 0.525], + 90: [0, 0.61111, 0, 0, 0.525], + 91: [0.08333, 0.69444, 0, 0, 0.525], + 92: [0.08333, 0.69444, 0, 0, 0.525], + 93: [0.08333, 0.69444, 0, 0, 0.525], + 94: [0, 0.61111, 0, 0, 0.525], + 95: [0.09514, 0, 0, 0, 0.525], + 96: [0, 0.61111, 0, 0, 0.525], + 97: [0, 0.43056, 0, 0, 0.525], + 98: [0, 0.61111, 0, 0, 0.525], + 99: [0, 0.43056, 0, 0, 0.525], + 100: [0, 0.61111, 0, 0, 0.525], + 101: [0, 0.43056, 0, 0, 0.525], + 102: [0, 0.61111, 0, 0, 0.525], + 103: [0.22222, 0.43056, 0, 0, 0.525], + 104: [0, 0.61111, 0, 0, 0.525], + 105: [0, 0.61111, 0, 0, 0.525], + 106: [0.22222, 0.61111, 0, 0, 0.525], + 107: [0, 0.61111, 0, 0, 0.525], + 108: [0, 0.61111, 0, 0, 0.525], + 109: [0, 0.43056, 0, 0, 0.525], + 110: [0, 0.43056, 0, 0, 0.525], + 111: [0, 0.43056, 0, 0, 0.525], + 112: [0.22222, 0.43056, 0, 0, 0.525], + 113: [0.22222, 0.43056, 0, 0, 0.525], + 114: [0, 0.43056, 0, 0, 0.525], + 115: [0, 0.43056, 0, 0, 0.525], + 116: [0, 0.55358, 0, 0, 0.525], + 117: [0, 0.43056, 0, 0, 0.525], + 118: [0, 0.43056, 0, 0, 0.525], + 119: [0, 0.43056, 0, 0, 0.525], + 120: [0, 0.43056, 0, 0, 0.525], + 121: [0.22222, 0.43056, 0, 0, 0.525], + 122: [0, 0.43056, 0, 0, 0.525], + 123: [0.08333, 0.69444, 0, 0, 0.525], + 124: [0.08333, 0.69444, 0, 0, 0.525], + 125: [0.08333, 0.69444, 0, 0, 0.525], + 126: [0, 0.61111, 0, 0, 0.525], + 127: [0, 0.61111, 0, 0, 0.525], + 160: [0, 0, 0, 0, 0.525], + 176: [0, 0.61111, 0, 0, 0.525], + 184: [0.19445, 0, 0, 0, 0.525], + 305: [0, 0.43056, 0, 0, 0.525], + 567: [0.22222, 0.43056, 0, 0, 0.525], + 711: [0, 0.56597, 0, 0, 0.525], + 713: [0, 0.56555, 0, 0, 0.525], + 714: [0, 0.61111, 0, 0, 0.525], + 715: [0, 0.61111, 0, 0, 0.525], + 728: [0, 0.61111, 0, 0, 0.525], + 730: [0, 0.61111, 0, 0, 0.525], + 770: [0, 0.61111, 0, 0, 0.525], + 771: [0, 0.61111, 0, 0, 0.525], + 776: [0, 0.61111, 0, 0, 0.525], + 915: [0, 0.61111, 0, 0, 0.525], + 916: [0, 0.61111, 0, 0, 0.525], + 920: [0, 0.61111, 0, 0, 0.525], + 923: [0, 0.61111, 0, 0, 0.525], + 926: [0, 0.61111, 0, 0, 0.525], + 928: [0, 0.61111, 0, 0, 0.525], + 931: [0, 0.61111, 0, 0, 0.525], + 933: [0, 0.61111, 0, 0, 0.525], + 934: [0, 0.61111, 0, 0, 0.525], + 936: [0, 0.61111, 0, 0, 0.525], + 937: [0, 0.61111, 0, 0, 0.525], + 8216: [0, 0.61111, 0, 0, 0.525], + 8217: [0, 0.61111, 0, 0, 0.525], + 8242: [0, 0.61111, 0, 0, 0.525], + 9251: [0.11111, 0.21944, 0, 0, 0.525], + }, + }, + V = { + slant: [0.25, 0.25, 0.25], + space: [0, 0, 0], + stretch: [0, 0, 0], + shrink: [0, 0, 0], + xHeight: [0.431, 0.431, 0.431], + quad: [1, 1.171, 1.472], + extraSpace: [0, 0, 0], + num1: [0.677, 0.732, 0.925], + num2: [0.394, 0.384, 0.387], + num3: [0.444, 0.471, 0.504], + denom1: [0.686, 0.752, 1.025], + denom2: [0.345, 0.344, 0.532], + sup1: [0.413, 0.503, 0.504], + sup2: [0.363, 0.431, 0.404], + sup3: [0.289, 0.286, 0.294], + sub1: [0.15, 0.143, 0.2], + sub2: [0.247, 0.286, 0.4], + supDrop: [0.386, 0.353, 0.494], + subDrop: [0.05, 0.071, 0.1], + delim1: [2.39, 1.7, 1.98], + delim2: [1.01, 1.157, 1.42], + axisHeight: [0.25, 0.25, 0.25], + defaultRuleThickness: [0.04, 0.049, 0.049], + bigOpSpacing1: [0.111, 0.111, 0.111], + bigOpSpacing2: [0.166, 0.166, 0.166], + bigOpSpacing3: [0.2, 0.2, 0.2], + bigOpSpacing4: [0.6, 0.611, 0.611], + bigOpSpacing5: [0.1, 0.143, 0.143], + sqrtRuleThickness: [0.04, 0.04, 0.04], + ptPerEm: [10, 10, 10], + doubleRuleSep: [0.2, 0.2, 0.2], + arrayRuleWidth: [0.04, 0.04, 0.04], + fboxsep: [0.3, 0.3, 0.3], + fboxrule: [0.04, 0.04, 0.04], + }, + U = { + '\xc5': 'A', + '\xc7': 'C', + '\xd0': 'D', + '\xde': 'o', + '\xe5': 'a', + '\xe7': 'c', + '\xf0': 'd', + '\xfe': 'o', + '\u0410': 'A', + '\u0411': 'B', + '\u0412': 'B', + '\u0413': 'F', + '\u0414': 'A', + '\u0415': 'E', + '\u0416': 'K', + '\u0417': '3', + '\u0418': 'N', + '\u0419': 'N', + '\u041a': 'K', + '\u041b': 'N', + '\u041c': 'M', + '\u041d': 'H', + '\u041e': 'O', + '\u041f': 'N', + '\u0420': 'P', + '\u0421': 'C', + '\u0422': 'T', + '\u0423': 'y', + '\u0424': 'O', + '\u0425': 'X', + '\u0426': 'U', + '\u0427': 'h', + '\u0428': 'W', + '\u0429': 'W', + '\u042a': 'B', + '\u042b': 'X', + '\u042c': 'B', + '\u042d': '3', + '\u042e': 'X', + '\u042f': 'R', + '\u0430': 'a', + '\u0431': 'b', + '\u0432': 'a', + '\u0433': 'r', + '\u0434': 'y', + '\u0435': 'e', + '\u0436': 'm', + '\u0437': 'e', + '\u0438': 'n', + '\u0439': 'n', + '\u043a': 'n', + '\u043b': 'n', + '\u043c': 'm', + '\u043d': 'n', + '\u043e': 'o', + '\u043f': 'n', + '\u0440': 'p', + '\u0441': 'c', + '\u0442': 'o', + '\u0443': 'y', + '\u0444': 'b', + '\u0445': 'x', + '\u0446': 'n', + '\u0447': 'n', + '\u0448': 'w', + '\u0449': 'w', + '\u044a': 'a', + '\u044b': 'm', + '\u044c': 'a', + '\u044d': 'e', + '\u044e': 'm', + '\u044f': 'r', + }; + function G(t, e, r) { + if (!F[e]) throw new Error('Font metrics not found for font: ' + e + '.'); + var a = t.charCodeAt(0), + n = F[e][a]; + if ((!n && t[0] in U && ((a = U[t[0]].charCodeAt(0)), (n = F[e][a])), n || 'text' !== r || (M(a) && (n = F[e][77])), n)) + return { depth: n[0], height: n[1], italic: n[2], skew: n[3], width: n[4] }; + } + var Y = {}; + var W = { bin: 1, close: 1, inner: 1, open: 1, punct: 1, rel: 1 }, + X = { 'accent-token': 1, mathord: 1, 'op-token': 1, spacing: 1, textord: 1 }, + _ = { math: {}, text: {} }, + j = _; + function $(t, e, r, a, n, i) { + (_[t][n] = { font: e, group: r, replace: a }), i && a && (_[t][a] = _[t][n]); + } + var Z = 'main', + K = 'ams', + J = 'bin', + Q = 'mathord', + tt = 'op-token', + et = 'rel'; + $('math', Z, et, '\u2261', '\\equiv', !0), + $('math', Z, et, '\u227a', '\\prec', !0), + $('math', Z, et, '\u227b', '\\succ', !0), + $('math', Z, et, '\u223c', '\\sim', !0), + $('math', Z, et, '\u22a5', '\\perp'), + $('math', Z, et, '\u2aaf', '\\preceq', !0), + $('math', Z, et, '\u2ab0', '\\succeq', !0), + $('math', Z, et, '\u2243', '\\simeq', !0), + $('math', Z, et, '\u2223', '\\mid', !0), + $('math', Z, et, '\u226a', '\\ll', !0), + $('math', Z, et, '\u226b', '\\gg', !0), + $('math', Z, et, '\u224d', '\\asymp', !0), + $('math', Z, et, '\u2225', '\\parallel'), + $('math', Z, et, '\u22c8', '\\bowtie', !0), + $('math', Z, et, '\u2323', '\\smile', !0), + $('math', Z, et, '\u2291', '\\sqsubseteq', !0), + $('math', Z, et, '\u2292', '\\sqsupseteq', !0), + $('math', Z, et, '\u2250', '\\doteq', !0), + $('math', Z, et, '\u2322', '\\frown', !0), + $('math', Z, et, '\u220b', '\\ni', !0), + $('math', Z, et, '\u221d', '\\propto', !0), + $('math', Z, et, '\u22a2', '\\vdash', !0), + $('math', Z, et, '\u22a3', '\\dashv', !0), + $('math', Z, et, '\u220b', '\\owns'), + $('math', Z, 'punct', '.', '\\ldotp'), + $('math', Z, 'punct', '\u22c5', '\\cdotp'), + $('math', Z, 'textord', '#', '\\#'), + $('text', Z, 'textord', '#', '\\#'), + $('math', Z, 'textord', '&', '\\&'), + $('text', Z, 'textord', '&', '\\&'), + $('math', Z, 'textord', '\u2135', '\\aleph', !0), + $('math', Z, 'textord', '\u2200', '\\forall', !0), + $('math', Z, 'textord', '\u210f', '\\hbar', !0), + $('math', Z, 'textord', '\u2203', '\\exists', !0), + $('math', Z, 'textord', '\u2207', '\\nabla', !0), + $('math', Z, 'textord', '\u266d', '\\flat', !0), + $('math', Z, 'textord', '\u2113', '\\ell', !0), + $('math', Z, 'textord', '\u266e', '\\natural', !0), + $('math', Z, 'textord', '\u2663', '\\clubsuit', !0), + $('math', Z, 'textord', '\u2118', '\\wp', !0), + $('math', Z, 'textord', '\u266f', '\\sharp', !0), + $('math', Z, 'textord', '\u2662', '\\diamondsuit', !0), + $('math', Z, 'textord', '\u211c', '\\Re', !0), + $('math', Z, 'textord', '\u2661', '\\heartsuit', !0), + $('math', Z, 'textord', '\u2111', '\\Im', !0), + $('math', Z, 'textord', '\u2660', '\\spadesuit', !0), + $('text', Z, 'textord', '\xa7', '\\S', !0), + $('text', Z, 'textord', '\xb6', '\\P', !0), + $('math', Z, 'textord', '\u2020', '\\dag'), + $('text', Z, 'textord', '\u2020', '\\dag'), + $('text', Z, 'textord', '\u2020', '\\textdagger'), + $('math', Z, 'textord', '\u2021', '\\ddag'), + $('text', Z, 'textord', '\u2021', '\\ddag'), + $('text', Z, 'textord', '\u2021', '\\textdaggerdbl'), + $('math', Z, 'close', '\u23b1', '\\rmoustache', !0), + $('math', Z, 'open', '\u23b0', '\\lmoustache', !0), + $('math', Z, 'close', '\u27ef', '\\rgroup', !0), + $('math', Z, 'open', '\u27ee', '\\lgroup', !0), + $('math', Z, J, '\u2213', '\\mp', !0), + $('math', Z, J, '\u2296', '\\ominus', !0), + $('math', Z, J, '\u228e', '\\uplus', !0), + $('math', Z, J, '\u2293', '\\sqcap', !0), + $('math', Z, J, '\u2217', '\\ast'), + $('math', Z, J, '\u2294', '\\sqcup', !0), + $('math', Z, J, '\u25ef', '\\bigcirc'), + $('math', Z, J, '\u2219', '\\bullet'), + $('math', Z, J, '\u2021', '\\ddagger'), + $('math', Z, J, '\u2240', '\\wr', !0), + $('math', Z, J, '\u2a3f', '\\amalg'), + $('math', Z, J, '&', '\\And'), + $('math', Z, et, '\u27f5', '\\longleftarrow', !0), + $('math', Z, et, '\u21d0', '\\Leftarrow', !0), + $('math', Z, et, '\u27f8', '\\Longleftarrow', !0), + $('math', Z, et, '\u27f6', '\\longrightarrow', !0), + $('math', Z, et, '\u21d2', '\\Rightarrow', !0), + $('math', Z, et, '\u27f9', '\\Longrightarrow', !0), + $('math', Z, et, '\u2194', '\\leftrightarrow', !0), + $('math', Z, et, '\u27f7', '\\longleftrightarrow', !0), + $('math', Z, et, '\u21d4', '\\Leftrightarrow', !0), + $('math', Z, et, '\u27fa', '\\Longleftrightarrow', !0), + $('math', Z, et, '\u21a6', '\\mapsto', !0), + $('math', Z, et, '\u27fc', '\\longmapsto', !0), + $('math', Z, et, '\u2197', '\\nearrow', !0), + $('math', Z, et, '\u21a9', '\\hookleftarrow', !0), + $('math', Z, et, '\u21aa', '\\hookrightarrow', !0), + $('math', Z, et, '\u2198', '\\searrow', !0), + $('math', Z, et, '\u21bc', '\\leftharpoonup', !0), + $('math', Z, et, '\u21c0', '\\rightharpoonup', !0), + $('math', Z, et, '\u2199', '\\swarrow', !0), + $('math', Z, et, '\u21bd', '\\leftharpoondown', !0), + $('math', Z, et, '\u21c1', '\\rightharpoondown', !0), + $('math', Z, et, '\u2196', '\\nwarrow', !0), + $('math', Z, et, '\u21cc', '\\rightleftharpoons', !0), + $('math', K, et, '\u226e', '\\nless', !0), + $('math', K, et, '\ue010', '\\@nleqslant'), + $('math', K, et, '\ue011', '\\@nleqq'), + $('math', K, et, '\u2a87', '\\lneq', !0), + $('math', K, et, '\u2268', '\\lneqq', !0), + $('math', K, et, '\ue00c', '\\@lvertneqq'), + $('math', K, et, '\u22e6', '\\lnsim', !0), + $('math', K, et, '\u2a89', '\\lnapprox', !0), + $('math', K, et, '\u2280', '\\nprec', !0), + $('math', K, et, '\u22e0', '\\npreceq', !0), + $('math', K, et, '\u22e8', '\\precnsim', !0), + $('math', K, et, '\u2ab9', '\\precnapprox', !0), + $('math', K, et, '\u2241', '\\nsim', !0), + $('math', K, et, '\ue006', '\\@nshortmid'), + $('math', K, et, '\u2224', '\\nmid', !0), + $('math', K, et, '\u22ac', '\\nvdash', !0), + $('math', K, et, '\u22ad', '\\nvDash', !0), + $('math', K, et, '\u22ea', '\\ntriangleleft'), + $('math', K, et, '\u22ec', '\\ntrianglelefteq', !0), + $('math', K, et, '\u228a', '\\subsetneq', !0), + $('math', K, et, '\ue01a', '\\@varsubsetneq'), + $('math', K, et, '\u2acb', '\\subsetneqq', !0), + $('math', K, et, '\ue017', '\\@varsubsetneqq'), + $('math', K, et, '\u226f', '\\ngtr', !0), + $('math', K, et, '\ue00f', '\\@ngeqslant'), + $('math', K, et, '\ue00e', '\\@ngeqq'), + $('math', K, et, '\u2a88', '\\gneq', !0), + $('math', K, et, '\u2269', '\\gneqq', !0), + $('math', K, et, '\ue00d', '\\@gvertneqq'), + $('math', K, et, '\u22e7', '\\gnsim', !0), + $('math', K, et, '\u2a8a', '\\gnapprox', !0), + $('math', K, et, '\u2281', '\\nsucc', !0), + $('math', K, et, '\u22e1', '\\nsucceq', !0), + $('math', K, et, '\u22e9', '\\succnsim', !0), + $('math', K, et, '\u2aba', '\\succnapprox', !0), + $('math', K, et, '\u2246', '\\ncong', !0), + $('math', K, et, '\ue007', '\\@nshortparallel'), + $('math', K, et, '\u2226', '\\nparallel', !0), + $('math', K, et, '\u22af', '\\nVDash', !0), + $('math', K, et, '\u22eb', '\\ntriangleright'), + $('math', K, et, '\u22ed', '\\ntrianglerighteq', !0), + $('math', K, et, '\ue018', '\\@nsupseteqq'), + $('math', K, et, '\u228b', '\\supsetneq', !0), + $('math', K, et, '\ue01b', '\\@varsupsetneq'), + $('math', K, et, '\u2acc', '\\supsetneqq', !0), + $('math', K, et, '\ue019', '\\@varsupsetneqq'), + $('math', K, et, '\u22ae', '\\nVdash', !0), + $('math', K, et, '\u2ab5', '\\precneqq', !0), + $('math', K, et, '\u2ab6', '\\succneqq', !0), + $('math', K, et, '\ue016', '\\@nsubseteqq'), + $('math', K, J, '\u22b4', '\\unlhd'), + $('math', K, J, '\u22b5', '\\unrhd'), + $('math', K, et, '\u219a', '\\nleftarrow', !0), + $('math', K, et, '\u219b', '\\nrightarrow', !0), + $('math', K, et, '\u21cd', '\\nLeftarrow', !0), + $('math', K, et, '\u21cf', '\\nRightarrow', !0), + $('math', K, et, '\u21ae', '\\nleftrightarrow', !0), + $('math', K, et, '\u21ce', '\\nLeftrightarrow', !0), + $('math', K, et, '\u25b3', '\\vartriangle'), + $('math', K, 'textord', '\u210f', '\\hslash'), + $('math', K, 'textord', '\u25bd', '\\triangledown'), + $('math', K, 'textord', '\u25ca', '\\lozenge'), + $('math', K, 'textord', '\u24c8', '\\circledS'), + $('math', K, 'textord', '\xae', '\\circledR'), + $('text', K, 'textord', '\xae', '\\circledR'), + $('math', K, 'textord', '\u2221', '\\measuredangle', !0), + $('math', K, 'textord', '\u2204', '\\nexists'), + $('math', K, 'textord', '\u2127', '\\mho'), + $('math', K, 'textord', '\u2132', '\\Finv', !0), + $('math', K, 'textord', '\u2141', '\\Game', !0), + $('math', K, 'textord', '\u2035', '\\backprime'), + $('math', K, 'textord', '\u25b2', '\\blacktriangle'), + $('math', K, 'textord', '\u25bc', '\\blacktriangledown'), + $('math', K, 'textord', '\u25a0', '\\blacksquare'), + $('math', K, 'textord', '\u29eb', '\\blacklozenge'), + $('math', K, 'textord', '\u2605', '\\bigstar'), + $('math', K, 'textord', '\u2222', '\\sphericalangle', !0), + $('math', K, 'textord', '\u2201', '\\complement', !0), + $('math', K, 'textord', '\xf0', '\\eth', !0), + $('text', Z, 'textord', '\xf0', '\xf0'), + $('math', K, 'textord', '\u2571', '\\diagup'), + $('math', K, 'textord', '\u2572', '\\diagdown'), + $('math', K, 'textord', '\u25a1', '\\square'), + $('math', K, 'textord', '\u25a1', '\\Box'), + $('math', K, 'textord', '\u25ca', '\\Diamond'), + $('math', K, 'textord', '\xa5', '\\yen', !0), + $('text', K, 'textord', '\xa5', '\\yen', !0), + $('math', K, 'textord', '\u2713', '\\checkmark', !0), + $('text', K, 'textord', '\u2713', '\\checkmark'), + $('math', K, 'textord', '\u2136', '\\beth', !0), + $('math', K, 'textord', '\u2138', '\\daleth', !0), + $('math', K, 'textord', '\u2137', '\\gimel', !0), + $('math', K, 'textord', '\u03dd', '\\digamma', !0), + $('math', K, 'textord', '\u03f0', '\\varkappa'), + $('math', K, 'open', '\u250c', '\\@ulcorner', !0), + $('math', K, 'close', '\u2510', '\\@urcorner', !0), + $('math', K, 'open', '\u2514', '\\@llcorner', !0), + $('math', K, 'close', '\u2518', '\\@lrcorner', !0), + $('math', K, et, '\u2266', '\\leqq', !0), + $('math', K, et, '\u2a7d', '\\leqslant', !0), + $('math', K, et, '\u2a95', '\\eqslantless', !0), + $('math', K, et, '\u2272', '\\lesssim', !0), + $('math', K, et, '\u2a85', '\\lessapprox', !0), + $('math', K, et, '\u224a', '\\approxeq', !0), + $('math', K, J, '\u22d6', '\\lessdot'), + $('math', K, et, '\u22d8', '\\lll', !0), + $('math', K, et, '\u2276', '\\lessgtr', !0), + $('math', K, et, '\u22da', '\\lesseqgtr', !0), + $('math', K, et, '\u2a8b', '\\lesseqqgtr', !0), + $('math', K, et, '\u2251', '\\doteqdot'), + $('math', K, et, '\u2253', '\\risingdotseq', !0), + $('math', K, et, '\u2252', '\\fallingdotseq', !0), + $('math', K, et, '\u223d', '\\backsim', !0), + $('math', K, et, '\u22cd', '\\backsimeq', !0), + $('math', K, et, '\u2ac5', '\\subseteqq', !0), + $('math', K, et, '\u22d0', '\\Subset', !0), + $('math', K, et, '\u228f', '\\sqsubset', !0), + $('math', K, et, '\u227c', '\\preccurlyeq', !0), + $('math', K, et, '\u22de', '\\curlyeqprec', !0), + $('math', K, et, '\u227e', '\\precsim', !0), + $('math', K, et, '\u2ab7', '\\precapprox', !0), + $('math', K, et, '\u22b2', '\\vartriangleleft'), + $('math', K, et, '\u22b4', '\\trianglelefteq'), + $('math', K, et, '\u22a8', '\\vDash', !0), + $('math', K, et, '\u22aa', '\\Vvdash', !0), + $('math', K, et, '\u2323', '\\smallsmile'), + $('math', K, et, '\u2322', '\\smallfrown'), + $('math', K, et, '\u224f', '\\bumpeq', !0), + $('math', K, et, '\u224e', '\\Bumpeq', !0), + $('math', K, et, '\u2267', '\\geqq', !0), + $('math', K, et, '\u2a7e', '\\geqslant', !0), + $('math', K, et, '\u2a96', '\\eqslantgtr', !0), + $('math', K, et, '\u2273', '\\gtrsim', !0), + $('math', K, et, '\u2a86', '\\gtrapprox', !0), + $('math', K, J, '\u22d7', '\\gtrdot'), + $('math', K, et, '\u22d9', '\\ggg', !0), + $('math', K, et, '\u2277', '\\gtrless', !0), + $('math', K, et, '\u22db', '\\gtreqless', !0), + $('math', K, et, '\u2a8c', '\\gtreqqless', !0), + $('math', K, et, '\u2256', '\\eqcirc', !0), + $('math', K, et, '\u2257', '\\circeq', !0), + $('math', K, et, '\u225c', '\\triangleq', !0), + $('math', K, et, '\u223c', '\\thicksim'), + $('math', K, et, '\u2248', '\\thickapprox'), + $('math', K, et, '\u2ac6', '\\supseteqq', !0), + $('math', K, et, '\u22d1', '\\Supset', !0), + $('math', K, et, '\u2290', '\\sqsupset', !0), + $('math', K, et, '\u227d', '\\succcurlyeq', !0), + $('math', K, et, '\u22df', '\\curlyeqsucc', !0), + $('math', K, et, '\u227f', '\\succsim', !0), + $('math', K, et, '\u2ab8', '\\succapprox', !0), + $('math', K, et, '\u22b3', '\\vartriangleright'), + $('math', K, et, '\u22b5', '\\trianglerighteq'), + $('math', K, et, '\u22a9', '\\Vdash', !0), + $('math', K, et, '\u2223', '\\shortmid'), + $('math', K, et, '\u2225', '\\shortparallel'), + $('math', K, et, '\u226c', '\\between', !0), + $('math', K, et, '\u22d4', '\\pitchfork', !0), + $('math', K, et, '\u221d', '\\varpropto'), + $('math', K, et, '\u25c0', '\\blacktriangleleft'), + $('math', K, et, '\u2234', '\\therefore', !0), + $('math', K, et, '\u220d', '\\backepsilon'), + $('math', K, et, '\u25b6', '\\blacktriangleright'), + $('math', K, et, '\u2235', '\\because', !0), + $('math', K, et, '\u22d8', '\\llless'), + $('math', K, et, '\u22d9', '\\gggtr'), + $('math', K, J, '\u22b2', '\\lhd'), + $('math', K, J, '\u22b3', '\\rhd'), + $('math', K, et, '\u2242', '\\eqsim', !0), + $('math', Z, et, '\u22c8', '\\Join'), + $('math', K, et, '\u2251', '\\Doteq', !0), + $('math', K, J, '\u2214', '\\dotplus', !0), + $('math', K, J, '\u2216', '\\smallsetminus'), + $('math', K, J, '\u22d2', '\\Cap', !0), + $('math', K, J, '\u22d3', '\\Cup', !0), + $('math', K, J, '\u2a5e', '\\doublebarwedge', !0), + $('math', K, J, '\u229f', '\\boxminus', !0), + $('math', K, J, '\u229e', '\\boxplus', !0), + $('math', K, J, '\u22c7', '\\divideontimes', !0), + $('math', K, J, '\u22c9', '\\ltimes', !0), + $('math', K, J, '\u22ca', '\\rtimes', !0), + $('math', K, J, '\u22cb', '\\leftthreetimes', !0), + $('math', K, J, '\u22cc', '\\rightthreetimes', !0), + $('math', K, J, '\u22cf', '\\curlywedge', !0), + $('math', K, J, '\u22ce', '\\curlyvee', !0), + $('math', K, J, '\u229d', '\\circleddash', !0), + $('math', K, J, '\u229b', '\\circledast', !0), + $('math', K, J, '\u22c5', '\\centerdot'), + $('math', K, J, '\u22ba', '\\intercal', !0), + $('math', K, J, '\u22d2', '\\doublecap'), + $('math', K, J, '\u22d3', '\\doublecup'), + $('math', K, J, '\u22a0', '\\boxtimes', !0), + $('math', K, et, '\u21e2', '\\dashrightarrow', !0), + $('math', K, et, '\u21e0', '\\dashleftarrow', !0), + $('math', K, et, '\u21c7', '\\leftleftarrows', !0), + $('math', K, et, '\u21c6', '\\leftrightarrows', !0), + $('math', K, et, '\u21da', '\\Lleftarrow', !0), + $('math', K, et, '\u219e', '\\twoheadleftarrow', !0), + $('math', K, et, '\u21a2', '\\leftarrowtail', !0), + $('math', K, et, '\u21ab', '\\looparrowleft', !0), + $('math', K, et, '\u21cb', '\\leftrightharpoons', !0), + $('math', K, et, '\u21b6', '\\curvearrowleft', !0), + $('math', K, et, '\u21ba', '\\circlearrowleft', !0), + $('math', K, et, '\u21b0', '\\Lsh', !0), + $('math', K, et, '\u21c8', '\\upuparrows', !0), + $('math', K, et, '\u21bf', '\\upharpoonleft', !0), + $('math', K, et, '\u21c3', '\\downharpoonleft', !0), + $('math', K, et, '\u22b8', '\\multimap', !0), + $('math', K, et, '\u21ad', '\\leftrightsquigarrow', !0), + $('math', K, et, '\u21c9', '\\rightrightarrows', !0), + $('math', K, et, '\u21c4', '\\rightleftarrows', !0), + $('math', K, et, '\u21a0', '\\twoheadrightarrow', !0), + $('math', K, et, '\u21a3', '\\rightarrowtail', !0), + $('math', K, et, '\u21ac', '\\looparrowright', !0), + $('math', K, et, '\u21b7', '\\curvearrowright', !0), + $('math', K, et, '\u21bb', '\\circlearrowright', !0), + $('math', K, et, '\u21b1', '\\Rsh', !0), + $('math', K, et, '\u21ca', '\\downdownarrows', !0), + $('math', K, et, '\u21be', '\\upharpoonright', !0), + $('math', K, et, '\u21c2', '\\downharpoonright', !0), + $('math', K, et, '\u21dd', '\\rightsquigarrow', !0), + $('math', K, et, '\u21dd', '\\leadsto'), + $('math', K, et, '\u21db', '\\Rrightarrow', !0), + $('math', K, et, '\u21be', '\\restriction'), + $('math', Z, 'textord', '\u2018', '`'), + $('math', Z, 'textord', '$', '\\$'), + $('text', Z, 'textord', '$', '\\$'), + $('text', Z, 'textord', '$', '\\textdollar'), + $('math', Z, 'textord', '%', '\\%'), + $('text', Z, 'textord', '%', '\\%'), + $('math', Z, 'textord', '_', '\\_'), + $('text', Z, 'textord', '_', '\\_'), + $('text', Z, 'textord', '_', '\\textunderscore'), + $('math', Z, 'textord', '\u2220', '\\angle', !0), + $('math', Z, 'textord', '\u221e', '\\infty', !0), + $('math', Z, 'textord', '\u2032', '\\prime'), + $('math', Z, 'textord', '\u25b3', '\\triangle'), + $('math', Z, 'textord', '\u0393', '\\Gamma', !0), + $('math', Z, 'textord', '\u0394', '\\Delta', !0), + $('math', Z, 'textord', '\u0398', '\\Theta', !0), + $('math', Z, 'textord', '\u039b', '\\Lambda', !0), + $('math', Z, 'textord', '\u039e', '\\Xi', !0), + $('math', Z, 'textord', '\u03a0', '\\Pi', !0), + $('math', Z, 'textord', '\u03a3', '\\Sigma', !0), + $('math', Z, 'textord', '\u03a5', '\\Upsilon', !0), + $('math', Z, 'textord', '\u03a6', '\\Phi', !0), + $('math', Z, 'textord', '\u03a8', '\\Psi', !0), + $('math', Z, 'textord', '\u03a9', '\\Omega', !0), + $('math', Z, 'textord', 'A', '\u0391'), + $('math', Z, 'textord', 'B', '\u0392'), + $('math', Z, 'textord', 'E', '\u0395'), + $('math', Z, 'textord', 'Z', '\u0396'), + $('math', Z, 'textord', 'H', '\u0397'), + $('math', Z, 'textord', 'I', '\u0399'), + $('math', Z, 'textord', 'K', '\u039a'), + $('math', Z, 'textord', 'M', '\u039c'), + $('math', Z, 'textord', 'N', '\u039d'), + $('math', Z, 'textord', 'O', '\u039f'), + $('math', Z, 'textord', 'P', '\u03a1'), + $('math', Z, 'textord', 'T', '\u03a4'), + $('math', Z, 'textord', 'X', '\u03a7'), + $('math', Z, 'textord', '\xac', '\\neg', !0), + $('math', Z, 'textord', '\xac', '\\lnot'), + $('math', Z, 'textord', '\u22a4', '\\top'), + $('math', Z, 'textord', '\u22a5', '\\bot'), + $('math', Z, 'textord', '\u2205', '\\emptyset'), + $('math', K, 'textord', '\u2205', '\\varnothing'), + $('math', Z, Q, '\u03b1', '\\alpha', !0), + $('math', Z, Q, '\u03b2', '\\beta', !0), + $('math', Z, Q, '\u03b3', '\\gamma', !0), + $('math', Z, Q, '\u03b4', '\\delta', !0), + $('math', Z, Q, '\u03f5', '\\epsilon', !0), + $('math', Z, Q, '\u03b6', '\\zeta', !0), + $('math', Z, Q, '\u03b7', '\\eta', !0), + $('math', Z, Q, '\u03b8', '\\theta', !0), + $('math', Z, Q, '\u03b9', '\\iota', !0), + $('math', Z, Q, '\u03ba', '\\kappa', !0), + $('math', Z, Q, '\u03bb', '\\lambda', !0), + $('math', Z, Q, '\u03bc', '\\mu', !0), + $('math', Z, Q, '\u03bd', '\\nu', !0), + $('math', Z, Q, '\u03be', '\\xi', !0), + $('math', Z, Q, '\u03bf', '\\omicron', !0), + $('math', Z, Q, '\u03c0', '\\pi', !0), + $('math', Z, Q, '\u03c1', '\\rho', !0), + $('math', Z, Q, '\u03c3', '\\sigma', !0), + $('math', Z, Q, '\u03c4', '\\tau', !0), + $('math', Z, Q, '\u03c5', '\\upsilon', !0), + $('math', Z, Q, '\u03d5', '\\phi', !0), + $('math', Z, Q, '\u03c7', '\\chi', !0), + $('math', Z, Q, '\u03c8', '\\psi', !0), + $('math', Z, Q, '\u03c9', '\\omega', !0), + $('math', Z, Q, '\u03b5', '\\varepsilon', !0), + $('math', Z, Q, '\u03d1', '\\vartheta', !0), + $('math', Z, Q, '\u03d6', '\\varpi', !0), + $('math', Z, Q, '\u03f1', '\\varrho', !0), + $('math', Z, Q, '\u03c2', '\\varsigma', !0), + $('math', Z, Q, '\u03c6', '\\varphi', !0), + $('math', Z, J, '\u2217', '*'), + $('math', Z, J, '+', '+'), + $('math', Z, J, '\u2212', '-'), + $('math', Z, J, '\u22c5', '\\cdot', !0), + $('math', Z, J, '\u2218', '\\circ'), + $('math', Z, J, '\xf7', '\\div', !0), + $('math', Z, J, '\xb1', '\\pm', !0), + $('math', Z, J, '\xd7', '\\times', !0), + $('math', Z, J, '\u2229', '\\cap', !0), + $('math', Z, J, '\u222a', '\\cup', !0), + $('math', Z, J, '\u2216', '\\setminus'), + $('math', Z, J, '\u2227', '\\land'), + $('math', Z, J, '\u2228', '\\lor'), + $('math', Z, J, '\u2227', '\\wedge', !0), + $('math', Z, J, '\u2228', '\\vee', !0), + $('math', Z, 'textord', '\u221a', '\\surd'), + $('math', Z, 'open', '\u27e8', '\\langle', !0), + $('math', Z, 'open', '\u2223', '\\lvert'), + $('math', Z, 'open', '\u2225', '\\lVert'), + $('math', Z, 'close', '?', '?'), + $('math', Z, 'close', '!', '!'), + $('math', Z, 'close', '\u27e9', '\\rangle', !0), + $('math', Z, 'close', '\u2223', '\\rvert'), + $('math', Z, 'close', '\u2225', '\\rVert'), + $('math', Z, et, '=', '='), + $('math', Z, et, ':', ':'), + $('math', Z, et, '\u2248', '\\approx', !0), + $('math', Z, et, '\u2245', '\\cong', !0), + $('math', Z, et, '\u2265', '\\ge'), + $('math', Z, et, '\u2265', '\\geq', !0), + $('math', Z, et, '\u2190', '\\gets'), + $('math', Z, et, '>', '\\gt', !0), + $('math', Z, et, '\u2208', '\\in', !0), + $('math', Z, et, '\ue020', '\\@not'), + $('math', Z, et, '\u2282', '\\subset', !0), + $('math', Z, et, '\u2283', '\\supset', !0), + $('math', Z, et, '\u2286', '\\subseteq', !0), + $('math', Z, et, '\u2287', '\\supseteq', !0), + $('math', K, et, '\u2288', '\\nsubseteq', !0), + $('math', K, et, '\u2289', '\\nsupseteq', !0), + $('math', Z, et, '\u22a8', '\\models'), + $('math', Z, et, '\u2190', '\\leftarrow', !0), + $('math', Z, et, '\u2264', '\\le'), + $('math', Z, et, '\u2264', '\\leq', !0), + $('math', Z, et, '<', '\\lt', !0), + $('math', Z, et, '\u2192', '\\rightarrow', !0), + $('math', Z, et, '\u2192', '\\to'), + $('math', K, et, '\u2271', '\\ngeq', !0), + $('math', K, et, '\u2270', '\\nleq', !0), + $('math', Z, 'spacing', '\xa0', '\\ '), + $('math', Z, 'spacing', '\xa0', '~'), + $('math', Z, 'spacing', '\xa0', '\\space'), + $('math', Z, 'spacing', '\xa0', '\\nobreakspace'), + $('text', Z, 'spacing', '\xa0', '\\ '), + $('text', Z, 'spacing', '\xa0', ' '), + $('text', Z, 'spacing', '\xa0', '~'), + $('text', Z, 'spacing', '\xa0', '\\space'), + $('text', Z, 'spacing', '\xa0', '\\nobreakspace'), + $('math', Z, 'spacing', null, '\\nobreak'), + $('math', Z, 'spacing', null, '\\allowbreak'), + $('math', Z, 'punct', ',', ','), + $('math', Z, 'punct', ';', ';'), + $('math', K, J, '\u22bc', '\\barwedge', !0), + $('math', K, J, '\u22bb', '\\veebar', !0), + $('math', Z, J, '\u2299', '\\odot', !0), + $('math', Z, J, '\u2295', '\\oplus', !0), + $('math', Z, J, '\u2297', '\\otimes', !0), + $('math', Z, 'textord', '\u2202', '\\partial', !0), + $('math', Z, J, '\u2298', '\\oslash', !0), + $('math', K, J, '\u229a', '\\circledcirc', !0), + $('math', K, J, '\u22a1', '\\boxdot', !0), + $('math', Z, J, '\u25b3', '\\bigtriangleup'), + $('math', Z, J, '\u25bd', '\\bigtriangledown'), + $('math', Z, J, '\u2020', '\\dagger'), + $('math', Z, J, '\u22c4', '\\diamond'), + $('math', Z, J, '\u22c6', '\\star'), + $('math', Z, J, '\u25c3', '\\triangleleft'), + $('math', Z, J, '\u25b9', '\\triangleright'), + $('math', Z, 'open', '{', '\\{'), + $('text', Z, 'textord', '{', '\\{'), + $('text', Z, 'textord', '{', '\\textbraceleft'), + $('math', Z, 'close', '}', '\\}'), + $('text', Z, 'textord', '}', '\\}'), + $('text', Z, 'textord', '}', '\\textbraceright'), + $('math', Z, 'open', '{', '\\lbrace'), + $('math', Z, 'close', '}', '\\rbrace'), + $('math', Z, 'open', '[', '\\lbrack', !0), + $('text', Z, 'textord', '[', '\\lbrack', !0), + $('math', Z, 'close', ']', '\\rbrack', !0), + $('text', Z, 'textord', ']', '\\rbrack', !0), + $('math', Z, 'open', '(', '\\lparen', !0), + $('math', Z, 'close', ')', '\\rparen', !0), + $('text', Z, 'textord', '<', '\\textless', !0), + $('text', Z, 'textord', '>', '\\textgreater', !0), + $('math', Z, 'open', '\u230a', '\\lfloor', !0), + $('math', Z, 'close', '\u230b', '\\rfloor', !0), + $('math', Z, 'open', '\u2308', '\\lceil', !0), + $('math', Z, 'close', '\u2309', '\\rceil', !0), + $('math', Z, 'textord', '\\', '\\backslash'), + $('math', Z, 'textord', '\u2223', '|'), + $('math', Z, 'textord', '\u2223', '\\vert'), + $('text', Z, 'textord', '|', '\\textbar', !0), + $('math', Z, 'textord', '\u2225', '\\|'), + $('math', Z, 'textord', '\u2225', '\\Vert'), + $('text', Z, 'textord', '\u2225', '\\textbardbl'), + $('text', Z, 'textord', '~', '\\textasciitilde'), + $('text', Z, 'textord', '\\', '\\textbackslash'), + $('text', Z, 'textord', '^', '\\textasciicircum'), + $('math', Z, et, '\u2191', '\\uparrow', !0), + $('math', Z, et, '\u21d1', '\\Uparrow', !0), + $('math', Z, et, '\u2193', '\\downarrow', !0), + $('math', Z, et, '\u21d3', '\\Downarrow', !0), + $('math', Z, et, '\u2195', '\\updownarrow', !0), + $('math', Z, et, '\u21d5', '\\Updownarrow', !0), + $('math', Z, tt, '\u2210', '\\coprod'), + $('math', Z, tt, '\u22c1', '\\bigvee'), + $('math', Z, tt, '\u22c0', '\\bigwedge'), + $('math', Z, tt, '\u2a04', '\\biguplus'), + $('math', Z, tt, '\u22c2', '\\bigcap'), + $('math', Z, tt, '\u22c3', '\\bigcup'), + $('math', Z, tt, '\u222b', '\\int'), + $('math', Z, tt, '\u222b', '\\intop'), + $('math', Z, tt, '\u222c', '\\iint'), + $('math', Z, tt, '\u222d', '\\iiint'), + $('math', Z, tt, '\u220f', '\\prod'), + $('math', Z, tt, '\u2211', '\\sum'), + $('math', Z, tt, '\u2a02', '\\bigotimes'), + $('math', Z, tt, '\u2a01', '\\bigoplus'), + $('math', Z, tt, '\u2a00', '\\bigodot'), + $('math', Z, tt, '\u222e', '\\oint'), + $('math', Z, tt, '\u2a06', '\\bigsqcup'), + $('math', Z, tt, '\u222b', '\\smallint'), + $('text', Z, 'inner', '\u2026', '\\textellipsis'), + $('math', Z, 'inner', '\u2026', '\\mathellipsis'), + $('text', Z, 'inner', '\u2026', '\\ldots', !0), + $('math', Z, 'inner', '\u2026', '\\ldots', !0), + $('math', Z, 'inner', '\u22ef', '\\@cdots', !0), + $('math', Z, 'inner', '\u22f1', '\\ddots', !0), + $('math', Z, 'textord', '\u22ee', '\\varvdots'), + $('math', Z, 'accent-token', '\u02ca', '\\acute'), + $('math', Z, 'accent-token', '\u02cb', '\\grave'), + $('math', Z, 'accent-token', '\xa8', '\\ddot'), + $('math', Z, 'accent-token', '~', '\\tilde'), + $('math', Z, 'accent-token', '\u02c9', '\\bar'), + $('math', Z, 'accent-token', '\u02d8', '\\breve'), + $('math', Z, 'accent-token', '\u02c7', '\\check'), + $('math', Z, 'accent-token', '^', '\\hat'), + $('math', Z, 'accent-token', '\u20d7', '\\vec'), + $('math', Z, 'accent-token', '\u02d9', '\\dot'), + $('math', Z, 'accent-token', '\u02da', '\\mathring'), + $('math', Z, Q, '\ue131', '\\@imath'), + $('math', Z, Q, '\ue237', '\\@jmath'), + $('math', Z, 'textord', '\u0131', '\u0131'), + $('math', Z, 'textord', '\u0237', '\u0237'), + $('text', Z, 'textord', '\u0131', '\\i', !0), + $('text', Z, 'textord', '\u0237', '\\j', !0), + $('text', Z, 'textord', '\xdf', '\\ss', !0), + $('text', Z, 'textord', '\xe6', '\\ae', !0), + $('text', Z, 'textord', '\u0153', '\\oe', !0), + $('text', Z, 'textord', '\xf8', '\\o', !0), + $('text', Z, 'textord', '\xc6', '\\AE', !0), + $('text', Z, 'textord', '\u0152', '\\OE', !0), + $('text', Z, 'textord', '\xd8', '\\O', !0), + $('text', Z, 'accent-token', '\u02ca', "\\'"), + $('text', Z, 'accent-token', '\u02cb', '\\`'), + $('text', Z, 'accent-token', '\u02c6', '\\^'), + $('text', Z, 'accent-token', '\u02dc', '\\~'), + $('text', Z, 'accent-token', '\u02c9', '\\='), + $('text', Z, 'accent-token', '\u02d8', '\\u'), + $('text', Z, 'accent-token', '\u02d9', '\\.'), + $('text', Z, 'accent-token', '\u02da', '\\r'), + $('text', Z, 'accent-token', '\u02c7', '\\v'), + $('text', Z, 'accent-token', '\xa8', '\\"'), + $('text', Z, 'accent-token', '\u02dd', '\\H'), + $('text', Z, 'accent-token', '\u25ef', '\\textcircled'); + var rt = { '--': !0, '---': !0, '``': !0, "''": !0 }; + $('text', Z, 'textord', '\u2013', '--', !0), + $('text', Z, 'textord', '\u2013', '\\textendash'), + $('text', Z, 'textord', '\u2014', '---', !0), + $('text', Z, 'textord', '\u2014', '\\textemdash'), + $('text', Z, 'textord', '\u2018', '`', !0), + $('text', Z, 'textord', '\u2018', '\\textquoteleft'), + $('text', Z, 'textord', '\u2019', "'", !0), + $('text', Z, 'textord', '\u2019', '\\textquoteright'), + $('text', Z, 'textord', '\u201c', '``', !0), + $('text', Z, 'textord', '\u201c', '\\textquotedblleft'), + $('text', Z, 'textord', '\u201d', "''", !0), + $('text', Z, 'textord', '\u201d', '\\textquotedblright'), + $('math', Z, 'textord', '\xb0', '\\degree', !0), + $('text', Z, 'textord', '\xb0', '\\degree'), + $('text', Z, 'textord', '\xb0', '\\textdegree', !0), + $('math', Z, 'textord', '\xa3', '\\pounds'), + $('math', Z, 'textord', '\xa3', '\\mathsterling', !0), + $('text', Z, 'textord', '\xa3', '\\pounds'), + $('text', Z, 'textord', '\xa3', '\\textsterling', !0), + $('math', K, 'textord', '\u2720', '\\maltese'), + $('text', K, 'textord', '\u2720', '\\maltese'); + for (var at = 0; at < '0123456789/@."'.length; at++) { + var nt = '0123456789/@."'.charAt(at); + $('math', Z, 'textord', nt, nt); + } + for (var it = 0; it < '0123456789!@*()-=+";:?/.,'.length; it++) { + var ot = '0123456789!@*()-=+";:?/.,'.charAt(it); + $('text', Z, 'textord', ot, ot); + } + for (var st = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', lt = 0; lt < st.length; lt++) { + var ht = st.charAt(lt); + $('math', Z, Q, ht, ht), $('text', Z, 'textord', ht, ht); + } + $('math', K, 'textord', 'C', '\u2102'), + $('text', K, 'textord', 'C', '\u2102'), + $('math', K, 'textord', 'H', '\u210d'), + $('text', K, 'textord', 'H', '\u210d'), + $('math', K, 'textord', 'N', '\u2115'), + $('text', K, 'textord', 'N', '\u2115'), + $('math', K, 'textord', 'P', '\u2119'), + $('text', K, 'textord', 'P', '\u2119'), + $('math', K, 'textord', 'Q', '\u211a'), + $('text', K, 'textord', 'Q', '\u211a'), + $('math', K, 'textord', 'R', '\u211d'), + $('text', K, 'textord', 'R', '\u211d'), + $('math', K, 'textord', 'Z', '\u2124'), + $('text', K, 'textord', 'Z', '\u2124'), + $('math', Z, Q, 'h', '\u210e'), + $('text', Z, Q, 'h', '\u210e'); + for (var mt = '', ct = 0; ct < st.length; ct++) { + var ut = st.charAt(ct); + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56320 + ct))), + $('text', Z, 'textord', ut, mt), + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56372 + ct))), + $('text', Z, 'textord', ut, mt), + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56424 + ct))), + $('text', Z, 'textord', ut, mt), + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56580 + ct))), + $('text', Z, 'textord', ut, mt), + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56736 + ct))), + $('text', Z, 'textord', ut, mt), + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56788 + ct))), + $('text', Z, 'textord', ut, mt), + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56840 + ct))), + $('text', Z, 'textord', ut, mt), + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56944 + ct))), + $('text', Z, 'textord', ut, mt), + ct < 26 && + ($('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56632 + ct))), + $('text', Z, 'textord', ut, mt), + $('math', Z, Q, ut, (mt = String.fromCharCode(55349, 56476 + ct))), + $('text', Z, 'textord', ut, mt)); + } + $('math', Z, Q, 'k', (mt = String.fromCharCode(55349, 56668))), $('text', Z, 'textord', 'k', mt); + for (var pt = 0; pt < 10; pt++) { + var dt = pt.toString(); + $('math', Z, Q, dt, (mt = String.fromCharCode(55349, 57294 + pt))), + $('text', Z, 'textord', dt, mt), + $('math', Z, Q, dt, (mt = String.fromCharCode(55349, 57314 + pt))), + $('text', Z, 'textord', dt, mt), + $('math', Z, Q, dt, (mt = String.fromCharCode(55349, 57324 + pt))), + $('text', Z, 'textord', dt, mt), + $('math', Z, Q, dt, (mt = String.fromCharCode(55349, 57334 + pt))), + $('text', Z, 'textord', dt, mt); + } + for (var ft = 0; ft < '\xc7\xd0\xde\xe7\xfe'.length; ft++) { + var gt = '\xc7\xd0\xde\xe7\xfe'.charAt(ft); + $('math', Z, Q, gt, gt), $('text', Z, 'textord', gt, gt); + } + var xt = [ + ['mathbf', 'textbf', 'Main-Bold'], + ['mathbf', 'textbf', 'Main-Bold'], + ['mathnormal', 'textit', 'Math-Italic'], + ['mathnormal', 'textit', 'Math-Italic'], + ['boldsymbol', 'boldsymbol', 'Main-BoldItalic'], + ['boldsymbol', 'boldsymbol', 'Main-BoldItalic'], + ['mathscr', 'textscr', 'Script-Regular'], + ['', '', ''], + ['', '', ''], + ['', '', ''], + ['mathfrak', 'textfrak', 'Fraktur-Regular'], + ['mathfrak', 'textfrak', 'Fraktur-Regular'], + ['mathbb', 'textbb', 'AMS-Regular'], + ['mathbb', 'textbb', 'AMS-Regular'], + ['', '', ''], + ['', '', ''], + ['mathsf', 'textsf', 'SansSerif-Regular'], + ['mathsf', 'textsf', 'SansSerif-Regular'], + ['mathboldsf', 'textboldsf', 'SansSerif-Bold'], + ['mathboldsf', 'textboldsf', 'SansSerif-Bold'], + ['mathitsf', 'textitsf', 'SansSerif-Italic'], + ['mathitsf', 'textitsf', 'SansSerif-Italic'], + ['', '', ''], + ['', '', ''], + ['mathtt', 'texttt', 'Typewriter-Regular'], + ['mathtt', 'texttt', 'Typewriter-Regular'], + ], + vt = [ + ['mathbf', 'textbf', 'Main-Bold'], + ['', '', ''], + ['mathsf', 'textsf', 'SansSerif-Regular'], + ['mathboldsf', 'textboldsf', 'SansSerif-Bold'], + ['mathtt', 'texttt', 'Typewriter-Regular'], + ], + bt = [ + [1, 1, 1], + [2, 1, 1], + [3, 1, 1], + [4, 2, 1], + [5, 2, 1], + [6, 3, 1], + [7, 4, 2], + [8, 6, 3], + [9, 7, 6], + [10, 8, 7], + [11, 10, 9], + ], + yt = [0.5, 0.6, 0.7, 0.8, 0.9, 1, 1.2, 1.44, 1.728, 2.074, 2.488], + wt = function (t, e) { + return e.size < 2 ? t : bt[t - 1][e.size - 1]; + }, + kt = (function () { + function t(e) { + (this.style = void 0), + (this.color = void 0), + (this.size = void 0), + (this.textSize = void 0), + (this.phantom = void 0), + (this.font = void 0), + (this.fontFamily = void 0), + (this.fontWeight = void 0), + (this.fontShape = void 0), + (this.sizeMultiplier = void 0), + (this.maxSize = void 0), + (this.minRuleThickness = void 0), + (this._fontMetrics = void 0), + (this.style = e.style), + (this.color = e.color), + (this.size = e.size || t.BASESIZE), + (this.textSize = e.textSize || this.size), + (this.phantom = !!e.phantom), + (this.font = e.font || ''), + (this.fontFamily = e.fontFamily || ''), + (this.fontWeight = e.fontWeight || ''), + (this.fontShape = e.fontShape || ''), + (this.sizeMultiplier = yt[this.size - 1]), + (this.maxSize = e.maxSize), + (this.minRuleThickness = e.minRuleThickness), + (this._fontMetrics = void 0); + } + var e = t.prototype; + return ( + (e.extend = function (e) { + var r = { + style: this.style, + size: this.size, + textSize: this.textSize, + color: this.color, + phantom: this.phantom, + font: this.font, + fontFamily: this.fontFamily, + fontWeight: this.fontWeight, + fontShape: this.fontShape, + maxSize: this.maxSize, + minRuleThickness: this.minRuleThickness, + }; + for (var a in e) e.hasOwnProperty(a) && (r[a] = e[a]); + return new t(r); + }), + (e.havingStyle = function (t) { + return this.style === t ? this : this.extend({ style: t, size: wt(this.textSize, t) }); + }), + (e.havingCrampedStyle = function () { + return this.havingStyle(this.style.cramp()); + }), + (e.havingSize = function (t) { + return this.size === t && this.textSize === t + ? this + : this.extend({ style: this.style.text(), size: t, textSize: t, sizeMultiplier: yt[t - 1] }); + }), + (e.havingBaseStyle = function (e) { + e = e || this.style.text(); + var r = wt(t.BASESIZE, e); + return this.size === r && this.textSize === t.BASESIZE && this.style === e ? this : this.extend({ style: e, size: r }); + }), + (e.havingBaseSizing = function () { + var t; + switch (this.style.id) { + case 4: + case 5: + t = 3; + break; + case 6: + case 7: + t = 1; + break; + default: + t = 6; + } + return this.extend({ style: this.style.text(), size: t }); + }), + (e.withColor = function (t) { + return this.extend({ color: t }); + }), + (e.withPhantom = function () { + return this.extend({ phantom: !0 }); + }), + (e.withFont = function (t) { + return this.extend({ font: t }); + }), + (e.withTextFontFamily = function (t) { + return this.extend({ fontFamily: t, font: '' }); + }), + (e.withTextFontWeight = function (t) { + return this.extend({ fontWeight: t, font: '' }); + }), + (e.withTextFontShape = function (t) { + return this.extend({ fontShape: t, font: '' }); + }), + (e.sizingClasses = function (t) { + return t.size !== this.size ? ['sizing', 'reset-size' + t.size, 'size' + this.size] : []; + }), + (e.baseSizingClasses = function () { + return this.size !== t.BASESIZE ? ['sizing', 'reset-size' + this.size, 'size' + t.BASESIZE] : []; + }), + (e.fontMetrics = function () { + return ( + this._fontMetrics || + (this._fontMetrics = (function (t) { + var e; + if (!Y[(e = t >= 5 ? 0 : t >= 3 ? 1 : 2)]) { + var r = (Y[e] = { cssEmPerMu: V.quad[e] / 18 }); + for (var a in V) V.hasOwnProperty(a) && (r[a] = V[a][e]); + } + return Y[e]; + })(this.size)), + this._fontMetrics + ); + }), + (e.getColor = function () { + return this.phantom ? 'transparent' : this.color; + }), + t + ); + })(); + kt.BASESIZE = 6; + var St = kt, + Mt = { + pt: 1, + mm: 7227 / 2540, + cm: 7227 / 254, + in: 72.27, + bp: 1.00375, + pc: 12, + dd: 1238 / 1157, + cc: 14856 / 1157, + nd: 685 / 642, + nc: 1370 / 107, + sp: 1 / 65536, + px: 1.00375, + }, + zt = { ex: !0, em: !0, mu: !0 }, + At = function (t) { + return 'string' != typeof t && (t = t.unit), t in Mt || t in zt || 'ex' === t; + }, + Tt = function (t, e) { + var r; + if (t.unit in Mt) r = Mt[t.unit] / e.fontMetrics().ptPerEm / e.sizeMultiplier; + else if ('mu' === t.unit) r = e.fontMetrics().cssEmPerMu; + else { + var a; + if (((a = e.style.isTight() ? e.havingStyle(e.style.text()) : e), 'ex' === t.unit)) r = a.fontMetrics().xHeight; + else { + if ('em' !== t.unit) throw new o("Invalid unit: '" + t.unit + "'"); + r = a.fontMetrics().quad; + } + a !== e && (r *= a.sizeMultiplier / e.sizeMultiplier); + } + return Math.min(t.number * r, e.maxSize); + }, + Bt = function (t, e, r) { + return j[r][t] && j[r][t].replace && (t = j[r][t].replace), { value: t, metrics: G(t, e, r) }; + }, + Ct = function (t, e, r, a, n) { + var i, + o = Bt(t, e, r), + s = o.metrics; + if (((t = o.value), s)) { + var l = s.italic; + ('text' === r || (a && 'mathit' === a.font)) && (l = 0), (i = new E(t, s.height, s.depth, l, s.skew, s.width, n)); + } else + 'undefined' != typeof console && console.warn("No character metrics for '" + t + "' in style '" + e + "' and mode '" + r + "'"), + (i = new E(t, 0, 0, 0, 0, 0, n)); + if (a) { + (i.maxFontSize = a.sizeMultiplier), a.style.isTight() && i.classes.push('mtight'); + var h = a.getColor(); + h && (i.style.color = h); + } + return i; + }, + qt = function (t, e) { + if (T(t.classes) !== T(e.classes) || t.skew !== e.skew || t.maxFontSize !== e.maxFontSize) return !1; + for (var r in t.style) if (t.style.hasOwnProperty(r) && t.style[r] !== e.style[r]) return !1; + for (var a in e.style) if (e.style.hasOwnProperty(a) && t.style[a] !== e.style[a]) return !1; + return !0; + }, + Nt = function (t) { + for (var e = 0, r = 0, a = 0, n = 0; n < t.children.length; n++) { + var i = t.children[n]; + i.height > e && (e = i.height), i.depth > r && (r = i.depth), i.maxFontSize > a && (a = i.maxFontSize); + } + (t.height = e), (t.depth = r), (t.maxFontSize = a); + }, + It = function (t, e, r, a) { + var n = new N(t, e, r, a); + return Nt(n), n; + }, + Ot = function (t, e, r, a) { + return new N(t, e, r, a); + }, + Rt = function (t) { + var e = new A(t); + return Nt(e), e; + }, + Et = function (t, e, r) { + var a = ''; + switch (t) { + case 'amsrm': + a = 'AMS'; + break; + case 'textrm': + a = 'Main'; + break; + case 'textsf': + a = 'SansSerif'; + break; + case 'texttt': + a = 'Typewriter'; + break; + default: + a = t; + } + return ( + a + '-' + ('textbf' === e && 'textit' === r ? 'BoldItalic' : 'textbf' === e ? 'Bold' : 'textit' === e ? 'Italic' : 'Regular') + ); + }, + Lt = { + mathbf: { variant: 'bold', fontName: 'Main-Bold' }, + mathrm: { variant: 'normal', fontName: 'Main-Regular' }, + textit: { variant: 'italic', fontName: 'Main-Italic' }, + mathit: { variant: 'italic', fontName: 'Main-Italic' }, + mathnormal: { variant: 'italic', fontName: 'Math-Italic' }, + mathbb: { variant: 'double-struck', fontName: 'AMS-Regular' }, + mathcal: { variant: 'script', fontName: 'Caligraphic-Regular' }, + mathfrak: { variant: 'fraktur', fontName: 'Fraktur-Regular' }, + mathscr: { variant: 'script', fontName: 'Script-Regular' }, + mathsf: { variant: 'sans-serif', fontName: 'SansSerif-Regular' }, + mathtt: { variant: 'monospace', fontName: 'Typewriter-Regular' }, + }, + Pt = { + vec: ['vec', 0.471, 0.714], + oiintSize1: ['oiintSize1', 0.957, 0.499], + oiintSize2: ['oiintSize2', 1.472, 0.659], + oiiintSize1: ['oiiintSize1', 1.304, 0.499], + oiiintSize2: ['oiiintSize2', 1.98, 0.659], + leftParenInner: ['leftParenInner', 0.875, 0.3], + rightParenInner: ['rightParenInner', 0.875, 0.3], + }, + Dt = { + fontMap: Lt, + makeSymbol: Ct, + mathsym: function (t, e, r, a) { + return ( + void 0 === a && (a = []), + 'boldsymbol' === r.font && Bt(t, 'Main-Bold', e).metrics + ? Ct(t, 'Main-Bold', e, r, a.concat(['mathbf'])) + : '\\' === t || 'main' === j[e][t].font + ? Ct(t, 'Main-Regular', e, r, a) + : Ct(t, 'AMS-Regular', e, r, a.concat(['amsrm'])) + ); + }, + makeSpan: It, + makeSvgSpan: Ot, + makeLineSpan: function (t, e, r) { + var a = It([t], [], e); + return ( + (a.height = Math.max(r || e.fontMetrics().defaultRuleThickness, e.minRuleThickness)), + (a.style.borderBottomWidth = a.height + 'em'), + (a.maxFontSize = 1), + a + ); + }, + makeAnchor: function (t, e, r, a) { + var n = new I(t, e, r, a); + return Nt(n), n; + }, + makeFragment: Rt, + wrapFragment: function (t, e) { + return t instanceof A ? It([], [t], e) : t; + }, + makeVList: function (t, e) { + for ( + var r = (function (t) { + if ('individualShift' === t.positionType) { + for (var e = t.children, r = [e[0]], a = -e[0].shift - e[0].elem.depth, n = a, i = 1; i < e.length; i++) { + var o = -e[i].shift - n - e[i].elem.depth, + s = o - (e[i - 1].elem.height + e[i - 1].elem.depth); + (n += o), r.push({ type: 'kern', size: s }), r.push(e[i]); + } + return { children: r, depth: a }; + } + var l; + if ('top' === t.positionType) { + for (var h = t.positionData, m = 0; m < t.children.length; m++) { + var c = t.children[m]; + h -= 'kern' === c.type ? c.size : c.elem.height + c.elem.depth; + } + l = h; + } else if ('bottom' === t.positionType) l = -t.positionData; + else { + var u = t.children[0]; + if ('elem' !== u.type) throw new Error('First child must have type "elem".'); + if ('shift' === t.positionType) l = -u.elem.depth - t.positionData; + else { + if ('firstBaseline' !== t.positionType) throw new Error('Invalid positionType ' + t.positionType + '.'); + l = -u.elem.depth; + } + } + return { children: t.children, depth: l }; + })(t), + a = r.children, + n = r.depth, + i = 0, + o = 0; + o < a.length; + o++ + ) { + var s = a[o]; + if ('elem' === s.type) { + var l = s.elem; + i = Math.max(i, l.maxFontSize, l.height); + } + } + i += 2; + var h = It(['pstrut'], []); + h.style.height = i + 'em'; + for (var m = [], c = n, u = n, p = n, d = 0; d < a.length; d++) { + var f = a[d]; + if ('kern' === f.type) p += f.size; + else { + var g = f.elem, + x = f.wrapperClasses || [], + v = f.wrapperStyle || {}, + b = It(x, [h, g], void 0, v); + (b.style.top = -i - p - g.depth + 'em'), + f.marginLeft && (b.style.marginLeft = f.marginLeft), + f.marginRight && (b.style.marginRight = f.marginRight), + m.push(b), + (p += g.height + g.depth); + } + (c = Math.min(c, p)), (u = Math.max(u, p)); + } + var y, + w = It(['vlist'], m); + if (((w.style.height = u + 'em'), c < 0)) { + var k = It([], []), + S = It(['vlist'], [k]); + S.style.height = -c + 'em'; + var M = It(['vlist-s'], [new E('\u200b')]); + y = [It(['vlist-r'], [w, M]), It(['vlist-r'], [S])]; + } else y = [It(['vlist-r'], [w])]; + var z = It(['vlist-t'], y); + return 2 === y.length && z.classes.push('vlist-t2'), (z.height = u), (z.depth = -c), z; + }, + makeOrd: function (t, e, r) { + var a = t.mode, + n = t.text, + i = ['mord'], + s = 'math' === a || ('text' === a && e.font), + l = s ? e.font : e.fontFamily; + if (55349 === n.charCodeAt(0)) { + var h = (function (t, e) { + var r = 1024 * (t.charCodeAt(0) - 55296) + (t.charCodeAt(1) - 56320) + 65536, + a = 'math' === e ? 0 : 1; + if (119808 <= r && r < 120484) { + var n = Math.floor((r - 119808) / 26); + return [xt[n][2], xt[n][a]]; + } + if (120782 <= r && r <= 120831) { + var i = Math.floor((r - 120782) / 10); + return [vt[i][2], vt[i][a]]; + } + if (120485 === r || 120486 === r) return [xt[0][2], xt[0][a]]; + if (120486 < r && r < 120782) return ['', '']; + throw new o('Unsupported character: ' + t); + })(n, a), + m = h[0], + c = h[1]; + return Ct(n, m, a, e, i.concat(c)); + } + if (l) { + var u, p; + if ('boldsymbol' === l) { + var d = (function (t, e, r, a, n) { + return 'textord' !== n && Bt(t, 'Math-BoldItalic', e).metrics + ? { fontName: 'Math-BoldItalic', fontClass: 'boldsymbol' } + : { fontName: 'Main-Bold', fontClass: 'mathbf' }; + })(n, a, 0, 0, r); + (u = d.fontName), (p = [d.fontClass]); + } else s ? ((u = Lt[l].fontName), (p = [l])) : ((u = Et(l, e.fontWeight, e.fontShape)), (p = [l, e.fontWeight, e.fontShape])); + if (Bt(n, u, a).metrics) return Ct(n, u, a, e, i.concat(p)); + if (rt.hasOwnProperty(n) && 'Typewriter' === u.substr(0, 10)) { + for (var f = [], g = 0; g < n.length; g++) f.push(Ct(n[g], u, a, e, i.concat(p))); + return Rt(f); + } + } + if ('mathord' === r) return Ct(n, 'Math-Italic', a, e, i.concat(['mathnormal'])); + if ('textord' === r) { + var x = j[a][n] && j[a][n].font; + if ('ams' === x) { + var v = Et('amsrm', e.fontWeight, e.fontShape); + return Ct(n, v, a, e, i.concat('amsrm', e.fontWeight, e.fontShape)); + } + if ('main' !== x && x) { + var b = Et(x, e.fontWeight, e.fontShape); + return Ct(n, b, a, e, i.concat(b, e.fontWeight, e.fontShape)); + } + var y = Et('textrm', e.fontWeight, e.fontShape); + return Ct(n, y, a, e, i.concat(e.fontWeight, e.fontShape)); + } + throw new Error('unexpected type: ' + r + ' in makeOrd'); + }, + makeGlue: function (t, e) { + var r = It(['mspace'], [], e), + a = Tt(t, e); + return (r.style.marginRight = a + 'em'), r; + }, + staticSvg: function (t, e) { + var r = Pt[t], + a = r[0], + n = r[1], + i = r[2], + o = new P(a), + s = new L([o], { + width: n + 'em', + height: i + 'em', + style: 'width:' + n + 'em', + viewBox: '0 0 ' + 1e3 * n + ' ' + 1e3 * i, + preserveAspectRatio: 'xMinYMin', + }), + l = Ot(['overlay'], [s], e); + return (l.height = i), (l.style.height = i + 'em'), (l.style.width = n + 'em'), l; + }, + svgData: Pt, + tryCombineChars: function (t) { + for (var e = 0; e < t.length - 1; e++) { + var r = t[e], + a = t[e + 1]; + r instanceof E && + a instanceof E && + qt(r, a) && + ((r.text += a.text), + (r.height = Math.max(r.height, a.height)), + (r.depth = Math.max(r.depth, a.depth)), + (r.italic = a.italic), + t.splice(e + 1, 1), + e--); + } + return t; + }, + }, + Ht = { number: 3, unit: 'mu' }, + Ft = { number: 4, unit: 'mu' }, + Vt = { number: 5, unit: 'mu' }, + Ut = { + mord: { mop: Ht, mbin: Ft, mrel: Vt, minner: Ht }, + mop: { mord: Ht, mop: Ht, mrel: Vt, minner: Ht }, + mbin: { mord: Ft, mop: Ft, mopen: Ft, minner: Ft }, + mrel: { mord: Vt, mop: Vt, mopen: Vt, minner: Vt }, + mopen: {}, + mclose: { mop: Ht, mbin: Ft, mrel: Vt, minner: Ht }, + mpunct: { mord: Ht, mop: Ht, mrel: Vt, mopen: Ht, mclose: Ht, mpunct: Ht, minner: Ht }, + minner: { mord: Ht, mop: Ht, mbin: Ft, mrel: Vt, mopen: Ht, mpunct: Ht, minner: Ht }, + }, + Gt = { + mord: { mop: Ht }, + mop: { mord: Ht, mop: Ht }, + mbin: {}, + mrel: {}, + mopen: {}, + mclose: { mop: Ht }, + mpunct: {}, + minner: { mop: Ht }, + }, + Yt = {}, + Wt = {}, + Xt = {}; + function _t(t) { + for ( + var e = t.type, + r = t.names, + a = t.props, + n = t.handler, + i = t.htmlBuilder, + o = t.mathmlBuilder, + s = { + type: e, + numArgs: a.numArgs, + argTypes: a.argTypes, + greediness: void 0 === a.greediness ? 1 : a.greediness, + allowedInText: !!a.allowedInText, + allowedInMath: void 0 === a.allowedInMath || a.allowedInMath, + numOptionalArgs: a.numOptionalArgs || 0, + infix: !!a.infix, + handler: n, + }, + l = 0; + l < r.length; + ++l + ) + Yt[r[l]] = s; + e && (i && (Wt[e] = i), o && (Xt[e] = o)); + } + function jt(t) { + _t({ + type: t.type, + names: [], + props: { numArgs: 0 }, + handler: function () { + throw new Error('Should never be called.'); + }, + htmlBuilder: t.htmlBuilder, + mathmlBuilder: t.mathmlBuilder, + }); + } + var $t = function (t) { + return 'ordgroup' === t.type ? t.body : [t]; + }, + Zt = Dt.makeSpan, + Kt = ['leftmost', 'mbin', 'mopen', 'mrel', 'mop', 'mpunct'], + Jt = ['rightmost', 'mrel', 'mclose', 'mpunct'], + Qt = { display: w.DISPLAY, text: w.TEXT, script: w.SCRIPT, scriptscript: w.SCRIPTSCRIPT }, + te = { mord: 'mord', mop: 'mop', mbin: 'mbin', mrel: 'mrel', mopen: 'mopen', mclose: 'mclose', mpunct: 'mpunct', minner: 'minner' }, + ee = function (t, e, r, a) { + void 0 === a && (a = [null, null]); + for (var n = [], i = 0; i < t.length; i++) { + var o = oe(t[i], e); + if (o instanceof A) { + var s = o.children; + n.push.apply(n, s); + } else n.push(o); + } + if (!r) return n; + var l = e; + if (1 === t.length) { + var h = t[0]; + 'sizing' === h.type ? (l = e.havingSize(h.size)) : 'styling' === h.type && (l = e.havingStyle(Qt[h.style])); + } + var m = Zt([a[0] || 'leftmost'], [], e), + u = Zt([a[1] || 'rightmost'], [], e), + p = 'root' === r; + return ( + re( + n, + function (t, e) { + var r = e.classes[0], + a = t.classes[0]; + 'mbin' === r && c.contains(Jt, a) ? (e.classes[0] = 'mord') : 'mbin' === a && c.contains(Kt, r) && (t.classes[0] = 'mord'); + }, + { node: m }, + u, + p + ), + re( + n, + function (t, e) { + var r = ne(e), + a = ne(t), + n = r && a ? (t.hasClass('mtight') ? Gt[r][a] : Ut[r][a]) : null; + if (n) return Dt.makeGlue(n, l); + }, + { node: m }, + u, + p + ), + n + ); + }, + re = function t(e, r, a, n, i) { + n && e.push(n); + for (var o = 0; o < e.length; o++) { + var s = e[o], + l = ae(s); + if (l) t(l.children, r, a, null, i); + else { + var h = !s.hasClass('mspace'); + if (h) { + var m = r(s, a.node); + m && (a.insertAfter ? a.insertAfter(m) : (e.unshift(m), o++)); + } + h ? (a.node = s) : i && s.hasClass('newline') && (a.node = Zt(['leftmost'])), + (a.insertAfter = (function (t) { + return function (r) { + e.splice(t + 1, 0, r), o++; + }; + })(o)); + } + } + n && e.pop(); + }, + ae = function (t) { + return t instanceof A || t instanceof I || (t instanceof N && t.hasClass('enclosing')) ? t : null; + }, + ne = function (t, e) { + return t + ? (e && + (t = (function t(e, r) { + var a = ae(e); + if (a) { + var n = a.children; + if (n.length) { + if ('right' === r) return t(n[n.length - 1], 'right'); + if ('left' === r) return t(n[0], 'left'); + } + } + return e; + })(t, e)), + te[t.classes[0]] || null) + : null; + }, + ie = function (t, e) { + var r = ['nulldelimiter'].concat(t.baseSizingClasses()); + return Zt(e.concat(r)); + }, + oe = function (t, e, r) { + if (!t) return Zt(); + if (Wt[t.type]) { + var a = Wt[t.type](t, e); + if (r && e.size !== r.size) { + a = Zt(e.sizingClasses(r), [a], e); + var n = e.sizeMultiplier / r.sizeMultiplier; + (a.height *= n), (a.depth *= n); + } + return a; + } + throw new o("Got group of unknown type: '" + t.type + "'"); + }; + function se(t, e) { + var r = Zt(['base'], t, e), + a = Zt(['strut']); + return (a.style.height = r.height + r.depth + 'em'), (a.style.verticalAlign = -r.depth + 'em'), r.children.unshift(a), r; + } + function le(t, e) { + var r = null; + 1 === t.length && 'tag' === t[0].type && ((r = t[0].tag), (t = t[0].body)); + for (var a, n = ee(t, e, 'root'), i = [], o = [], s = 0; s < n.length; s++) + if ((o.push(n[s]), n[s].hasClass('mbin') || n[s].hasClass('mrel') || n[s].hasClass('allowbreak'))) { + for (var l = !1; s < n.length - 1 && n[s + 1].hasClass('mspace') && !n[s + 1].hasClass('newline'); ) + s++, o.push(n[s]), n[s].hasClass('nobreak') && (l = !0); + l || (i.push(se(o, e)), (o = [])); + } else n[s].hasClass('newline') && (o.pop(), o.length > 0 && (i.push(se(o, e)), (o = [])), i.push(n[s])); + o.length > 0 && i.push(se(o, e)), r && (((a = se(ee(r, e, !0))).classes = ['tag']), i.push(a)); + var h = Zt(['katex-html'], i); + if ((h.setAttribute('aria-hidden', 'true'), a)) { + var m = a.children[0]; + (m.style.height = h.height + h.depth + 'em'), (m.style.verticalAlign = -h.depth + 'em'); + } + return h; + } + function he(t) { + return new A(t); + } + var me = (function () { + function t(t, e) { + (this.type = void 0), + (this.attributes = void 0), + (this.children = void 0), + (this.type = t), + (this.attributes = {}), + (this.children = e || []); + } + var e = t.prototype; + return ( + (e.setAttribute = function (t, e) { + this.attributes[t] = e; + }), + (e.getAttribute = function (t) { + return this.attributes[t]; + }), + (e.toNode = function () { + var t = document.createElementNS('http://www.w3.org/1998/Math/MathML', this.type); + for (var e in this.attributes) + Object.prototype.hasOwnProperty.call(this.attributes, e) && t.setAttribute(e, this.attributes[e]); + for (var r = 0; r < this.children.length; r++) t.appendChild(this.children[r].toNode()); + return t; + }), + (e.toMarkup = function () { + var t = '<' + this.type; + for (var e in this.attributes) + Object.prototype.hasOwnProperty.call(this.attributes, e) && + ((t += ' ' + e + '="'), (t += c.escape(this.attributes[e])), (t += '"')); + t += '>'; + for (var r = 0; r < this.children.length; r++) t += this.children[r].toMarkup(); + return (t += '</' + this.type + '>'); + }), + (e.toText = function () { + return this.children + .map(function (t) { + return t.toText(); + }) + .join(''); + }), + t + ); + })(), + ce = (function () { + function t(t) { + (this.text = void 0), (this.text = t); + } + var e = t.prototype; + return ( + (e.toNode = function () { + return document.createTextNode(this.text); + }), + (e.toMarkup = function () { + return c.escape(this.toText()); + }), + (e.toText = function () { + return this.text; + }), + t + ); + })(), + ue = { + MathNode: me, + TextNode: ce, + SpaceNode: (function () { + function t(t) { + (this.width = void 0), + (this.character = void 0), + (this.width = t), + (this.character = + t >= 0.05555 && t <= 0.05556 + ? '\u200a' + : t >= 0.1666 && t <= 0.1667 + ? '\u2009' + : t >= 0.2222 && t <= 0.2223 + ? '\u2005' + : t >= 0.2777 && t <= 0.2778 + ? '\u2005\u200a' + : t >= -0.05556 && t <= -0.05555 + ? '\u200a\u2063' + : t >= -0.1667 && t <= -0.1666 + ? '\u2009\u2063' + : t >= -0.2223 && t <= -0.2222 + ? '\u205f\u2063' + : t >= -0.2778 && t <= -0.2777 + ? '\u2005\u2063' + : null); + } + var e = t.prototype; + return ( + (e.toNode = function () { + if (this.character) return document.createTextNode(this.character); + var t = document.createElementNS('http://www.w3.org/1998/Math/MathML', 'mspace'); + return t.setAttribute('width', this.width + 'em'), t; + }), + (e.toMarkup = function () { + return this.character ? '<mtext>' + this.character + '</mtext>' : '<mspace width="' + this.width + 'em"/>'; + }), + (e.toText = function () { + return this.character ? this.character : ' '; + }), + t + ); + })(), + newDocumentFragment: he, + }, + pe = function (t, e, r) { + return ( + !j[e][t] || + !j[e][t].replace || + 55349 === t.charCodeAt(0) || + (rt.hasOwnProperty(t) && + r && + ((r.fontFamily && 'tt' === r.fontFamily.substr(4, 2)) || (r.font && 'tt' === r.font.substr(4, 2)))) || + (t = j[e][t].replace), + new ue.TextNode(t) + ); + }, + de = function (t) { + return 1 === t.length ? t[0] : new ue.MathNode('mrow', t); + }, + fe = function (t, e) { + if ('texttt' === e.fontFamily) return 'monospace'; + if ('textsf' === e.fontFamily) + return 'textit' === e.fontShape && 'textbf' === e.fontWeight + ? 'sans-serif-bold-italic' + : 'textit' === e.fontShape + ? 'sans-serif-italic' + : 'textbf' === e.fontWeight + ? 'bold-sans-serif' + : 'sans-serif'; + if ('textit' === e.fontShape && 'textbf' === e.fontWeight) return 'bold-italic'; + if ('textit' === e.fontShape) return 'italic'; + if ('textbf' === e.fontWeight) return 'bold'; + var r = e.font; + if (!r || 'mathnormal' === r) return null; + var a = t.mode; + if ('mathit' === r) return 'italic'; + if ('boldsymbol' === r) return 'textord' === t.type ? 'bold' : 'bold-italic'; + if ('mathbf' === r) return 'bold'; + if ('mathbb' === r) return 'double-struck'; + if ('mathfrak' === r) return 'fraktur'; + if ('mathscr' === r || 'mathcal' === r) return 'script'; + if ('mathsf' === r) return 'sans-serif'; + if ('mathtt' === r) return 'monospace'; + var n = t.text; + return c.contains(['\\imath', '\\jmath'], n) + ? null + : (j[a][n] && j[a][n].replace && (n = j[a][n].replace), G(n, Dt.fontMap[r].fontName, a) ? Dt.fontMap[r].variant : null); + }, + ge = function (t, e, r) { + if (1 === t.length) { + var a = ve(t[0], e); + return r && a instanceof me && 'mo' === a.type && (a.setAttribute('lspace', '0em'), a.setAttribute('rspace', '0em')), [a]; + } + for (var n, i = [], o = 0; o < t.length; o++) { + var s = ve(t[o], e); + if (s instanceof me && n instanceof me) { + if ('mtext' === s.type && 'mtext' === n.type && s.getAttribute('mathvariant') === n.getAttribute('mathvariant')) { + var l; + (l = n.children).push.apply(l, s.children); + continue; + } + if ('mn' === s.type && 'mn' === n.type) { + var h; + (h = n.children).push.apply(h, s.children); + continue; + } + if ('mi' === s.type && 1 === s.children.length && 'mn' === n.type) { + var m = s.children[0]; + if (m instanceof ce && '.' === m.text) { + var c; + (c = n.children).push.apply(c, s.children); + continue; + } + } else if ('mi' === n.type && 1 === n.children.length) { + var u = n.children[0]; + if (u instanceof ce && '\u0338' === u.text && ('mo' === s.type || 'mi' === s.type || 'mn' === s.type)) { + var p = s.children[0]; + p instanceof ce && p.text.length > 0 && ((p.text = p.text.slice(0, 1) + '\u0338' + p.text.slice(1)), i.pop()); + } + } + } + i.push(s), (n = s); + } + return i; + }, + xe = function (t, e, r) { + return de(ge(t, e, r)); + }, + ve = function (t, e) { + if (!t) return new ue.MathNode('mrow'); + if (Xt[t.type]) return Xt[t.type](t, e); + throw new o("Got group of unknown type: '" + t.type + "'"); + }; + function be(t, e, r, a, n) { + var i, + o = ge(t, r); + i = 1 === o.length && o[0] instanceof me && c.contains(['mrow', 'mtable'], o[0].type) ? o[0] : new ue.MathNode('mrow', o); + var s = new ue.MathNode('annotation', [new ue.TextNode(e)]); + s.setAttribute('encoding', 'application/x-tex'); + var l = new ue.MathNode('semantics', [i, s]), + h = new ue.MathNode('math', [l]); + h.setAttribute('xmlns', 'http://www.w3.org/1998/Math/MathML'), a && h.setAttribute('display', 'block'); + var m = n ? 'katex' : 'katex-mathml'; + return Dt.makeSpan([m], [h]); + } + var ye = function (t) { + return new St({ style: t.displayMode ? w.DISPLAY : w.TEXT, maxSize: t.maxSize, minRuleThickness: t.minRuleThickness }); + }, + we = function (t, e) { + if (e.displayMode) { + var r = ['katex-display']; + e.leqno && r.push('leqno'), e.fleqn && r.push('fleqn'), (t = Dt.makeSpan(r, [t])); + } + return t; + }, + ke = function (t, e, r) { + var a, + n = ye(r); + if ('mathml' === r.output) return be(t, e, n, r.displayMode, !0); + if ('html' === r.output) { + var i = le(t, n); + a = Dt.makeSpan(['katex'], [i]); + } else { + var o = be(t, e, n, r.displayMode, !1), + s = le(t, n); + a = Dt.makeSpan(['katex'], [o, s]); + } + return we(a, r); + }, + Se = { + widehat: '^', + widecheck: '\u02c7', + widetilde: '~', + utilde: '~', + overleftarrow: '\u2190', + underleftarrow: '\u2190', + xleftarrow: '\u2190', + overrightarrow: '\u2192', + underrightarrow: '\u2192', + xrightarrow: '\u2192', + underbrace: '\u23df', + overbrace: '\u23de', + overgroup: '\u23e0', + undergroup: '\u23e1', + overleftrightarrow: '\u2194', + underleftrightarrow: '\u2194', + xleftrightarrow: '\u2194', + Overrightarrow: '\u21d2', + xRightarrow: '\u21d2', + overleftharpoon: '\u21bc', + xleftharpoonup: '\u21bc', + overrightharpoon: '\u21c0', + xrightharpoonup: '\u21c0', + xLeftarrow: '\u21d0', + xLeftrightarrow: '\u21d4', + xhookleftarrow: '\u21a9', + xhookrightarrow: '\u21aa', + xmapsto: '\u21a6', + xrightharpoondown: '\u21c1', + xleftharpoondown: '\u21bd', + xrightleftharpoons: '\u21cc', + xleftrightharpoons: '\u21cb', + xtwoheadleftarrow: '\u219e', + xtwoheadrightarrow: '\u21a0', + xlongequal: '=', + xtofrom: '\u21c4', + xrightleftarrows: '\u21c4', + xrightequilibrium: '\u21cc', + xleftequilibrium: '\u21cb', + }, + Me = { + overrightarrow: [['rightarrow'], 0.888, 522, 'xMaxYMin'], + overleftarrow: [['leftarrow'], 0.888, 522, 'xMinYMin'], + underrightarrow: [['rightarrow'], 0.888, 522, 'xMaxYMin'], + underleftarrow: [['leftarrow'], 0.888, 522, 'xMinYMin'], + xrightarrow: [['rightarrow'], 1.469, 522, 'xMaxYMin'], + xleftarrow: [['leftarrow'], 1.469, 522, 'xMinYMin'], + Overrightarrow: [['doublerightarrow'], 0.888, 560, 'xMaxYMin'], + xRightarrow: [['doublerightarrow'], 1.526, 560, 'xMaxYMin'], + xLeftarrow: [['doubleleftarrow'], 1.526, 560, 'xMinYMin'], + overleftharpoon: [['leftharpoon'], 0.888, 522, 'xMinYMin'], + xleftharpoonup: [['leftharpoon'], 0.888, 522, 'xMinYMin'], + xleftharpoondown: [['leftharpoondown'], 0.888, 522, 'xMinYMin'], + overrightharpoon: [['rightharpoon'], 0.888, 522, 'xMaxYMin'], + xrightharpoonup: [['rightharpoon'], 0.888, 522, 'xMaxYMin'], + xrightharpoondown: [['rightharpoondown'], 0.888, 522, 'xMaxYMin'], + xlongequal: [['longequal'], 0.888, 334, 'xMinYMin'], + xtwoheadleftarrow: [['twoheadleftarrow'], 0.888, 334, 'xMinYMin'], + xtwoheadrightarrow: [['twoheadrightarrow'], 0.888, 334, 'xMaxYMin'], + overleftrightarrow: [['leftarrow', 'rightarrow'], 0.888, 522], + overbrace: [['leftbrace', 'midbrace', 'rightbrace'], 1.6, 548], + underbrace: [['leftbraceunder', 'midbraceunder', 'rightbraceunder'], 1.6, 548], + underleftrightarrow: [['leftarrow', 'rightarrow'], 0.888, 522], + xleftrightarrow: [['leftarrow', 'rightarrow'], 1.75, 522], + xLeftrightarrow: [['doubleleftarrow', 'doublerightarrow'], 1.75, 560], + xrightleftharpoons: [['leftharpoondownplus', 'rightharpoonplus'], 1.75, 716], + xleftrightharpoons: [['leftharpoonplus', 'rightharpoondownplus'], 1.75, 716], + xhookleftarrow: [['leftarrow', 'righthook'], 1.08, 522], + xhookrightarrow: [['lefthook', 'rightarrow'], 1.08, 522], + overlinesegment: [['leftlinesegment', 'rightlinesegment'], 0.888, 522], + underlinesegment: [['leftlinesegment', 'rightlinesegment'], 0.888, 522], + overgroup: [['leftgroup', 'rightgroup'], 0.888, 342], + undergroup: [['leftgroupunder', 'rightgroupunder'], 0.888, 342], + xmapsto: [['leftmapsto', 'rightarrow'], 1.5, 522], + xtofrom: [['leftToFrom', 'rightToFrom'], 1.75, 528], + xrightleftarrows: [['baraboveleftarrow', 'rightarrowabovebar'], 1.75, 901], + xrightequilibrium: [['baraboveshortleftharpoon', 'rightharpoonaboveshortbar'], 1.75, 716], + xleftequilibrium: [['shortbaraboveleftharpoon', 'shortrightharpoonabovebar'], 1.75, 716], + }, + ze = function (t) { + return 'ordgroup' === t.type ? t.body.length : 1; + }, + Ae = function (t, e, r, a) { + var n, + i = t.height + t.depth + 2 * r; + if (/fbox|color/.test(e)) { + if (((n = Dt.makeSpan(['stretchy', e], [], a)), 'fbox' === e)) { + var o = a.color && a.getColor(); + o && (n.style.borderColor = o); + } + } else { + var s = []; + /^[bx]cancel$/.test(e) && s.push(new D({ x1: '0', y1: '0', x2: '100%', y2: '100%', 'stroke-width': '0.046em' })), + /^x?cancel$/.test(e) && s.push(new D({ x1: '0', y1: '100%', x2: '100%', y2: '0', 'stroke-width': '0.046em' })); + var l = new L(s, { width: '100%', height: i + 'em' }); + n = Dt.makeSvgSpan([], [l], a); + } + return (n.height = i), (n.style.height = i + 'em'), n; + }, + Te = function (t) { + var e = new ue.MathNode('mo', [new ue.TextNode(Se[t.substr(1)])]); + return e.setAttribute('stretchy', 'true'), e; + }, + Be = function (t, e) { + var r = (function () { + var r = 4e5, + a = t.label.substr(1); + if (c.contains(['widehat', 'widecheck', 'widetilde', 'utilde'], a)) { + var n, + i, + o, + s = ze(t.base); + if (s > 5) + 'widehat' === a || 'widecheck' === a + ? ((n = 420), (r = 2364), (o = 0.42), (i = a + '4')) + : ((n = 312), (r = 2340), (o = 0.34), (i = 'tilde4')); + else { + var l = [1, 1, 2, 2, 3, 3][s]; + 'widehat' === a || 'widecheck' === a + ? ((r = [0, 1062, 2364, 2364, 2364][l]), + (n = [0, 239, 300, 360, 420][l]), + (o = [0, 0.24, 0.3, 0.3, 0.36, 0.42][l]), + (i = a + l)) + : ((r = [0, 600, 1033, 2339, 2340][l]), + (n = [0, 260, 286, 306, 312][l]), + (o = [0, 0.26, 0.286, 0.3, 0.306, 0.34][l]), + (i = 'tilde' + l)); + } + var h = new P(i), + m = new L([h], { width: '100%', height: o + 'em', viewBox: '0 0 ' + r + ' ' + n, preserveAspectRatio: 'none' }); + return { span: Dt.makeSvgSpan([], [m], e), minWidth: 0, height: o }; + } + var u, + p, + d = [], + f = Me[a], + g = f[0], + x = f[1], + v = f[2], + b = v / 1e3, + y = g.length; + if (1 === y) (u = ['hide-tail']), (p = [f[3]]); + else if (2 === y) (u = ['halfarrow-left', 'halfarrow-right']), (p = ['xMinYMin', 'xMaxYMin']); + else { + if (3 !== y) + throw new Error('Correct katexImagesData or update code here to support\n ' + y + ' children.'); + (u = ['brace-left', 'brace-center', 'brace-right']), (p = ['xMinYMin', 'xMidYMin', 'xMaxYMin']); + } + for (var w = 0; w < y; w++) { + var k = new P(g[w]), + S = new L([k], { width: '400em', height: b + 'em', viewBox: '0 0 ' + r + ' ' + v, preserveAspectRatio: p[w] + ' slice' }), + M = Dt.makeSvgSpan([u[w]], [S], e); + if (1 === y) return { span: M, minWidth: x, height: b }; + (M.style.height = b + 'em'), d.push(M); + } + return { span: Dt.makeSpan(['stretchy'], d, e), minWidth: x, height: b }; + })(), + a = r.span, + n = r.minWidth, + i = r.height; + return (a.height = i), (a.style.height = i + 'em'), n > 0 && (a.style.minWidth = n + 'em'), a; + }; + function Ce(t, e) { + if (!t || t.type !== e) throw new Error('Expected node of type ' + e + ', but got ' + (t ? 'node of type ' + t.type : String(t))); + return t; + } + function qe(t) { + var e = Ne(t); + if (!e) throw new Error('Expected node of symbol group type, but got ' + (t ? 'node of type ' + t.type : String(t))); + return e; + } + function Ne(t) { + return t && ('atom' === t.type || X.hasOwnProperty(t.type)) ? t : null; + } + var Ie = function (t, e) { + var r, a, n; + t && 'supsub' === t.type + ? ((r = (a = Ce(t.base, 'accent')).base), + (t.base = r), + (n = (function (t) { + if (t instanceof N) return t; + throw new Error('Expected span<HtmlDomNode> but got ' + String(t) + '.'); + })(oe(t, e))), + (t.base = a)) + : (r = (a = Ce(t, 'accent')).base); + var i = oe(r, e.havingCrampedStyle()), + o = 0; + if (a.isShifty && c.isCharacterBox(r)) { + var s = c.getBaseElem(r); + o = H(oe(s, e.havingCrampedStyle())).skew; + } + var l, + h = Math.min(i.height, e.fontMetrics().xHeight); + if (a.isStretchy) + (l = Be(a, e)), + (l = Dt.makeVList( + { + positionType: 'firstBaseline', + children: [ + { type: 'elem', elem: i }, + { + type: 'elem', + elem: l, + wrapperClasses: ['svg-align'], + wrapperStyle: o > 0 ? { width: 'calc(100% - ' + 2 * o + 'em)', marginLeft: 2 * o + 'em' } : void 0, + }, + ], + }, + e + )); + else { + var m, u; + '\\vec' === a.label + ? ((m = Dt.staticSvg('vec', e)), (u = Dt.svgData.vec[1])) + : (((m = H((m = Dt.makeOrd({ mode: a.mode, text: a.label }, e, 'textord')))).italic = 0), (u = m.width)), + (l = Dt.makeSpan(['accent-body'], [m])); + var p = '\\textcircled' === a.label; + p && (l.classes.push('accent-full'), (h = i.height)); + var d = o; + p || (d -= u / 2), + (l.style.left = d + 'em'), + '\\textcircled' === a.label && (l.style.top = '.2em'), + (l = Dt.makeVList( + { + positionType: 'firstBaseline', + children: [ + { type: 'elem', elem: i }, + { type: 'kern', size: -h }, + { type: 'elem', elem: l }, + ], + }, + e + )); + } + var f = Dt.makeSpan(['mord', 'accent'], [l], e); + return n ? ((n.children[0] = f), (n.height = Math.max(f.height, n.height)), (n.classes[0] = 'mord'), n) : f; + }, + Oe = function (t, e) { + var r = t.isStretchy ? Te(t.label) : new ue.MathNode('mo', [pe(t.label, t.mode)]), + a = new ue.MathNode('mover', [ve(t.base, e), r]); + return a.setAttribute('accent', 'true'), a; + }, + Re = new RegExp( + ['\\acute', '\\grave', '\\ddot', '\\tilde', '\\bar', '\\breve', '\\check', '\\hat', '\\vec', '\\dot', '\\mathring'] + .map(function (t) { + return '\\' + t; + }) + .join('|') + ); + _t({ + type: 'accent', + names: [ + '\\acute', + '\\grave', + '\\ddot', + '\\tilde', + '\\bar', + '\\breve', + '\\check', + '\\hat', + '\\vec', + '\\dot', + '\\mathring', + '\\widecheck', + '\\widehat', + '\\widetilde', + '\\overrightarrow', + '\\overleftarrow', + '\\Overrightarrow', + '\\overleftrightarrow', + '\\overgroup', + '\\overlinesegment', + '\\overleftharpoon', + '\\overrightharpoon', + ], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = e[0], + a = !Re.test(t.funcName), + n = !a || '\\widehat' === t.funcName || '\\widetilde' === t.funcName || '\\widecheck' === t.funcName; + return { type: 'accent', mode: t.parser.mode, label: t.funcName, isStretchy: a, isShifty: n, base: r }; + }, + htmlBuilder: Ie, + mathmlBuilder: Oe, + }), + _t({ + type: 'accent', + names: ["\\'", '\\`', '\\^', '\\~', '\\=', '\\u', '\\.', '\\"', '\\r', '\\H', '\\v', '\\textcircled'], + props: { numArgs: 1, allowedInText: !0, allowedInMath: !1 }, + handler: function (t, e) { + var r = e[0]; + return { type: 'accent', mode: t.parser.mode, label: t.funcName, isStretchy: !1, isShifty: !0, base: r }; + }, + htmlBuilder: Ie, + mathmlBuilder: Oe, + }), + _t({ + type: 'accentUnder', + names: ['\\underleftarrow', '\\underrightarrow', '\\underleftrightarrow', '\\undergroup', '\\underlinesegment', '\\utilde'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = e[0]; + return { type: 'accentUnder', mode: r.mode, label: a, base: n }; + }, + htmlBuilder: function (t, e) { + var r = oe(t.base, e), + a = Be(t, e), + n = '\\utilde' === t.label ? 0.12 : 0, + i = Dt.makeVList( + { + positionType: 'top', + positionData: r.height, + children: [ + { type: 'elem', elem: a, wrapperClasses: ['svg-align'] }, + { type: 'kern', size: n }, + { type: 'elem', elem: r }, + ], + }, + e + ); + return Dt.makeSpan(['mord', 'accentunder'], [i], e); + }, + mathmlBuilder: function (t, e) { + var r = Te(t.label), + a = new ue.MathNode('munder', [ve(t.base, e), r]); + return a.setAttribute('accentunder', 'true'), a; + }, + }); + var Ee = function (t) { + var e = new ue.MathNode('mpadded', t ? [t] : []); + return e.setAttribute('width', '+0.6em'), e.setAttribute('lspace', '0.3em'), e; + }; + _t({ + type: 'xArrow', + names: [ + '\\xleftarrow', + '\\xrightarrow', + '\\xLeftarrow', + '\\xRightarrow', + '\\xleftrightarrow', + '\\xLeftrightarrow', + '\\xhookleftarrow', + '\\xhookrightarrow', + '\\xmapsto', + '\\xrightharpoondown', + '\\xrightharpoonup', + '\\xleftharpoondown', + '\\xleftharpoonup', + '\\xrightleftharpoons', + '\\xleftrightharpoons', + '\\xlongequal', + '\\xtwoheadrightarrow', + '\\xtwoheadleftarrow', + '\\xtofrom', + '\\xrightleftarrows', + '\\xrightequilibrium', + '\\xleftequilibrium', + ], + props: { numArgs: 1, numOptionalArgs: 1 }, + handler: function (t, e, r) { + var a = t.parser, + n = t.funcName; + return { type: 'xArrow', mode: a.mode, label: n, body: e[0], below: r[0] }; + }, + htmlBuilder: function (t, e) { + var r, + a = e.style, + n = e.havingStyle(a.sup()), + i = Dt.wrapFragment(oe(t.body, n, e), e); + i.classes.push('x-arrow-pad'), + t.below && ((n = e.havingStyle(a.sub())), (r = Dt.wrapFragment(oe(t.below, n, e), e)).classes.push('x-arrow-pad')); + var o, + s = Be(t, e), + l = -e.fontMetrics().axisHeight + 0.5 * s.height, + h = -e.fontMetrics().axisHeight - 0.5 * s.height - 0.111; + if (((i.depth > 0.25 || '\\xleftequilibrium' === t.label) && (h -= i.depth), r)) { + var m = -e.fontMetrics().axisHeight + r.height + 0.5 * s.height + 0.111; + o = Dt.makeVList( + { + positionType: 'individualShift', + children: [ + { type: 'elem', elem: i, shift: h }, + { type: 'elem', elem: s, shift: l }, + { type: 'elem', elem: r, shift: m }, + ], + }, + e + ); + } else + o = Dt.makeVList( + { + positionType: 'individualShift', + children: [ + { type: 'elem', elem: i, shift: h }, + { type: 'elem', elem: s, shift: l }, + ], + }, + e + ); + return o.children[0].children[0].children[1].classes.push('svg-align'), Dt.makeSpan(['mrel', 'x-arrow'], [o], e); + }, + mathmlBuilder: function (t, e) { + var r, + a = Te(t.label); + if (t.body) { + var n = Ee(ve(t.body, e)); + if (t.below) { + var i = Ee(ve(t.below, e)); + r = new ue.MathNode('munderover', [a, i, n]); + } else r = new ue.MathNode('mover', [a, n]); + } else if (t.below) { + var o = Ee(ve(t.below, e)); + r = new ue.MathNode('munder', [a, o]); + } else (r = Ee()), (r = new ue.MathNode('mover', [a, r])); + return r; + }, + }), + _t({ + type: 'textord', + names: ['\\@char'], + props: { numArgs: 1, allowedInText: !0 }, + handler: function (t, e) { + for (var r = t.parser, a = Ce(e[0], 'ordgroup').body, n = '', i = 0; i < a.length; i++) { + n += Ce(a[i], 'textord').text; + } + var s = parseInt(n); + if (isNaN(s)) throw new o('\\@char has non-numeric argument ' + n); + return { type: 'textord', mode: r.mode, text: String.fromCharCode(s) }; + }, + }); + var Le = function (t, e) { + var r = ee(t.body, e.withColor(t.color), !1); + return Dt.makeFragment(r); + }, + Pe = function (t, e) { + var r = ge(t.body, e.withColor(t.color)), + a = new ue.MathNode('mstyle', r); + return a.setAttribute('mathcolor', t.color), a; + }; + _t({ + type: 'color', + names: ['\\textcolor'], + props: { numArgs: 2, allowedInText: !0, greediness: 3, argTypes: ['color', 'original'] }, + handler: function (t, e) { + var r = t.parser, + a = Ce(e[0], 'color-token').color, + n = e[1]; + return { type: 'color', mode: r.mode, color: a, body: $t(n) }; + }, + htmlBuilder: Le, + mathmlBuilder: Pe, + }), + _t({ + type: 'color', + names: ['\\color'], + props: { numArgs: 1, allowedInText: !0, greediness: 3, argTypes: ['color'] }, + handler: function (t, e) { + var r = t.parser, + a = t.breakOnTokenText, + n = Ce(e[0], 'color-token').color; + r.gullet.macros.set('\\current@color', n); + var i = r.parseExpression(!0, a); + return { type: 'color', mode: r.mode, color: n, body: i }; + }, + htmlBuilder: Le, + mathmlBuilder: Pe, + }), + _t({ + type: 'cr', + names: ['\\cr', '\\newline'], + props: { numArgs: 0, numOptionalArgs: 1, argTypes: ['size'], allowedInText: !0 }, + handler: function (t, e, r) { + var a = t.parser, + n = t.funcName, + i = r[0], + o = '\\cr' === n, + s = !1; + return ( + o || + (s = + !a.settings.displayMode || + !a.settings.useStrictBehavior('newLineInDisplayMode', 'In LaTeX, \\\\ or \\newline does nothing in display mode')), + { type: 'cr', mode: a.mode, newLine: s, newRow: o, size: i && Ce(i, 'size').value } + ); + }, + htmlBuilder: function (t, e) { + if (t.newRow) throw new o('\\cr valid only within a tabular/array environment'); + var r = Dt.makeSpan(['mspace'], [], e); + return t.newLine && (r.classes.push('newline'), t.size && (r.style.marginTop = Tt(t.size, e) + 'em')), r; + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mspace'); + return t.newLine && (r.setAttribute('linebreak', 'newline'), t.size && r.setAttribute('height', Tt(t.size, e) + 'em')), r; + }, + }); + var De = { + '\\global': '\\global', + '\\long': '\\\\globallong', + '\\\\globallong': '\\\\globallong', + '\\def': '\\gdef', + '\\gdef': '\\gdef', + '\\edef': '\\xdef', + '\\xdef': '\\xdef', + '\\let': '\\\\globallet', + '\\futurelet': '\\\\globalfuture', + }, + He = function (t) { + var e = t.text; + if (/^(?:[\\{}$&#^_]|EOF)$/.test(e)) throw new o('Expected a control sequence', t); + return e; + }, + Fe = function (t, e, r, a) { + var n = t.gullet.macros.get(r.text); + null == n && ((r.noexpand = !0), (n = { tokens: [r], numArgs: 0, unexpandable: !t.gullet.isExpandable(r.text) })), + t.gullet.macros.set(e, n, a); + }; + _t({ + type: 'internal', + names: ['\\global', '\\long', '\\\\globallong'], + props: { numArgs: 0, allowedInText: !0 }, + handler: function (t) { + var e = t.parser, + r = t.funcName; + e.consumeSpaces(); + var a = e.fetch(); + if (De[a.text]) return ('\\global' !== r && '\\\\globallong' !== r) || (a.text = De[a.text]), Ce(e.parseFunction(), 'internal'); + throw new o('Invalid token after macro prefix', a); + }, + }), + _t({ + type: 'internal', + names: ['\\def', '\\gdef', '\\edef', '\\xdef'], + props: { numArgs: 0, allowedInText: !0 }, + handler: function (t) { + var e = t.parser, + r = t.funcName, + a = e.gullet.consumeArgs(1)[0]; + if (1 !== a.length) throw new o("\\gdef's first argument must be a macro name"); + var n = a[0].text, + i = 0; + for (a = e.gullet.consumeArgs(1)[0]; 1 === a.length && '#' === a[0].text; ) { + if (1 !== (a = e.gullet.consumeArgs(1)[0]).length) throw new o('Invalid argument number length "' + a.length + '"'); + if (!/^[1-9]$/.test(a[0].text)) throw new o('Invalid argument number "' + a[0].text + '"'); + if ((i++, parseInt(a[0].text) !== i)) throw new o('Argument number "' + a[0].text + '" out of order'); + a = e.gullet.consumeArgs(1)[0]; + } + return ( + ('\\edef' !== r && '\\xdef' !== r) || (a = e.gullet.expandTokens(a)).reverse(), + e.gullet.macros.set(n, { tokens: a, numArgs: i }, r === De[r]), + { type: 'internal', mode: e.mode } + ); + }, + }), + _t({ + type: 'internal', + names: ['\\let', '\\\\globallet'], + props: { numArgs: 0, allowedInText: !0 }, + handler: function (t) { + var e = t.parser, + r = t.funcName, + a = He(e.gullet.popToken()); + e.gullet.consumeSpaces(); + var n = (function (t) { + var e = t.gullet.popToken(); + return '=' === e.text && ' ' === (e = t.gullet.popToken()).text && (e = t.gullet.popToken()), e; + })(e); + return Fe(e, a, n, '\\\\globallet' === r), { type: 'internal', mode: e.mode }; + }, + }), + _t({ + type: 'internal', + names: ['\\futurelet', '\\\\globalfuture'], + props: { numArgs: 0, allowedInText: !0 }, + handler: function (t) { + var e = t.parser, + r = t.funcName, + a = He(e.gullet.popToken()), + n = e.gullet.popToken(), + i = e.gullet.popToken(); + return Fe(e, a, i, '\\\\globalfuture' === r), e.gullet.pushToken(i), e.gullet.pushToken(n), { type: 'internal', mode: e.mode }; + }, + }); + var Ve = function (t, e, r) { + var a = G((j.math[t] && j.math[t].replace) || t, e, r); + if (!a) throw new Error('Unsupported symbol ' + t + ' and font size ' + e + '.'); + return a; + }, + Ue = function (t, e, r, a) { + var n = r.havingBaseStyle(e), + i = Dt.makeSpan(a.concat(n.sizingClasses(r)), [t], r), + o = n.sizeMultiplier / r.sizeMultiplier; + return (i.height *= o), (i.depth *= o), (i.maxFontSize = n.sizeMultiplier), i; + }, + Ge = function (t, e, r) { + var a = e.havingBaseStyle(r), + n = (1 - e.sizeMultiplier / a.sizeMultiplier) * e.fontMetrics().axisHeight; + t.classes.push('delimcenter'), (t.style.top = n + 'em'), (t.height -= n), (t.depth += n); + }, + Ye = function (t, e, r, a, n, i) { + var o = (function (t, e, r, a) { + return Dt.makeSymbol(t, 'Size' + e + '-Regular', r, a); + })(t, e, n, a), + s = Ue(Dt.makeSpan(['delimsizing', 'size' + e], [o], a), w.TEXT, a, i); + return r && Ge(s, a, w.TEXT), s; + }, + We = function (t, e, r) { + var a; + return ( + (a = 'Size1-Regular' === e ? 'delim-size1' : 'delim-size4'), + { type: 'elem', elem: Dt.makeSpan(['delimsizinginner', a], [Dt.makeSpan([], [Dt.makeSymbol(t, e, r)])]) } + ); + }, + Xe = { type: 'kern', size: -0.005 }, + _e = function (t, e, r, a, n, i) { + var o, s, l, h; + (o = l = h = t), (s = null); + var m = 'Size1-Regular'; + '\\uparrow' === t + ? (l = h = '\u23d0') + : '\\Uparrow' === t + ? (l = h = '\u2016') + : '\\downarrow' === t + ? (o = l = '\u23d0') + : '\\Downarrow' === t + ? (o = l = '\u2016') + : '\\updownarrow' === t + ? ((o = '\\uparrow'), (l = '\u23d0'), (h = '\\downarrow')) + : '\\Updownarrow' === t + ? ((o = '\\Uparrow'), (l = '\u2016'), (h = '\\Downarrow')) + : '[' === t || '\\lbrack' === t + ? ((o = '\u23a1'), (l = '\u23a2'), (h = '\u23a3'), (m = 'Size4-Regular')) + : ']' === t || '\\rbrack' === t + ? ((o = '\u23a4'), (l = '\u23a5'), (h = '\u23a6'), (m = 'Size4-Regular')) + : '\\lfloor' === t || '\u230a' === t + ? ((l = o = '\u23a2'), (h = '\u23a3'), (m = 'Size4-Regular')) + : '\\lceil' === t || '\u2308' === t + ? ((o = '\u23a1'), (l = h = '\u23a2'), (m = 'Size4-Regular')) + : '\\rfloor' === t || '\u230b' === t + ? ((l = o = '\u23a5'), (h = '\u23a6'), (m = 'Size4-Regular')) + : '\\rceil' === t || '\u2309' === t + ? ((o = '\u23a4'), (l = h = '\u23a5'), (m = 'Size4-Regular')) + : '(' === t || '\\lparen' === t + ? ((o = '\u239b'), (l = '\u239c'), (h = '\u239d'), (m = 'Size4-Regular')) + : ')' === t || '\\rparen' === t + ? ((o = '\u239e'), (l = '\u239f'), (h = '\u23a0'), (m = 'Size4-Regular')) + : '\\{' === t || '\\lbrace' === t + ? ((o = '\u23a7'), (s = '\u23a8'), (h = '\u23a9'), (l = '\u23aa'), (m = 'Size4-Regular')) + : '\\}' === t || '\\rbrace' === t + ? ((o = '\u23ab'), (s = '\u23ac'), (h = '\u23ad'), (l = '\u23aa'), (m = 'Size4-Regular')) + : '\\lgroup' === t || '\u27ee' === t + ? ((o = '\u23a7'), (h = '\u23a9'), (l = '\u23aa'), (m = 'Size4-Regular')) + : '\\rgroup' === t || '\u27ef' === t + ? ((o = '\u23ab'), (h = '\u23ad'), (l = '\u23aa'), (m = 'Size4-Regular')) + : '\\lmoustache' === t || '\u23b0' === t + ? ((o = '\u23a7'), (h = '\u23ad'), (l = '\u23aa'), (m = 'Size4-Regular')) + : ('\\rmoustache' !== t && '\u23b1' !== t) || ((o = '\u23ab'), (h = '\u23a9'), (l = '\u23aa'), (m = 'Size4-Regular')); + var c = Ve(o, m, n), + u = c.height + c.depth, + p = Ve(l, m, n), + d = p.height + p.depth, + f = Ve(h, m, n), + g = f.height + f.depth, + x = 0, + v = 1; + if (null !== s) { + var b = Ve(s, m, n); + (x = b.height + b.depth), (v = 2); + } + var y = u + g + x, + k = Math.max(0, Math.ceil((e - y) / (v * d))), + S = y + k * v * d, + M = a.fontMetrics().axisHeight; + r && (M *= a.sizeMultiplier); + var z = S / 2 - M, + A = 0.005 * (k + 1) - d, + T = []; + if ((T.push(We(h, m, n)), null === s)) for (var B = 0; B < k; B++) T.push(Xe), T.push(We(l, m, n)); + else { + for (var C = 0; C < k; C++) T.push(Xe), T.push(We(l, m, n)); + T.push({ type: 'kern', size: A }), T.push(We(l, m, n)), T.push(Xe), T.push(We(s, m, n)); + for (var q = 0; q < k; q++) T.push(Xe), T.push(We(l, m, n)); + } + if (('\u239c' !== l && '\u239f' !== l) || 0 !== k) T.push({ type: 'kern', size: A }), T.push(We(l, m, n)), T.push(Xe); + else { + var N = Dt.svgData.leftParenInner[2] / 2; + T.push({ type: 'kern', size: -N }); + var I = '\u239c' === l ? 'leftParenInner' : 'rightParenInner', + O = Dt.staticSvg(I, a); + T.push({ type: 'elem', elem: O }), T.push({ type: 'kern', size: -N }); + } + T.push(We(o, m, n)); + var R = a.havingBaseStyle(w.TEXT), + E = Dt.makeVList({ positionType: 'bottom', positionData: z, children: T }, R); + return Ue(Dt.makeSpan(['delimsizing', 'mult'], [E], R), w.TEXT, a, i); + }, + je = function (t, e, r, a, n) { + var i = (function (t, e, r) { + e *= 1e3; + var a = ''; + switch (t) { + case 'sqrtMain': + a = (function (t, e) { + return ( + 'M95,' + + (622 + t + e) + + '\nc-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,-10,-9.5,-14\nc0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54\nc44.2,-33.3,65.8,-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10\ns173,378,173,378c0.7,0,35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429\nc69,-144,104.5,-217.7,106.5,-221\nl' + + t / 2.075 + + ' -' + + t + + '\nc5.3,-9.3,12,-14,20,-14\nH400000v' + + (40 + t) + + 'H845.2724\ns-225.272,467,-225.272,467s-235,486,-235,486c-2.7,4.7,-9,7,-19,7\nc-6,0,-10,-1,-12,-3s-194,-422,-194,-422s-65,47,-65,47z\nM' + + (834 + t) + + ' ' + + e + + 'h400000v' + + (40 + t) + + 'h-400000z' + ); + })(e, 80); + break; + case 'sqrtSize1': + a = (function (t, e) { + return ( + 'M263,' + + (601 + t + e) + + 'c0.7,0,18,39.7,52,119\nc34,79.3,68.167,158.7,102.5,238c34.3,79.3,51.8,119.3,52.5,120\nc340,-704.7,510.7,-1060.3,512,-1067\nl' + + t / 2.084 + + ' -' + + t + + '\nc4.7,-7.3,11,-11,19,-11\nH40000v' + + (40 + t) + + 'H1012.3\ns-271.3,567,-271.3,567c-38.7,80.7,-84,175,-136,283c-52,108,-89.167,185.3,-111.5,232\nc-22.3,46.7,-33.8,70.3,-34.5,71c-4.7,4.7,-12.3,7,-23,7s-12,-1,-12,-1\ns-109,-253,-109,-253c-72.7,-168,-109.3,-252,-110,-252c-10.7,8,-22,16.7,-34,26\nc-22,17.3,-33.3,26,-34,26s-26,-26,-26,-26s76,-59,76,-59s76,-60,76,-60z\nM' + + (1001 + t) + + ' ' + + e + + 'h400000v' + + (40 + t) + + 'h-400000z' + ); + })(e, 80); + break; + case 'sqrtSize2': + a = (function (t, e) { + return ( + 'M983 ' + + (10 + t + e) + + '\nl' + + t / 3.13 + + ' -' + + t + + '\nc4,-6.7,10,-10,18,-10 H400000v' + + (40 + t) + + '\nH1013.1s-83.4,268,-264.1,840c-180.7,572,-277,876.3,-289,913c-4.7,4.7,-12.7,7,-24,7\ns-12,0,-12,0c-1.3,-3.3,-3.7,-11.7,-7,-25c-35.3,-125.3,-106.7,-373.3,-214,-744\nc-10,12,-21,25,-33,39s-32,39,-32,39c-6,-5.3,-15,-14,-27,-26s25,-30,25,-30\nc26.7,-32.7,52,-63,76,-91s52,-60,52,-60s208,722,208,722\nc56,-175.3,126.3,-397.3,211,-666c84.7,-268.7,153.8,-488.2,207.5,-658.5\nc53.7,-170.3,84.5,-266.8,92.5,-289.5z\nM' + + (1001 + t) + + ' ' + + e + + 'h400000v' + + (40 + t) + + 'h-400000z' + ); + })(e, 80); + break; + case 'sqrtSize3': + a = (function (t, e) { + return ( + 'M424,' + + (2398 + t + e) + + '\nc-1.3,-0.7,-38.5,-172,-111.5,-514c-73,-342,-109.8,-513.3,-110.5,-514\nc0,-2,-10.7,14.3,-32,49c-4.7,7.3,-9.8,15.7,-15.5,25c-5.7,9.3,-9.8,16,-12.5,20\ns-5,7,-5,7c-4,-3.3,-8.3,-7.7,-13,-13s-13,-13,-13,-13s76,-122,76,-122s77,-121,77,-121\ns209,968,209,968c0,-2,84.7,-361.7,254,-1079c169.3,-717.3,254.7,-1077.7,256,-1081\nl' + + t / 4.223 + + ' -' + + t + + 'c4,-6.7,10,-10,18,-10 H400000\nv' + + (40 + t) + + 'H1014.6\ns-87.3,378.7,-272.6,1166c-185.3,787.3,-279.3,1182.3,-282,1185\nc-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2z M' + + (1001 + t) + + ' ' + + e + + '\nh400000v' + + (40 + t) + + 'h-400000z' + ); + })(e, 80); + break; + case 'sqrtSize4': + a = (function (t, e) { + return ( + 'M473,' + + (2713 + t + e) + + '\nc339.3,-1799.3,509.3,-2700,510,-2702 l' + + t / 5.298 + + ' -' + + t + + '\nc3.3,-7.3,9.3,-11,18,-11 H400000v' + + (40 + t) + + 'H1017.7\ns-90.5,478,-276.2,1466c-185.7,988,-279.5,1483,-281.5,1485c-2,6,-10,9,-24,9\nc-8,0,-12,-0.7,-12,-2c0,-1.3,-5.3,-32,-16,-92c-50.7,-293.3,-119.7,-693.3,-207,-1200\nc0,-1.3,-5.3,8.7,-16,30c-10.7,21.3,-21.3,42.7,-32,64s-16,33,-16,33s-26,-26,-26,-26\ns76,-153,76,-153s77,-151,77,-151c0.7,0.7,35.7,202,105,604c67.3,400.7,102,602.7,104,\n606zM' + + (1001 + t) + + ' ' + + e + + 'h400000v' + + (40 + t) + + 'H1017.7z' + ); + })(e, 80); + break; + case 'sqrtTall': + a = (function (t, e, r) { + return ( + 'M702 ' + + (t + e) + + 'H400000' + + (40 + t) + + '\nH742v' + + (r - 54 - e - t) + + 'l-4 4-4 4c-.667.7 -2 1.5-4 2.5s-4.167 1.833-6.5 2.5-5.5 1-9.5 1\nh-12l-28-84c-16.667-52-96.667 -294.333-240-727l-212 -643 -85 170\nc-4-3.333-8.333-7.667-13 -13l-13-13l77-155 77-156c66 199.333 139 419.667\n219 661 l218 661zM702 ' + + e + + 'H400000v' + + (40 + t) + + 'H742z' + ); + })(e, 80, r); + } + return a; + })(t, a, r), + o = new P(t, i), + s = new L([o], { width: '400em', height: e + 'em', viewBox: '0 0 400000 ' + r, preserveAspectRatio: 'xMinYMin slice' }); + return Dt.makeSvgSpan(['hide-tail'], [s], n); + }, + $e = [ + '(', + '\\lparen', + ')', + '\\rparen', + '[', + '\\lbrack', + ']', + '\\rbrack', + '\\{', + '\\lbrace', + '\\}', + '\\rbrace', + '\\lfloor', + '\\rfloor', + '\u230a', + '\u230b', + '\\lceil', + '\\rceil', + '\u2308', + '\u2309', + '\\surd', + ], + Ze = [ + '\\uparrow', + '\\downarrow', + '\\updownarrow', + '\\Uparrow', + '\\Downarrow', + '\\Updownarrow', + '|', + '\\|', + '\\vert', + '\\Vert', + '\\lvert', + '\\rvert', + '\\lVert', + '\\rVert', + '\\lgroup', + '\\rgroup', + '\u27ee', + '\u27ef', + '\\lmoustache', + '\\rmoustache', + '\u23b0', + '\u23b1', + ], + Ke = ['<', '>', '\\langle', '\\rangle', '/', '\\backslash', '\\lt', '\\gt'], + Je = [0, 1.2, 1.8, 2.4, 3], + Qe = [ + { type: 'small', style: w.SCRIPTSCRIPT }, + { type: 'small', style: w.SCRIPT }, + { type: 'small', style: w.TEXT }, + { type: 'large', size: 1 }, + { type: 'large', size: 2 }, + { type: 'large', size: 3 }, + { type: 'large', size: 4 }, + ], + tr = [ + { type: 'small', style: w.SCRIPTSCRIPT }, + { type: 'small', style: w.SCRIPT }, + { type: 'small', style: w.TEXT }, + { type: 'stack' }, + ], + er = [ + { type: 'small', style: w.SCRIPTSCRIPT }, + { type: 'small', style: w.SCRIPT }, + { type: 'small', style: w.TEXT }, + { type: 'large', size: 1 }, + { type: 'large', size: 2 }, + { type: 'large', size: 3 }, + { type: 'large', size: 4 }, + { type: 'stack' }, + ], + rr = function (t) { + if ('small' === t.type) return 'Main-Regular'; + if ('large' === t.type) return 'Size' + t.size + '-Regular'; + if ('stack' === t.type) return 'Size4-Regular'; + throw new Error("Add support for delim type '" + t.type + "' here."); + }, + ar = function (t, e, r, a) { + for (var n = Math.min(2, 3 - a.style.size); n < r.length && 'stack' !== r[n].type; n++) { + var i = Ve(t, rr(r[n]), 'math'), + o = i.height + i.depth; + if (('small' === r[n].type && (o *= a.havingBaseStyle(r[n].style).sizeMultiplier), o > e)) return r[n]; + } + return r[r.length - 1]; + }, + nr = function (t, e, r, a, n, i) { + var o; + '<' === t || '\\lt' === t || '\u27e8' === t + ? (t = '\\langle') + : ('>' !== t && '\\gt' !== t && '\u27e9' !== t) || (t = '\\rangle'), + (o = c.contains(Ke, t) ? Qe : c.contains($e, t) ? er : tr); + var s = ar(t, e, o, a); + return 'small' === s.type + ? (function (t, e, r, a, n, i) { + var o = Dt.makeSymbol(t, 'Main-Regular', n, a), + s = Ue(o, e, a, i); + return r && Ge(s, a, e), s; + })(t, s.style, r, a, n, i) + : 'large' === s.type + ? Ye(t, s.size, r, a, n, i) + : _e(t, e, r, a, n, i); + }, + ir = function (t, e) { + var r, + a, + n = e.havingBaseSizing(), + i = ar('\\surd', t * n.sizeMultiplier, er, n), + o = n.sizeMultiplier, + s = Math.max(0, e.minRuleThickness - e.fontMetrics().sqrtRuleThickness), + l = 0, + h = 0, + m = 0; + return ( + 'small' === i.type + ? (t < 1 ? (o = 1) : t < 1.4 && (o = 0.7), + (h = (1 + s) / o), + ((r = je('sqrtMain', (l = (1 + s + 0.08) / o), (m = 1e3 + 1e3 * s + 80), s, e)).style.minWidth = '0.853em'), + (a = 0.833 / o)) + : 'large' === i.type + ? ((m = 1080 * Je[i.size]), + (h = (Je[i.size] + s) / o), + (l = (Je[i.size] + s + 0.08) / o), + ((r = je('sqrtSize' + i.size, l, m, s, e)).style.minWidth = '1.02em'), + (a = 1 / o)) + : ((l = t + s + 0.08), + (h = t + s), + (m = Math.floor(1e3 * t + s) + 80), + ((r = je('sqrtTall', l, m, s, e)).style.minWidth = '0.742em'), + (a = 1.056)), + (r.height = h), + (r.style.height = l + 'em'), + { span: r, advanceWidth: a, ruleWidth: (e.fontMetrics().sqrtRuleThickness + s) * o } + ); + }, + or = function (t, e, r, a, n) { + if ( + ('<' === t || '\\lt' === t || '\u27e8' === t + ? (t = '\\langle') + : ('>' !== t && '\\gt' !== t && '\u27e9' !== t) || (t = '\\rangle'), + c.contains($e, t) || c.contains(Ke, t)) + ) + return Ye(t, e, !1, r, a, n); + if (c.contains(Ze, t)) return _e(t, Je[e], !1, r, a, n); + throw new o("Illegal delimiter: '" + t + "'"); + }, + sr = nr, + lr = function (t, e, r, a, n, i) { + var o = a.fontMetrics().axisHeight * a.sizeMultiplier, + s = 5 / a.fontMetrics().ptPerEm, + l = Math.max(e - o, r + o), + h = Math.max((l / 500) * 901, 2 * l - s); + return nr(t, h, !0, a, n, i); + }, + hr = { + '\\bigl': { mclass: 'mopen', size: 1 }, + '\\Bigl': { mclass: 'mopen', size: 2 }, + '\\biggl': { mclass: 'mopen', size: 3 }, + '\\Biggl': { mclass: 'mopen', size: 4 }, + '\\bigr': { mclass: 'mclose', size: 1 }, + '\\Bigr': { mclass: 'mclose', size: 2 }, + '\\biggr': { mclass: 'mclose', size: 3 }, + '\\Biggr': { mclass: 'mclose', size: 4 }, + '\\bigm': { mclass: 'mrel', size: 1 }, + '\\Bigm': { mclass: 'mrel', size: 2 }, + '\\biggm': { mclass: 'mrel', size: 3 }, + '\\Biggm': { mclass: 'mrel', size: 4 }, + '\\big': { mclass: 'mord', size: 1 }, + '\\Big': { mclass: 'mord', size: 2 }, + '\\bigg': { mclass: 'mord', size: 3 }, + '\\Bigg': { mclass: 'mord', size: 4 }, + }, + mr = [ + '(', + '\\lparen', + ')', + '\\rparen', + '[', + '\\lbrack', + ']', + '\\rbrack', + '\\{', + '\\lbrace', + '\\}', + '\\rbrace', + '\\lfloor', + '\\rfloor', + '\u230a', + '\u230b', + '\\lceil', + '\\rceil', + '\u2308', + '\u2309', + '<', + '>', + '\\langle', + '\u27e8', + '\\rangle', + '\u27e9', + '\\lt', + '\\gt', + '\\lvert', + '\\rvert', + '\\lVert', + '\\rVert', + '\\lgroup', + '\\rgroup', + '\u27ee', + '\u27ef', + '\\lmoustache', + '\\rmoustache', + '\u23b0', + '\u23b1', + '/', + '\\backslash', + '|', + '\\vert', + '\\|', + '\\Vert', + '\\uparrow', + '\\Uparrow', + '\\downarrow', + '\\Downarrow', + '\\updownarrow', + '\\Updownarrow', + '.', + ]; + function cr(t, e) { + var r = Ne(t); + if (r && c.contains(mr, r.text)) return r; + throw new o(r ? "Invalid delimiter '" + r.text + "' after '" + e.funcName + "'" : "Invalid delimiter type '" + t.type + "'", t); + } + function ur(t) { + if (!t.body) throw new Error("Bug: The leftright ParseNode wasn't fully parsed."); + } + _t({ + type: 'delimsizing', + names: [ + '\\bigl', + '\\Bigl', + '\\biggl', + '\\Biggl', + '\\bigr', + '\\Bigr', + '\\biggr', + '\\Biggr', + '\\bigm', + '\\Bigm', + '\\biggm', + '\\Biggm', + '\\big', + '\\Big', + '\\bigg', + '\\Bigg', + ], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = cr(e[0], t); + return { type: 'delimsizing', mode: t.parser.mode, size: hr[t.funcName].size, mclass: hr[t.funcName].mclass, delim: r.text }; + }, + htmlBuilder: function (t, e) { + return '.' === t.delim ? Dt.makeSpan([t.mclass]) : or(t.delim, t.size, e, t.mode, [t.mclass]); + }, + mathmlBuilder: function (t) { + var e = []; + '.' !== t.delim && e.push(pe(t.delim, t.mode)); + var r = new ue.MathNode('mo', e); + return 'mopen' === t.mclass || 'mclose' === t.mclass ? r.setAttribute('fence', 'true') : r.setAttribute('fence', 'false'), r; + }, + }), + _t({ + type: 'leftright-right', + names: ['\\right'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = t.parser.gullet.macros.get('\\current@color'); + if (r && 'string' != typeof r) throw new o('\\current@color set to non-string in \\right'); + return { type: 'leftright-right', mode: t.parser.mode, delim: cr(e[0], t).text, color: r }; + }, + }), + _t({ + type: 'leftright', + names: ['\\left'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = cr(e[0], t), + a = t.parser; + ++a.leftrightDepth; + var n = a.parseExpression(!1); + --a.leftrightDepth, a.expect('\\right', !1); + var i = Ce(a.parseFunction(), 'leftright-right'); + return { type: 'leftright', mode: a.mode, body: n, left: r.text, right: i.delim, rightColor: i.color }; + }, + htmlBuilder: function (t, e) { + ur(t); + for (var r, a, n = ee(t.body, e, !0, ['mopen', 'mclose']), i = 0, o = 0, s = !1, l = 0; l < n.length; l++) + n[l].isMiddle ? (s = !0) : ((i = Math.max(n[l].height, i)), (o = Math.max(n[l].depth, o))); + if ( + ((i *= e.sizeMultiplier), + (o *= e.sizeMultiplier), + (r = '.' === t.left ? ie(e, ['mopen']) : lr(t.left, i, o, e, t.mode, ['mopen'])), + n.unshift(r), + s) + ) + for (var h = 1; h < n.length; h++) { + var m = n[h].isMiddle; + m && (n[h] = lr(m.delim, i, o, m.options, t.mode, [])); + } + if ('.' === t.right) a = ie(e, ['mclose']); + else { + var c = t.rightColor ? e.withColor(t.rightColor) : e; + a = lr(t.right, i, o, c, t.mode, ['mclose']); + } + return n.push(a), Dt.makeSpan(['minner'], n, e); + }, + mathmlBuilder: function (t, e) { + ur(t); + var r = ge(t.body, e); + if ('.' !== t.left) { + var a = new ue.MathNode('mo', [pe(t.left, t.mode)]); + a.setAttribute('fence', 'true'), r.unshift(a); + } + if ('.' !== t.right) { + var n = new ue.MathNode('mo', [pe(t.right, t.mode)]); + n.setAttribute('fence', 'true'), t.rightColor && n.setAttribute('mathcolor', t.rightColor), r.push(n); + } + return de(r); + }, + }), + _t({ + type: 'middle', + names: ['\\middle'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = cr(e[0], t); + if (!t.parser.leftrightDepth) throw new o('\\middle without preceding \\left', r); + return { type: 'middle', mode: t.parser.mode, delim: r.text }; + }, + htmlBuilder: function (t, e) { + var r; + if ('.' === t.delim) r = ie(e, []); + else { + r = or(t.delim, 1, e, t.mode, []); + var a = { delim: t.delim, options: e }; + r.isMiddle = a; + } + return r; + }, + mathmlBuilder: function (t, e) { + var r = '\\vert' === t.delim || '|' === t.delim ? pe('|', 'text') : pe(t.delim, t.mode), + a = new ue.MathNode('mo', [r]); + return a.setAttribute('fence', 'true'), a.setAttribute('lspace', '0.05em'), a.setAttribute('rspace', '0.05em'), a; + }, + }); + var pr = function (t, e) { + var r, + a, + n = Dt.wrapFragment(oe(t.body, e), e), + i = t.label.substr(1), + o = e.sizeMultiplier, + s = 0, + l = c.isCharacterBox(t.body); + if ('sout' === i) + ((r = Dt.makeSpan(['stretchy', 'sout'])).height = e.fontMetrics().defaultRuleThickness / o), + (s = -0.5 * e.fontMetrics().xHeight); + else { + /cancel/.test(i) ? l || n.classes.push('cancel-pad') : n.classes.push('boxpad'); + var h = 0, + m = 0; + /box/.test(i) + ? ((m = Math.max(e.fontMetrics().fboxrule, e.minRuleThickness)), (h = e.fontMetrics().fboxsep + ('colorbox' === i ? 0 : m))) + : (h = l ? 0.2 : 0), + (r = Ae(n, i, h, e)), + /fbox|boxed|fcolorbox/.test(i) && ((r.style.borderStyle = 'solid'), (r.style.borderWidth = m + 'em')), + (s = n.depth + h), + t.backgroundColor && ((r.style.backgroundColor = t.backgroundColor), t.borderColor && (r.style.borderColor = t.borderColor)); + } + return ( + (a = t.backgroundColor + ? Dt.makeVList( + { + positionType: 'individualShift', + children: [ + { type: 'elem', elem: r, shift: s }, + { type: 'elem', elem: n, shift: 0 }, + ], + }, + e + ) + : Dt.makeVList( + { + positionType: 'individualShift', + children: [ + { type: 'elem', elem: n, shift: 0 }, + { type: 'elem', elem: r, shift: s, wrapperClasses: /cancel/.test(i) ? ['svg-align'] : [] }, + ], + }, + e + )), + /cancel/.test(i) && ((a.height = n.height), (a.depth = n.depth)), + /cancel/.test(i) && !l ? Dt.makeSpan(['mord', 'cancel-lap'], [a], e) : Dt.makeSpan(['mord'], [a], e) + ); + }, + dr = function (t, e) { + var r = 0, + a = new ue.MathNode(t.label.indexOf('colorbox') > -1 ? 'mpadded' : 'menclose', [ve(t.body, e)]); + switch (t.label) { + case '\\cancel': + a.setAttribute('notation', 'updiagonalstrike'); + break; + case '\\bcancel': + a.setAttribute('notation', 'downdiagonalstrike'); + break; + case '\\sout': + a.setAttribute('notation', 'horizontalstrike'); + break; + case '\\fbox': + a.setAttribute('notation', 'box'); + break; + case '\\fcolorbox': + case '\\colorbox': + if ( + ((r = e.fontMetrics().fboxsep * e.fontMetrics().ptPerEm), + a.setAttribute('width', '+' + 2 * r + 'pt'), + a.setAttribute('height', '+' + 2 * r + 'pt'), + a.setAttribute('lspace', r + 'pt'), + a.setAttribute('voffset', r + 'pt'), + '\\fcolorbox' === t.label) + ) { + var n = Math.max(e.fontMetrics().fboxrule, e.minRuleThickness); + a.setAttribute('style', 'border: ' + n + 'em solid ' + String(t.borderColor)); + } + break; + case '\\xcancel': + a.setAttribute('notation', 'updiagonalstrike downdiagonalstrike'); + } + return t.backgroundColor && a.setAttribute('mathbackground', t.backgroundColor), a; + }; + _t({ + type: 'enclose', + names: ['\\colorbox'], + props: { numArgs: 2, allowedInText: !0, greediness: 3, argTypes: ['color', 'text'] }, + handler: function (t, e, r) { + var a = t.parser, + n = t.funcName, + i = Ce(e[0], 'color-token').color, + o = e[1]; + return { type: 'enclose', mode: a.mode, label: n, backgroundColor: i, body: o }; + }, + htmlBuilder: pr, + mathmlBuilder: dr, + }), + _t({ + type: 'enclose', + names: ['\\fcolorbox'], + props: { numArgs: 3, allowedInText: !0, greediness: 3, argTypes: ['color', 'color', 'text'] }, + handler: function (t, e, r) { + var a = t.parser, + n = t.funcName, + i = Ce(e[0], 'color-token').color, + o = Ce(e[1], 'color-token').color, + s = e[2]; + return { type: 'enclose', mode: a.mode, label: n, backgroundColor: o, borderColor: i, body: s }; + }, + htmlBuilder: pr, + mathmlBuilder: dr, + }), + _t({ + type: 'enclose', + names: ['\\fbox'], + props: { numArgs: 1, argTypes: ['hbox'], allowedInText: !0 }, + handler: function (t, e) { + return { type: 'enclose', mode: t.parser.mode, label: '\\fbox', body: e[0] }; + }, + }), + _t({ + type: 'enclose', + names: ['\\cancel', '\\bcancel', '\\xcancel', '\\sout'], + props: { numArgs: 1 }, + handler: function (t, e, r) { + var a = t.parser, + n = t.funcName, + i = e[0]; + return { type: 'enclose', mode: a.mode, label: n, body: i }; + }, + htmlBuilder: pr, + mathmlBuilder: dr, + }); + var fr = {}; + function gr(t) { + for ( + var e = t.type, + r = t.names, + a = t.props, + n = t.handler, + i = t.htmlBuilder, + o = t.mathmlBuilder, + s = { type: e, numArgs: a.numArgs || 0, greediness: 1, allowedInText: !1, numOptionalArgs: 0, handler: n }, + l = 0; + l < r.length; + ++l + ) + fr[r[l]] = s; + i && (Wt[e] = i), o && (Xt[e] = o); + } + function xr(t) { + var e = []; + t.consumeSpaces(); + for (var r = t.fetch().text; '\\hline' === r || '\\hdashline' === r; ) + t.consume(), e.push('\\hdashline' === r), t.consumeSpaces(), (r = t.fetch().text); + return e; + } + function vr(t, e, r) { + var a = e.hskipBeforeAndAfter, + n = e.addJot, + i = e.cols, + s = e.arraystretch, + l = e.colSeparationType; + if ((t.gullet.beginGroup(), t.gullet.macros.set('\\\\', '\\cr'), !s)) { + var h = t.gullet.expandMacroAsText('\\arraystretch'); + if (null == h) s = 1; + else if (!(s = parseFloat(h)) || s < 0) throw new o('Invalid \\arraystretch: ' + h); + } + t.gullet.beginGroup(); + var m = [], + c = [m], + u = [], + p = []; + for (p.push(xr(t)); ; ) { + var d = t.parseExpression(!1, '\\cr'); + t.gullet.endGroup(), + t.gullet.beginGroup(), + (d = { type: 'ordgroup', mode: t.mode, body: d }), + r && (d = { type: 'styling', mode: t.mode, style: r, body: [d] }), + m.push(d); + var f = t.fetch().text; + if ('&' === f) t.consume(); + else { + if ('\\end' === f) { + 1 === m.length && 'styling' === d.type && 0 === d.body[0].body.length && c.pop(), p.length < c.length + 1 && p.push([]); + break; + } + if ('\\cr' !== f) throw new o('Expected & or \\\\ or \\cr or \\end', t.nextToken); + var g = Ce(t.parseFunction(), 'cr'); + u.push(g.size), p.push(xr(t)), (m = []), c.push(m); + } + } + return ( + t.gullet.endGroup(), + t.gullet.endGroup(), + { + type: 'array', + mode: t.mode, + addJot: n, + arraystretch: s, + body: c, + cols: i, + rowGaps: u, + hskipBeforeAndAfter: a, + hLinesBeforeRow: p, + colSeparationType: l, + } + ); + } + function br(t) { + return 'd' === t.substr(0, 1) ? 'display' : 'text'; + } + var yr = function (t, e) { + var r, + a, + n = t.body.length, + i = t.hLinesBeforeRow, + s = 0, + l = new Array(n), + h = [], + m = Math.max(e.fontMetrics().arrayRuleWidth, e.minRuleThickness), + u = 1 / e.fontMetrics().ptPerEm, + p = 5 * u; + t.colSeparationType && + 'small' === t.colSeparationType && + (p = (e.havingStyle(w.SCRIPT).sizeMultiplier / e.sizeMultiplier) * 0.2778); + var d = 12 * u, + f = 3 * u, + g = t.arraystretch * d, + x = 0.7 * g, + v = 0.3 * g, + b = 0; + function y(t) { + for (var e = 0; e < t.length; ++e) e > 0 && (b += 0.25), h.push({ pos: b, isDashed: t[e] }); + } + for (y(i[0]), r = 0; r < t.body.length; ++r) { + var k = t.body[r], + S = x, + M = v; + s < k.length && (s = k.length); + var z = new Array(k.length); + for (a = 0; a < k.length; ++a) { + var A = oe(k[a], e); + M < A.depth && (M = A.depth), S < A.height && (S = A.height), (z[a] = A); + } + var T = t.rowGaps[r], + B = 0; + T && (B = Tt(T, e)) > 0 && (M < (B += v) && (M = B), (B = 0)), + t.addJot && (M += f), + (z.height = S), + (z.depth = M), + (b += S), + (z.pos = b), + (b += M + B), + (l[r] = z), + y(i[r + 1]); + } + var C, + q, + N = b / 2 + e.fontMetrics().axisHeight, + I = t.cols || [], + O = []; + for (a = 0, q = 0; a < s || q < I.length; ++a, ++q) { + for (var R = I[q] || {}, E = !0; 'separator' === R.type; ) { + if ( + (E || (((C = Dt.makeSpan(['arraycolsep'], [])).style.width = e.fontMetrics().doubleRuleSep + 'em'), O.push(C)), + '|' !== R.separator && ':' !== R.separator) + ) + throw new o('Invalid separator type: ' + R.separator); + var L = '|' === R.separator ? 'solid' : 'dashed', + P = Dt.makeSpan(['vertical-separator'], [], e); + (P.style.height = b + 'em'), + (P.style.borderRightWidth = m + 'em'), + (P.style.borderRightStyle = L), + (P.style.margin = '0 -' + m / 2 + 'em'), + (P.style.verticalAlign = -(b - N) + 'em'), + O.push(P), + (R = I[++q] || {}), + (E = !1); + } + if (!(a >= s)) { + var D = void 0; + (a > 0 || t.hskipBeforeAndAfter) && + 0 !== (D = c.deflt(R.pregap, p)) && + (((C = Dt.makeSpan(['arraycolsep'], [])).style.width = D + 'em'), O.push(C)); + var H = []; + for (r = 0; r < n; ++r) { + var F = l[r], + V = F[a]; + if (V) { + var U = F.pos - N; + (V.depth = F.depth), (V.height = F.height), H.push({ type: 'elem', elem: V, shift: U }); + } + } + (H = Dt.makeVList({ positionType: 'individualShift', children: H }, e)), + (H = Dt.makeSpan(['col-align-' + (R.align || 'c')], [H])), + O.push(H), + (a < s - 1 || t.hskipBeforeAndAfter) && + 0 !== (D = c.deflt(R.postgap, p)) && + (((C = Dt.makeSpan(['arraycolsep'], [])).style.width = D + 'em'), O.push(C)); + } + } + if (((l = Dt.makeSpan(['mtable'], O)), h.length > 0)) { + for ( + var G = Dt.makeLineSpan('hline', e, m), Y = Dt.makeLineSpan('hdashline', e, m), W = [{ type: 'elem', elem: l, shift: 0 }]; + h.length > 0; + + ) { + var X = h.pop(), + _ = X.pos - N; + X.isDashed ? W.push({ type: 'elem', elem: Y, shift: _ }) : W.push({ type: 'elem', elem: G, shift: _ }); + } + l = Dt.makeVList({ positionType: 'individualShift', children: W }, e); + } + return Dt.makeSpan(['mord'], [l], e); + }, + wr = { c: 'center ', l: 'left ', r: 'right ' }, + kr = function (t, e) { + var r = new ue.MathNode( + 'mtable', + t.body.map(function (t) { + return new ue.MathNode( + 'mtr', + t.map(function (t) { + return new ue.MathNode('mtd', [ve(t, e)]); + }) + ); + }) + ), + a = 0.5 === t.arraystretch ? 0.1 : 0.16 + t.arraystretch - 1 + (t.addJot ? 0.09 : 0); + r.setAttribute('rowspacing', a + 'em'); + var n = '', + i = ''; + if (t.cols && t.cols.length > 0) { + var o = t.cols, + s = '', + l = !1, + h = 0, + m = o.length; + 'separator' === o[0].type && ((n += 'top '), (h = 1)), 'separator' === o[o.length - 1].type && ((n += 'bottom '), (m -= 1)); + for (var c = h; c < m; c++) + 'align' === o[c].type + ? ((i += wr[o[c].align]), l && (s += 'none '), (l = !0)) + : 'separator' === o[c].type && l && ((s += '|' === o[c].separator ? 'solid ' : 'dashed '), (l = !1)); + r.setAttribute('columnalign', i.trim()), /[sd]/.test(s) && r.setAttribute('columnlines', s.trim()); + } + if ('align' === t.colSeparationType) { + for (var u = t.cols || [], p = '', d = 1; d < u.length; d++) p += d % 2 ? '0em ' : '1em '; + r.setAttribute('columnspacing', p.trim()); + } else + 'alignat' === t.colSeparationType + ? r.setAttribute('columnspacing', '0em') + : 'small' === t.colSeparationType + ? r.setAttribute('columnspacing', '0.2778em') + : r.setAttribute('columnspacing', '1em'); + var f = '', + g = t.hLinesBeforeRow; + (n += g[0].length > 0 ? 'left ' : ''), (n += g[g.length - 1].length > 0 ? 'right ' : ''); + for (var x = 1; x < g.length - 1; x++) f += 0 === g[x].length ? 'none ' : g[x][0] ? 'dashed ' : 'solid '; + return ( + /[sd]/.test(f) && r.setAttribute('rowlines', f.trim()), + '' !== n && (r = new ue.MathNode('menclose', [r])).setAttribute('notation', n.trim()), + t.arraystretch && t.arraystretch < 1 && (r = new ue.MathNode('mstyle', [r])).setAttribute('scriptlevel', '1'), + r + ); + }, + Sr = function (t, e) { + var r, + a = [], + n = vr(t.parser, { cols: a, addJot: !0 }, 'display'), + i = 0, + s = { type: 'ordgroup', mode: t.mode, body: [] }; + if (e[0] && 'ordgroup' === e[0].type) { + for (var l = '', h = 0; h < e[0].body.length; h++) { + l += Ce(e[0].body[h], 'textord').text; + } + (r = Number(l)), (i = 2 * r); + } + var m = !i; + n.body.forEach(function (t) { + for (var e = 1; e < t.length; e += 2) { + var a = Ce(t[e], 'styling'); + Ce(a.body[0], 'ordgroup').body.unshift(s); + } + if (m) i < t.length && (i = t.length); + else { + var n = t.length / 2; + if (r < n) throw new o('Too many math in a row: expected ' + r + ', but got ' + n, t[0]); + } + }); + for (var c = 0; c < i; ++c) { + var u = 'r', + p = 0; + c % 2 == 1 ? (u = 'l') : c > 0 && m && (p = 1), (a[c] = { type: 'align', align: u, pregap: p, postgap: 0 }); + } + return (n.colSeparationType = m ? 'align' : 'alignat'), n; + }; + gr({ + type: 'array', + names: ['array', 'darray'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = { + cols: (Ne(e[0]) ? [e[0]] : Ce(e[0], 'ordgroup').body).map(function (t) { + var e = qe(t).text; + if (-1 !== 'lcr'.indexOf(e)) return { type: 'align', align: e }; + if ('|' === e) return { type: 'separator', separator: '|' }; + if (':' === e) return { type: 'separator', separator: ':' }; + throw new o('Unknown column alignment: ' + e, t); + }), + hskipBeforeAndAfter: !0, + }; + return vr(t.parser, r, br(t.envName)); + }, + htmlBuilder: yr, + mathmlBuilder: kr, + }), + gr({ + type: 'array', + names: ['matrix', 'pmatrix', 'bmatrix', 'Bmatrix', 'vmatrix', 'Vmatrix'], + props: { numArgs: 0 }, + handler: function (t) { + var e = { + matrix: null, + pmatrix: ['(', ')'], + bmatrix: ['[', ']'], + Bmatrix: ['\\{', '\\}'], + vmatrix: ['|', '|'], + Vmatrix: ['\\Vert', '\\Vert'], + }[t.envName], + r = vr(t.parser, { hskipBeforeAndAfter: !1 }, br(t.envName)); + return e ? { type: 'leftright', mode: t.mode, body: [r], left: e[0], right: e[1], rightColor: void 0 } : r; + }, + htmlBuilder: yr, + mathmlBuilder: kr, + }), + gr({ + type: 'array', + names: ['smallmatrix'], + props: { numArgs: 0 }, + handler: function (t) { + var e = vr(t.parser, { arraystretch: 0.5 }, 'script'); + return (e.colSeparationType = 'small'), e; + }, + htmlBuilder: yr, + mathmlBuilder: kr, + }), + gr({ + type: 'array', + names: ['subarray'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = (Ne(e[0]) ? [e[0]] : Ce(e[0], 'ordgroup').body).map(function (t) { + var e = qe(t).text; + if (-1 !== 'lc'.indexOf(e)) return { type: 'align', align: e }; + throw new o('Unknown column alignment: ' + e, t); + }); + if (r.length > 1) throw new o('{subarray} can contain only one column'); + var a = { cols: r, hskipBeforeAndAfter: !1, arraystretch: 0.5 }; + if ((a = vr(t.parser, a, 'script')).body.length > 0 && a.body[0].length > 1) + throw new o('{subarray} can contain only one column'); + return a; + }, + htmlBuilder: yr, + mathmlBuilder: kr, + }), + gr({ + type: 'array', + names: ['cases', 'dcases', 'rcases', 'drcases'], + props: { numArgs: 0 }, + handler: function (t) { + var e = vr( + t.parser, + { + arraystretch: 1.2, + cols: [ + { type: 'align', align: 'l', pregap: 0, postgap: 1 }, + { type: 'align', align: 'l', pregap: 0, postgap: 0 }, + ], + }, + br(t.envName) + ); + return { + type: 'leftright', + mode: t.mode, + body: [e], + left: t.envName.indexOf('r') > -1 ? '.' : '\\{', + right: t.envName.indexOf('r') > -1 ? '\\}' : '.', + rightColor: void 0, + }; + }, + htmlBuilder: yr, + mathmlBuilder: kr, + }), + gr({ type: 'array', names: ['aligned'], props: { numArgs: 0 }, handler: Sr, htmlBuilder: yr, mathmlBuilder: kr }), + gr({ + type: 'array', + names: ['gathered'], + props: { numArgs: 0 }, + handler: function (t) { + return vr(t.parser, { cols: [{ type: 'align', align: 'c' }], addJot: !0 }, 'display'); + }, + htmlBuilder: yr, + mathmlBuilder: kr, + }), + gr({ type: 'array', names: ['alignedat'], props: { numArgs: 1 }, handler: Sr, htmlBuilder: yr, mathmlBuilder: kr }), + _t({ + type: 'text', + names: ['\\hline', '\\hdashline'], + props: { numArgs: 0, allowedInText: !0, allowedInMath: !0 }, + handler: function (t, e) { + throw new o(t.funcName + ' valid only within array environment'); + }, + }); + var Mr = fr; + _t({ + type: 'environment', + names: ['\\begin', '\\end'], + props: { numArgs: 1, argTypes: ['text'] }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = e[0]; + if ('ordgroup' !== n.type) throw new o('Invalid environment name', n); + for (var i = '', s = 0; s < n.body.length; ++s) i += Ce(n.body[s], 'textord').text; + if ('\\begin' === a) { + if (!Mr.hasOwnProperty(i)) throw new o('No such environment: ' + i, n); + var l = Mr[i], + h = r.parseArguments('\\begin{' + i + '}', l), + m = h.args, + c = h.optArgs, + u = { mode: r.mode, envName: i, parser: r }, + p = l.handler(u, m, c); + r.expect('\\end', !1); + var d = r.nextToken, + f = Ce(r.parseFunction(), 'environment'); + if (f.name !== i) throw new o('Mismatch: \\begin{' + i + '} matched by \\end{' + f.name + '}', d); + return p; + } + return { type: 'environment', mode: r.mode, name: i, nameGroup: n }; + }, + }); + var zr = Dt.makeSpan; + function Ar(t, e) { + var r = ee(t.body, e, !0); + return zr([t.mclass], r, e); + } + function Tr(t, e) { + var r, + a = ge(t.body, e); + return 'minner' === t.mclass + ? ue.newDocumentFragment(a) + : ('mord' === t.mclass + ? t.isCharacterBox + ? ((r = a[0]).type = 'mi') + : (r = new ue.MathNode('mi', a)) + : (t.isCharacterBox ? ((r = a[0]).type = 'mo') : (r = new ue.MathNode('mo', a)), + 'mbin' === t.mclass + ? ((r.attributes.lspace = '0.22em'), (r.attributes.rspace = '0.22em')) + : 'mpunct' === t.mclass + ? ((r.attributes.lspace = '0em'), (r.attributes.rspace = '0.17em')) + : ('mopen' !== t.mclass && 'mclose' !== t.mclass) || ((r.attributes.lspace = '0em'), (r.attributes.rspace = '0em'))), + r); + } + _t({ + type: 'mclass', + names: ['\\mathord', '\\mathbin', '\\mathrel', '\\mathopen', '\\mathclose', '\\mathpunct', '\\mathinner'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = e[0]; + return { type: 'mclass', mode: r.mode, mclass: 'm' + a.substr(5), body: $t(n), isCharacterBox: c.isCharacterBox(n) }; + }, + htmlBuilder: Ar, + mathmlBuilder: Tr, + }); + var Br = function (t) { + var e = 'ordgroup' === t.type && t.body.length ? t.body[0] : t; + return 'atom' !== e.type || ('bin' !== e.family && 'rel' !== e.family) ? 'mord' : 'm' + e.family; + }; + _t({ + type: 'mclass', + names: ['\\@binrel'], + props: { numArgs: 2 }, + handler: function (t, e) { + return { type: 'mclass', mode: t.parser.mode, mclass: Br(e[0]), body: [e[1]], isCharacterBox: c.isCharacterBox(e[1]) }; + }, + }), + _t({ + type: 'mclass', + names: ['\\stackrel', '\\overset', '\\underset'], + props: { numArgs: 2 }, + handler: function (t, e) { + var r, + a = t.parser, + n = t.funcName, + i = e[1], + o = e[0]; + r = '\\stackrel' !== n ? Br(i) : 'mrel'; + var s = { + type: 'op', + mode: i.mode, + limits: !0, + alwaysHandleSupSub: !0, + parentIsSupSub: !1, + symbol: !1, + suppressBaseShift: '\\stackrel' !== n, + body: $t(i), + }, + l = { type: 'supsub', mode: o.mode, base: s, sup: '\\underset' === n ? null : o, sub: '\\underset' === n ? o : null }; + return { type: 'mclass', mode: a.mode, mclass: r, body: [l], isCharacterBox: c.isCharacterBox(l) }; + }, + htmlBuilder: Ar, + mathmlBuilder: Tr, + }); + var Cr = function (t, e) { + var r = t.font, + a = e.withFont(r); + return oe(t.body, a); + }, + qr = function (t, e) { + var r = t.font, + a = e.withFont(r); + return ve(t.body, a); + }, + Nr = { '\\Bbb': '\\mathbb', '\\bold': '\\mathbf', '\\frak': '\\mathfrak', '\\bm': '\\boldsymbol' }; + _t({ + type: 'font', + names: [ + '\\mathrm', + '\\mathit', + '\\mathbf', + '\\mathnormal', + '\\mathbb', + '\\mathcal', + '\\mathfrak', + '\\mathscr', + '\\mathsf', + '\\mathtt', + '\\Bbb', + '\\bold', + '\\frak', + ], + props: { numArgs: 1, greediness: 2 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = e[0], + i = a; + return i in Nr && (i = Nr[i]), { type: 'font', mode: r.mode, font: i.slice(1), body: n }; + }, + htmlBuilder: Cr, + mathmlBuilder: qr, + }), + _t({ + type: 'mclass', + names: ['\\boldsymbol', '\\bm'], + props: { numArgs: 1, greediness: 2 }, + handler: function (t, e) { + var r = t.parser, + a = e[0], + n = c.isCharacterBox(a); + return { + type: 'mclass', + mode: r.mode, + mclass: Br(a), + body: [{ type: 'font', mode: r.mode, font: 'boldsymbol', body: a }], + isCharacterBox: n, + }; + }, + }), + _t({ + type: 'font', + names: ['\\rm', '\\sf', '\\tt', '\\bf', '\\it', '\\cal'], + props: { numArgs: 0, allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = t.breakOnTokenText, + i = r.mode, + o = r.parseExpression(!0, n); + return { type: 'font', mode: i, font: 'math' + a.slice(1), body: { type: 'ordgroup', mode: r.mode, body: o } }; + }, + htmlBuilder: Cr, + mathmlBuilder: qr, + }); + var Ir = function (t, e) { + var r = e; + return ( + 'display' === t + ? (r = r.id >= w.SCRIPT.id ? r.text() : w.DISPLAY) + : 'text' === t && r.size === w.DISPLAY.size + ? (r = w.TEXT) + : 'script' === t + ? (r = w.SCRIPT) + : 'scriptscript' === t && (r = w.SCRIPTSCRIPT), + r + ); + }, + Or = function (t, e) { + var r, + a = Ir(t.size, e.style), + n = a.fracNum(), + i = a.fracDen(); + r = e.havingStyle(n); + var o = oe(t.numer, r, e); + if (t.continued) { + var s = 8.5 / e.fontMetrics().ptPerEm, + l = 3.5 / e.fontMetrics().ptPerEm; + (o.height = o.height < s ? s : o.height), (o.depth = o.depth < l ? l : o.depth); + } + r = e.havingStyle(i); + var h, + m, + c, + u, + p, + d, + f, + g, + x, + v, + b = oe(t.denom, r, e); + if ( + (t.hasBarLine + ? (t.barSize ? ((m = Tt(t.barSize, e)), (h = Dt.makeLineSpan('frac-line', e, m))) : (h = Dt.makeLineSpan('frac-line', e)), + (m = h.height), + (c = h.height)) + : ((h = null), (m = 0), (c = e.fontMetrics().defaultRuleThickness)), + a.size === w.DISPLAY.size || 'display' === t.size + ? ((u = e.fontMetrics().num1), (p = m > 0 ? 3 * c : 7 * c), (d = e.fontMetrics().denom1)) + : (m > 0 ? ((u = e.fontMetrics().num2), (p = c)) : ((u = e.fontMetrics().num3), (p = 3 * c)), (d = e.fontMetrics().denom2)), + h) + ) { + var y = e.fontMetrics().axisHeight; + u - o.depth - (y + 0.5 * m) < p && (u += p - (u - o.depth - (y + 0.5 * m))), + y - 0.5 * m - (b.height - d) < p && (d += p - (y - 0.5 * m - (b.height - d))); + var k = -(y - 0.5 * m); + f = Dt.makeVList( + { + positionType: 'individualShift', + children: [ + { type: 'elem', elem: b, shift: d }, + { type: 'elem', elem: h, shift: k }, + { type: 'elem', elem: o, shift: -u }, + ], + }, + e + ); + } else { + var S = u - o.depth - (b.height - d); + S < p && ((u += 0.5 * (p - S)), (d += 0.5 * (p - S))), + (f = Dt.makeVList( + { + positionType: 'individualShift', + children: [ + { type: 'elem', elem: b, shift: d }, + { type: 'elem', elem: o, shift: -u }, + ], + }, + e + )); + } + return ( + (r = e.havingStyle(a)), + (f.height *= r.sizeMultiplier / e.sizeMultiplier), + (f.depth *= r.sizeMultiplier / e.sizeMultiplier), + (g = a.size === w.DISPLAY.size ? e.fontMetrics().delim1 : e.fontMetrics().delim2), + (x = null == t.leftDelim ? ie(e, ['mopen']) : sr(t.leftDelim, g, !0, e.havingStyle(a), t.mode, ['mopen'])), + (v = t.continued + ? Dt.makeSpan([]) + : null == t.rightDelim + ? ie(e, ['mclose']) + : sr(t.rightDelim, g, !0, e.havingStyle(a), t.mode, ['mclose'])), + Dt.makeSpan(['mord'].concat(r.sizingClasses(e)), [x, Dt.makeSpan(['mfrac'], [f]), v], e) + ); + }, + Rr = function (t, e) { + var r = new ue.MathNode('mfrac', [ve(t.numer, e), ve(t.denom, e)]); + if (t.hasBarLine) { + if (t.barSize) { + var a = Tt(t.barSize, e); + r.setAttribute('linethickness', a + 'em'); + } + } else r.setAttribute('linethickness', '0px'); + var n = Ir(t.size, e.style); + if (n.size !== e.style.size) { + r = new ue.MathNode('mstyle', [r]); + var i = n.size === w.DISPLAY.size ? 'true' : 'false'; + r.setAttribute('displaystyle', i), r.setAttribute('scriptlevel', '0'); + } + if (null != t.leftDelim || null != t.rightDelim) { + var o = []; + if (null != t.leftDelim) { + var s = new ue.MathNode('mo', [new ue.TextNode(t.leftDelim.replace('\\', ''))]); + s.setAttribute('fence', 'true'), o.push(s); + } + if ((o.push(r), null != t.rightDelim)) { + var l = new ue.MathNode('mo', [new ue.TextNode(t.rightDelim.replace('\\', ''))]); + l.setAttribute('fence', 'true'), o.push(l); + } + return de(o); + } + return r; + }; + _t({ + type: 'genfrac', + names: [ + '\\cfrac', + '\\dfrac', + '\\frac', + '\\tfrac', + '\\dbinom', + '\\binom', + '\\tbinom', + '\\\\atopfrac', + '\\\\bracefrac', + '\\\\brackfrac', + ], + props: { numArgs: 2, greediness: 2 }, + handler: function (t, e) { + var r, + a = t.parser, + n = t.funcName, + i = e[0], + o = e[1], + s = null, + l = null, + h = 'auto'; + switch (n) { + case '\\cfrac': + case '\\dfrac': + case '\\frac': + case '\\tfrac': + r = !0; + break; + case '\\\\atopfrac': + r = !1; + break; + case '\\dbinom': + case '\\binom': + case '\\tbinom': + (r = !1), (s = '('), (l = ')'); + break; + case '\\\\bracefrac': + (r = !1), (s = '\\{'), (l = '\\}'); + break; + case '\\\\brackfrac': + (r = !1), (s = '['), (l = ']'); + break; + default: + throw new Error('Unrecognized genfrac command'); + } + switch (n) { + case '\\cfrac': + case '\\dfrac': + case '\\dbinom': + h = 'display'; + break; + case '\\tfrac': + case '\\tbinom': + h = 'text'; + } + return { + type: 'genfrac', + mode: a.mode, + continued: '\\cfrac' === n, + numer: i, + denom: o, + hasBarLine: r, + leftDelim: s, + rightDelim: l, + size: h, + barSize: null, + }; + }, + htmlBuilder: Or, + mathmlBuilder: Rr, + }), + _t({ + type: 'infix', + names: ['\\over', '\\choose', '\\atop', '\\brace', '\\brack'], + props: { numArgs: 0, infix: !0 }, + handler: function (t) { + var e, + r = t.parser, + a = t.funcName, + n = t.token; + switch (a) { + case '\\over': + e = '\\frac'; + break; + case '\\choose': + e = '\\binom'; + break; + case '\\atop': + e = '\\\\atopfrac'; + break; + case '\\brace': + e = '\\\\bracefrac'; + break; + case '\\brack': + e = '\\\\brackfrac'; + break; + default: + throw new Error('Unrecognized infix genfrac command'); + } + return { type: 'infix', mode: r.mode, replaceWith: e, token: n }; + }, + }); + var Er = ['display', 'text', 'script', 'scriptscript'], + Lr = function (t) { + var e = null; + return t.length > 0 && (e = '.' === (e = t) ? null : e), e; + }; + _t({ + type: 'genfrac', + names: ['\\genfrac'], + props: { numArgs: 6, greediness: 6, argTypes: ['math', 'math', 'size', 'text', 'math', 'math'] }, + handler: function (t, e) { + var r, + a = t.parser, + n = e[4], + i = e[5], + o = 'atom' === e[0].type && 'open' === e[0].family ? Lr(e[0].text) : null, + s = 'atom' === e[1].type && 'close' === e[1].family ? Lr(e[1].text) : null, + l = Ce(e[2], 'size'), + h = null; + r = !!l.isBlank || (h = l.value).number > 0; + var m = 'auto', + c = e[3]; + if ('ordgroup' === c.type) { + if (c.body.length > 0) { + var u = Ce(c.body[0], 'textord'); + m = Er[Number(u.text)]; + } + } else (c = Ce(c, 'textord')), (m = Er[Number(c.text)]); + return { + type: 'genfrac', + mode: a.mode, + numer: n, + denom: i, + continued: !1, + hasBarLine: r, + barSize: h, + leftDelim: o, + rightDelim: s, + size: m, + }; + }, + htmlBuilder: Or, + mathmlBuilder: Rr, + }), + _t({ + type: 'infix', + names: ['\\above'], + props: { numArgs: 1, argTypes: ['size'], infix: !0 }, + handler: function (t, e) { + var r = t.parser, + a = (t.funcName, t.token); + return { type: 'infix', mode: r.mode, replaceWith: '\\\\abovefrac', size: Ce(e[0], 'size').value, token: a }; + }, + }), + _t({ + type: 'genfrac', + names: ['\\\\abovefrac'], + props: { numArgs: 3, argTypes: ['math', 'size', 'math'] }, + handler: function (t, e) { + var r = t.parser, + a = (t.funcName, e[0]), + n = (function (t) { + if (!t) throw new Error('Expected non-null, but got ' + String(t)); + return t; + })(Ce(e[1], 'infix').size), + i = e[2], + o = n.number > 0; + return { + type: 'genfrac', + mode: r.mode, + numer: a, + denom: i, + continued: !1, + hasBarLine: o, + barSize: n, + leftDelim: null, + rightDelim: null, + size: 'auto', + }; + }, + htmlBuilder: Or, + mathmlBuilder: Rr, + }); + var Pr = function (t, e) { + var r, + a, + n = e.style; + 'supsub' === t.type + ? ((r = t.sup ? oe(t.sup, e.havingStyle(n.sup()), e) : oe(t.sub, e.havingStyle(n.sub()), e)), (a = Ce(t.base, 'horizBrace'))) + : (a = Ce(t, 'horizBrace')); + var i, + o = oe(a.base, e.havingBaseStyle(w.DISPLAY)), + s = Be(a, e); + if ( + (a.isOver + ? (i = Dt.makeVList( + { + positionType: 'firstBaseline', + children: [ + { type: 'elem', elem: o }, + { type: 'kern', size: 0.1 }, + { type: 'elem', elem: s }, + ], + }, + e + )).children[0].children[0].children[1].classes.push('svg-align') + : (i = Dt.makeVList( + { + positionType: 'bottom', + positionData: o.depth + 0.1 + s.height, + children: [ + { type: 'elem', elem: s }, + { type: 'kern', size: 0.1 }, + { type: 'elem', elem: o }, + ], + }, + e + )).children[0].children[0].children[0].classes.push('svg-align'), + r) + ) { + var l = Dt.makeSpan(['mord', a.isOver ? 'mover' : 'munder'], [i], e); + i = a.isOver + ? Dt.makeVList( + { + positionType: 'firstBaseline', + children: [ + { type: 'elem', elem: l }, + { type: 'kern', size: 0.2 }, + { type: 'elem', elem: r }, + ], + }, + e + ) + : Dt.makeVList( + { + positionType: 'bottom', + positionData: l.depth + 0.2 + r.height + r.depth, + children: [ + { type: 'elem', elem: r }, + { type: 'kern', size: 0.2 }, + { type: 'elem', elem: l }, + ], + }, + e + ); + } + return Dt.makeSpan(['mord', a.isOver ? 'mover' : 'munder'], [i], e); + }; + _t({ + type: 'horizBrace', + names: ['\\overbrace', '\\underbrace'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName; + return { type: 'horizBrace', mode: r.mode, label: a, isOver: /^\\over/.test(a), base: e[0] }; + }, + htmlBuilder: Pr, + mathmlBuilder: function (t, e) { + var r = Te(t.label); + return new ue.MathNode(t.isOver ? 'mover' : 'munder', [ve(t.base, e), r]); + }, + }), + _t({ + type: 'href', + names: ['\\href'], + props: { numArgs: 2, argTypes: ['url', 'original'], allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = e[1], + n = Ce(e[0], 'url').url; + return r.settings.isTrusted({ command: '\\href', url: n }) + ? { type: 'href', mode: r.mode, href: n, body: $t(a) } + : r.formatUnsupportedCmd('\\href'); + }, + htmlBuilder: function (t, e) { + var r = ee(t.body, e, !1); + return Dt.makeAnchor(t.href, [], r, e); + }, + mathmlBuilder: function (t, e) { + var r = xe(t.body, e); + return r instanceof me || (r = new me('mrow', [r])), r.setAttribute('href', t.href), r; + }, + }), + _t({ + type: 'href', + names: ['\\url'], + props: { numArgs: 1, argTypes: ['url'], allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = Ce(e[0], 'url').url; + if (!r.settings.isTrusted({ command: '\\url', url: a })) return r.formatUnsupportedCmd('\\url'); + for (var n = [], i = 0; i < a.length; i++) { + var o = a[i]; + '~' === o && (o = '\\textasciitilde'), n.push({ type: 'textord', mode: 'text', text: o }); + } + var s = { type: 'text', mode: r.mode, font: '\\texttt', body: n }; + return { type: 'href', mode: r.mode, href: a, body: $t(s) }; + }, + }), + _t({ + type: 'html', + names: ['\\htmlClass', '\\htmlId', '\\htmlStyle', '\\htmlData'], + props: { numArgs: 2, argTypes: ['raw', 'original'], allowedInText: !0 }, + handler: function (t, e) { + var r, + a = t.parser, + n = t.funcName, + i = (t.token, Ce(e[0], 'raw').string), + s = e[1]; + a.settings.strict && a.settings.reportNonstrict('htmlExtension', 'HTML extension is disabled on strict mode'); + var l = {}; + switch (n) { + case '\\htmlClass': + (l.class = i), (r = { command: '\\htmlClass', class: i }); + break; + case '\\htmlId': + (l.id = i), (r = { command: '\\htmlId', id: i }); + break; + case '\\htmlStyle': + (l.style = i), (r = { command: '\\htmlStyle', style: i }); + break; + case '\\htmlData': + for (var h = i.split(','), m = 0; m < h.length; m++) { + var c = h[m].split('='); + if (2 !== c.length) throw new o('Error parsing key-value for \\htmlData'); + l['data-' + c[0].trim()] = c[1].trim(); + } + r = { command: '\\htmlData', attributes: l }; + break; + default: + throw new Error('Unrecognized html command'); + } + return a.settings.isTrusted(r) ? { type: 'html', mode: a.mode, attributes: l, body: $t(s) } : a.formatUnsupportedCmd(n); + }, + htmlBuilder: function (t, e) { + var r = ee(t.body, e, !1), + a = ['enclosing']; + t.attributes.class && a.push.apply(a, t.attributes.class.trim().split(/\s+/)); + var n = Dt.makeSpan(a, r, e); + for (var i in t.attributes) 'class' !== i && t.attributes.hasOwnProperty(i) && n.setAttribute(i, t.attributes[i]); + return n; + }, + mathmlBuilder: function (t, e) { + return xe(t.body, e); + }, + }), + _t({ + type: 'htmlmathml', + names: ['\\html@mathml'], + props: { numArgs: 2, allowedInText: !0 }, + handler: function (t, e) { + return { type: 'htmlmathml', mode: t.parser.mode, html: $t(e[0]), mathml: $t(e[1]) }; + }, + htmlBuilder: function (t, e) { + var r = ee(t.html, e, !1); + return Dt.makeFragment(r); + }, + mathmlBuilder: function (t, e) { + return xe(t.mathml, e); + }, + }); + var Dr = function (t) { + if (/^[-+]? *(\d+(\.\d*)?|\.\d+)$/.test(t)) return { number: +t, unit: 'bp' }; + var e = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(t); + if (!e) throw new o("Invalid size: '" + t + "' in \\includegraphics"); + var r = { number: +(e[1] + e[2]), unit: e[3] }; + if (!At(r)) throw new o("Invalid unit: '" + r.unit + "' in \\includegraphics."); + return r; + }; + _t({ + type: 'includegraphics', + names: ['\\includegraphics'], + props: { numArgs: 1, numOptionalArgs: 1, argTypes: ['raw', 'url'], allowedInText: !1 }, + handler: function (t, e, r) { + var a = t.parser, + n = { number: 0, unit: 'em' }, + i = { number: 0.9, unit: 'em' }, + s = { number: 0, unit: 'em' }, + l = ''; + if (r[0]) + for (var h = Ce(r[0], 'raw').string.split(','), m = 0; m < h.length; m++) { + var c = h[m].split('='); + if (2 === c.length) { + var u = c[1].trim(); + switch (c[0].trim()) { + case 'alt': + l = u; + break; + case 'width': + n = Dr(u); + break; + case 'height': + i = Dr(u); + break; + case 'totalheight': + s = Dr(u); + break; + default: + throw new o("Invalid key: '" + c[0] + "' in \\includegraphics."); + } + } + } + var p = Ce(e[0], 'url').url; + return ( + '' === l && (l = (l = (l = p).replace(/^.*[\\/]/, '')).substring(0, l.lastIndexOf('.'))), + a.settings.isTrusted({ command: '\\includegraphics', url: p }) + ? { type: 'includegraphics', mode: a.mode, alt: l, width: n, height: i, totalheight: s, src: p } + : a.formatUnsupportedCmd('\\includegraphics') + ); + }, + htmlBuilder: function (t, e) { + var r = Tt(t.height, e), + a = 0; + t.totalheight.number > 0 && ((a = Tt(t.totalheight, e) - r), (a = Number(a.toFixed(2)))); + var n = 0; + t.width.number > 0 && (n = Tt(t.width, e)); + var i = { height: r + a + 'em' }; + n > 0 && (i.width = n + 'em'), a > 0 && (i.verticalAlign = -a + 'em'); + var o = new O(t.src, t.alt, i); + return (o.height = r), (o.depth = a), o; + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mglyph', []); + r.setAttribute('alt', t.alt); + var a = Tt(t.height, e), + n = 0; + if ( + (t.totalheight.number > 0 && ((n = (n = Tt(t.totalheight, e) - a).toFixed(2)), r.setAttribute('valign', '-' + n + 'em')), + r.setAttribute('height', a + n + 'em'), + t.width.number > 0) + ) { + var i = Tt(t.width, e); + r.setAttribute('width', i + 'em'); + } + return r.setAttribute('src', t.src), r; + }, + }), + _t({ + type: 'kern', + names: ['\\kern', '\\mkern', '\\hskip', '\\mskip'], + props: { numArgs: 1, argTypes: ['size'], allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = Ce(e[0], 'size'); + if (r.settings.strict) { + var i = 'm' === a[1], + o = 'mu' === n.value.unit; + i + ? (o || + r.settings.reportNonstrict( + 'mathVsTextUnits', + "LaTeX's " + a + ' supports only mu units, not ' + n.value.unit + ' units' + ), + 'math' !== r.mode && r.settings.reportNonstrict('mathVsTextUnits', "LaTeX's " + a + ' works only in math mode')) + : o && r.settings.reportNonstrict('mathVsTextUnits', "LaTeX's " + a + " doesn't support mu units"); + } + return { type: 'kern', mode: r.mode, dimension: n.value }; + }, + htmlBuilder: function (t, e) { + return Dt.makeGlue(t.dimension, e); + }, + mathmlBuilder: function (t, e) { + var r = Tt(t.dimension, e); + return new ue.SpaceNode(r); + }, + }), + _t({ + type: 'lap', + names: ['\\mathllap', '\\mathrlap', '\\mathclap'], + props: { numArgs: 1, allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = e[0]; + return { type: 'lap', mode: r.mode, alignment: a.slice(5), body: n }; + }, + htmlBuilder: function (t, e) { + var r; + 'clap' === t.alignment + ? ((r = Dt.makeSpan([], [oe(t.body, e)])), (r = Dt.makeSpan(['inner'], [r], e))) + : (r = Dt.makeSpan(['inner'], [oe(t.body, e)])); + var a = Dt.makeSpan(['fix'], []), + n = Dt.makeSpan([t.alignment], [r, a], e), + i = Dt.makeSpan(['strut']); + return ( + (i.style.height = n.height + n.depth + 'em'), + (i.style.verticalAlign = -n.depth + 'em'), + n.children.unshift(i), + (n = Dt.makeSpan(['thinbox'], [n], e)), + Dt.makeSpan(['mord', 'vbox'], [n], e) + ); + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mpadded', [ve(t.body, e)]); + if ('rlap' !== t.alignment) { + var a = 'llap' === t.alignment ? '-1' : '-0.5'; + r.setAttribute('lspace', a + 'width'); + } + return r.setAttribute('width', '0px'), r; + }, + }), + _t({ + type: 'styling', + names: ['\\(', '$'], + props: { numArgs: 0, allowedInText: !0, allowedInMath: !1 }, + handler: function (t, e) { + var r = t.funcName, + a = t.parser, + n = a.mode; + a.switchMode('math'); + var i = '\\(' === r ? '\\)' : '$', + o = a.parseExpression(!1, i); + return a.expect(i), a.switchMode(n), { type: 'styling', mode: a.mode, style: 'text', body: o }; + }, + }), + _t({ + type: 'text', + names: ['\\)', '\\]'], + props: { numArgs: 0, allowedInText: !0, allowedInMath: !1 }, + handler: function (t, e) { + throw new o('Mismatched ' + t.funcName); + }, + }); + var Hr = function (t, e) { + switch (e.style.size) { + case w.DISPLAY.size: + return t.display; + case w.TEXT.size: + return t.text; + case w.SCRIPT.size: + return t.script; + case w.SCRIPTSCRIPT.size: + return t.scriptscript; + default: + return t.text; + } + }; + _t({ + type: 'mathchoice', + names: ['\\mathchoice'], + props: { numArgs: 4 }, + handler: function (t, e) { + return { type: 'mathchoice', mode: t.parser.mode, display: $t(e[0]), text: $t(e[1]), script: $t(e[2]), scriptscript: $t(e[3]) }; + }, + htmlBuilder: function (t, e) { + var r = Hr(t, e), + a = ee(r, e, !1); + return Dt.makeFragment(a); + }, + mathmlBuilder: function (t, e) { + var r = Hr(t, e); + return xe(r, e); + }, + }); + var Fr = function (t, e, r, a, n, i, o) { + var s, l, h; + if (((t = Dt.makeSpan([], [t])), e)) { + var m = oe(e, a.havingStyle(n.sup()), a); + l = { elem: m, kern: Math.max(a.fontMetrics().bigOpSpacing1, a.fontMetrics().bigOpSpacing3 - m.depth) }; + } + if (r) { + var c = oe(r, a.havingStyle(n.sub()), a); + s = { elem: c, kern: Math.max(a.fontMetrics().bigOpSpacing2, a.fontMetrics().bigOpSpacing4 - c.height) }; + } + if (l && s) { + var u = a.fontMetrics().bigOpSpacing5 + s.elem.height + s.elem.depth + s.kern + t.depth + o; + h = Dt.makeVList( + { + positionType: 'bottom', + positionData: u, + children: [ + { type: 'kern', size: a.fontMetrics().bigOpSpacing5 }, + { type: 'elem', elem: s.elem, marginLeft: -i + 'em' }, + { type: 'kern', size: s.kern }, + { type: 'elem', elem: t }, + { type: 'kern', size: l.kern }, + { type: 'elem', elem: l.elem, marginLeft: i + 'em' }, + { type: 'kern', size: a.fontMetrics().bigOpSpacing5 }, + ], + }, + a + ); + } else if (s) { + var p = t.height - o; + h = Dt.makeVList( + { + positionType: 'top', + positionData: p, + children: [ + { type: 'kern', size: a.fontMetrics().bigOpSpacing5 }, + { type: 'elem', elem: s.elem, marginLeft: -i + 'em' }, + { type: 'kern', size: s.kern }, + { type: 'elem', elem: t }, + ], + }, + a + ); + } else { + if (!l) return t; + var d = t.depth + o; + h = Dt.makeVList( + { + positionType: 'bottom', + positionData: d, + children: [ + { type: 'elem', elem: t }, + { type: 'kern', size: l.kern }, + { type: 'elem', elem: l.elem, marginLeft: i + 'em' }, + { type: 'kern', size: a.fontMetrics().bigOpSpacing5 }, + ], + }, + a + ); + } + return Dt.makeSpan(['mop', 'op-limits'], [h], a); + }, + Vr = ['\\smallint'], + Ur = function (t, e) { + var r, + a, + n, + i = !1; + 'supsub' === t.type ? ((r = t.sup), (a = t.sub), (n = Ce(t.base, 'op')), (i = !0)) : (n = Ce(t, 'op')); + var o, + s = e.style, + l = !1; + if ((s.size === w.DISPLAY.size && n.symbol && !c.contains(Vr, n.name) && (l = !0), n.symbol)) { + var h = l ? 'Size2-Regular' : 'Size1-Regular', + m = ''; + if ( + (('\\oiint' !== n.name && '\\oiiint' !== n.name) || ((m = n.name.substr(1)), (n.name = 'oiint' === m ? '\\iint' : '\\iiint')), + (o = Dt.makeSymbol(n.name, h, 'math', e, ['mop', 'op-symbol', l ? 'large-op' : 'small-op'])), + m.length > 0) + ) { + var u = o.italic, + p = Dt.staticSvg(m + 'Size' + (l ? '2' : '1'), e); + (o = Dt.makeVList( + { + positionType: 'individualShift', + children: [ + { type: 'elem', elem: o, shift: 0 }, + { type: 'elem', elem: p, shift: l ? 0.08 : 0 }, + ], + }, + e + )), + (n.name = '\\' + m), + o.classes.unshift('mop'), + (o.italic = u); + } + } else if (n.body) { + var d = ee(n.body, e, !0); + 1 === d.length && d[0] instanceof E ? ((o = d[0]).classes[0] = 'mop') : (o = Dt.makeSpan(['mop'], Dt.tryCombineChars(d), e)); + } else { + for (var f = [], g = 1; g < n.name.length; g++) f.push(Dt.mathsym(n.name[g], n.mode, e)); + o = Dt.makeSpan(['mop'], f, e); + } + var x = 0, + v = 0; + return ( + (o instanceof E || '\\oiint' === n.name || '\\oiiint' === n.name) && + !n.suppressBaseShift && + ((x = (o.height - o.depth) / 2 - e.fontMetrics().axisHeight), (v = o.italic)), + i ? Fr(o, r, a, e, s, v, x) : (x && ((o.style.position = 'relative'), (o.style.top = x + 'em')), o) + ); + }, + Gr = function (t, e) { + var r; + if (t.symbol) (r = new me('mo', [pe(t.name, t.mode)])), c.contains(Vr, t.name) && r.setAttribute('largeop', 'false'); + else if (t.body) r = new me('mo', ge(t.body, e)); + else { + r = new me('mi', [new ce(t.name.slice(1))]); + var a = new me('mo', [pe('\u2061', 'text')]); + r = t.parentIsSupSub ? new me('mo', [r, a]) : he([r, a]); + } + return r; + }, + Yr = { + '\u220f': '\\prod', + '\u2210': '\\coprod', + '\u2211': '\\sum', + '\u22c0': '\\bigwedge', + '\u22c1': '\\bigvee', + '\u22c2': '\\bigcap', + '\u22c3': '\\bigcup', + '\u2a00': '\\bigodot', + '\u2a01': '\\bigoplus', + '\u2a02': '\\bigotimes', + '\u2a04': '\\biguplus', + '\u2a06': '\\bigsqcup', + }; + _t({ + type: 'op', + names: [ + '\\coprod', + '\\bigvee', + '\\bigwedge', + '\\biguplus', + '\\bigcap', + '\\bigcup', + '\\intop', + '\\prod', + '\\sum', + '\\bigotimes', + '\\bigoplus', + '\\bigodot', + '\\bigsqcup', + '\\smallint', + '\u220f', + '\u2210', + '\u2211', + '\u22c0', + '\u22c1', + '\u22c2', + '\u22c3', + '\u2a00', + '\u2a01', + '\u2a02', + '\u2a04', + '\u2a06', + ], + props: { numArgs: 0 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName; + return 1 === a.length && (a = Yr[a]), { type: 'op', mode: r.mode, limits: !0, parentIsSupSub: !1, symbol: !0, name: a }; + }, + htmlBuilder: Ur, + mathmlBuilder: Gr, + }), + _t({ + type: 'op', + names: ['\\mathop'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = t.parser, + a = e[0]; + return { type: 'op', mode: r.mode, limits: !1, parentIsSupSub: !1, symbol: !1, body: $t(a) }; + }, + htmlBuilder: Ur, + mathmlBuilder: Gr, + }); + var Wr = { + '\u222b': '\\int', + '\u222c': '\\iint', + '\u222d': '\\iiint', + '\u222e': '\\oint', + '\u222f': '\\oiint', + '\u2230': '\\oiiint', + }; + _t({ + type: 'op', + names: [ + '\\arcsin', + '\\arccos', + '\\arctan', + '\\arctg', + '\\arcctg', + '\\arg', + '\\ch', + '\\cos', + '\\cosec', + '\\cosh', + '\\cot', + '\\cotg', + '\\coth', + '\\csc', + '\\ctg', + '\\cth', + '\\deg', + '\\dim', + '\\exp', + '\\hom', + '\\ker', + '\\lg', + '\\ln', + '\\log', + '\\sec', + '\\sin', + '\\sinh', + '\\sh', + '\\tan', + '\\tanh', + '\\tg', + '\\th', + ], + props: { numArgs: 0 }, + handler: function (t) { + var e = t.parser, + r = t.funcName; + return { type: 'op', mode: e.mode, limits: !1, parentIsSupSub: !1, symbol: !1, name: r }; + }, + htmlBuilder: Ur, + mathmlBuilder: Gr, + }), + _t({ + type: 'op', + names: ['\\det', '\\gcd', '\\inf', '\\lim', '\\max', '\\min', '\\Pr', '\\sup'], + props: { numArgs: 0 }, + handler: function (t) { + var e = t.parser, + r = t.funcName; + return { type: 'op', mode: e.mode, limits: !0, parentIsSupSub: !1, symbol: !1, name: r }; + }, + htmlBuilder: Ur, + mathmlBuilder: Gr, + }), + _t({ + type: 'op', + names: [ + '\\int', + '\\iint', + '\\iiint', + '\\oint', + '\\oiint', + '\\oiiint', + '\u222b', + '\u222c', + '\u222d', + '\u222e', + '\u222f', + '\u2230', + ], + props: { numArgs: 0 }, + handler: function (t) { + var e = t.parser, + r = t.funcName; + return 1 === r.length && (r = Wr[r]), { type: 'op', mode: e.mode, limits: !1, parentIsSupSub: !1, symbol: !0, name: r }; + }, + htmlBuilder: Ur, + mathmlBuilder: Gr, + }); + var Xr = function (t, e) { + var r, + a, + n, + i, + o = !1; + if ( + ('supsub' === t.type ? ((r = t.sup), (a = t.sub), (n = Ce(t.base, 'operatorname')), (o = !0)) : (n = Ce(t, 'operatorname')), + n.body.length > 0) + ) { + for ( + var s = n.body.map(function (t) { + var e = t.text; + return 'string' == typeof e ? { type: 'textord', mode: t.mode, text: e } : t; + }), + l = ee(s, e.withFont('mathrm'), !0), + h = 0; + h < l.length; + h++ + ) { + var m = l[h]; + m instanceof E && (m.text = m.text.replace(/\u2212/, '-').replace(/\u2217/, '*')); + } + i = Dt.makeSpan(['mop'], l, e); + } else i = Dt.makeSpan(['mop'], [], e); + return o ? Fr(i, r, a, e, e.style, 0, 0) : i; + }; + function _r(t, e, r) { + for (var a = ee(t, e, !1), n = e.sizeMultiplier / r.sizeMultiplier, i = 0; i < a.length; i++) { + var o = a[i].classes.indexOf('sizing'); + o < 0 + ? Array.prototype.push.apply(a[i].classes, e.sizingClasses(r)) + : a[i].classes[o + 1] === 'reset-size' + e.size && (a[i].classes[o + 1] = 'reset-size' + r.size), + (a[i].height *= n), + (a[i].depth *= n); + } + return Dt.makeFragment(a); + } + _t({ + type: 'operatorname', + names: ['\\operatorname', '\\operatorname*'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = e[0]; + return { + type: 'operatorname', + mode: r.mode, + body: $t(n), + alwaysHandleSupSub: '\\operatorname*' === a, + limits: !1, + parentIsSupSub: !1, + }; + }, + htmlBuilder: Xr, + mathmlBuilder: function (t, e) { + for (var r = ge(t.body, e.withFont('mathrm')), a = !0, n = 0; n < r.length; n++) { + var i = r[n]; + if (i instanceof ue.SpaceNode); + else if (i instanceof ue.MathNode) + switch (i.type) { + case 'mi': + case 'mn': + case 'ms': + case 'mspace': + case 'mtext': + break; + case 'mo': + var o = i.children[0]; + 1 === i.children.length && o instanceof ue.TextNode + ? (o.text = o.text.replace(/\u2212/, '-').replace(/\u2217/, '*')) + : (a = !1); + break; + default: + a = !1; + } + else a = !1; + } + if (a) { + var s = r + .map(function (t) { + return t.toText(); + }) + .join(''); + r = [new ue.TextNode(s)]; + } + var l = new ue.MathNode('mi', r); + l.setAttribute('mathvariant', 'normal'); + var h = new ue.MathNode('mo', [pe('\u2061', 'text')]); + return t.parentIsSupSub ? new ue.MathNode('mo', [l, h]) : ue.newDocumentFragment([l, h]); + }, + }), + jt({ + type: 'ordgroup', + htmlBuilder: function (t, e) { + return t.semisimple ? Dt.makeFragment(ee(t.body, e, !1)) : Dt.makeSpan(['mord'], ee(t.body, e, !0), e); + }, + mathmlBuilder: function (t, e) { + return xe(t.body, e, !0); + }, + }), + _t({ + type: 'overline', + names: ['\\overline'], + props: { numArgs: 1 }, + handler: function (t, e) { + var r = t.parser, + a = e[0]; + return { type: 'overline', mode: r.mode, body: a }; + }, + htmlBuilder: function (t, e) { + var r = oe(t.body, e.havingCrampedStyle()), + a = Dt.makeLineSpan('overline-line', e), + n = e.fontMetrics().defaultRuleThickness, + i = Dt.makeVList( + { + positionType: 'firstBaseline', + children: [ + { type: 'elem', elem: r }, + { type: 'kern', size: 3 * n }, + { type: 'elem', elem: a }, + { type: 'kern', size: n }, + ], + }, + e + ); + return Dt.makeSpan(['mord', 'overline'], [i], e); + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mo', [new ue.TextNode('\u203e')]); + r.setAttribute('stretchy', 'true'); + var a = new ue.MathNode('mover', [ve(t.body, e), r]); + return a.setAttribute('accent', 'true'), a; + }, + }), + _t({ + type: 'phantom', + names: ['\\phantom'], + props: { numArgs: 1, allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = e[0]; + return { type: 'phantom', mode: r.mode, body: $t(a) }; + }, + htmlBuilder: function (t, e) { + var r = ee(t.body, e.withPhantom(), !1); + return Dt.makeFragment(r); + }, + mathmlBuilder: function (t, e) { + var r = ge(t.body, e); + return new ue.MathNode('mphantom', r); + }, + }), + _t({ + type: 'hphantom', + names: ['\\hphantom'], + props: { numArgs: 1, allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = e[0]; + return { type: 'hphantom', mode: r.mode, body: a }; + }, + htmlBuilder: function (t, e) { + var r = Dt.makeSpan([], [oe(t.body, e.withPhantom())]); + if (((r.height = 0), (r.depth = 0), r.children)) + for (var a = 0; a < r.children.length; a++) (r.children[a].height = 0), (r.children[a].depth = 0); + return ( + (r = Dt.makeVList({ positionType: 'firstBaseline', children: [{ type: 'elem', elem: r }] }, e)), Dt.makeSpan(['mord'], [r], e) + ); + }, + mathmlBuilder: function (t, e) { + var r = ge($t(t.body), e), + a = new ue.MathNode('mphantom', r), + n = new ue.MathNode('mpadded', [a]); + return n.setAttribute('height', '0px'), n.setAttribute('depth', '0px'), n; + }, + }), + _t({ + type: 'vphantom', + names: ['\\vphantom'], + props: { numArgs: 1, allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = e[0]; + return { type: 'vphantom', mode: r.mode, body: a }; + }, + htmlBuilder: function (t, e) { + var r = Dt.makeSpan(['inner'], [oe(t.body, e.withPhantom())]), + a = Dt.makeSpan(['fix'], []); + return Dt.makeSpan(['mord', 'rlap'], [r, a], e); + }, + mathmlBuilder: function (t, e) { + var r = ge($t(t.body), e), + a = new ue.MathNode('mphantom', r), + n = new ue.MathNode('mpadded', [a]); + return n.setAttribute('width', '0px'), n; + }, + }), + _t({ + type: 'raisebox', + names: ['\\raisebox'], + props: { numArgs: 2, argTypes: ['size', 'hbox'], allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = Ce(e[0], 'size').value, + n = e[1]; + return { type: 'raisebox', mode: r.mode, dy: a, body: n }; + }, + htmlBuilder: function (t, e) { + var r = oe(t.body, e), + a = Tt(t.dy, e); + return Dt.makeVList({ positionType: 'shift', positionData: -a, children: [{ type: 'elem', elem: r }] }, e); + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mpadded', [ve(t.body, e)]), + a = t.dy.number + t.dy.unit; + return r.setAttribute('voffset', a), r; + }, + }), + _t({ + type: 'rule', + names: ['\\rule'], + props: { numArgs: 2, numOptionalArgs: 1, argTypes: ['size', 'size', 'size'] }, + handler: function (t, e, r) { + var a = t.parser, + n = r[0], + i = Ce(e[0], 'size'), + o = Ce(e[1], 'size'); + return { type: 'rule', mode: a.mode, shift: n && Ce(n, 'size').value, width: i.value, height: o.value }; + }, + htmlBuilder: function (t, e) { + var r = Dt.makeSpan(['mord', 'rule'], [], e), + a = Tt(t.width, e), + n = Tt(t.height, e), + i = t.shift ? Tt(t.shift, e) : 0; + return ( + (r.style.borderRightWidth = a + 'em'), + (r.style.borderTopWidth = n + 'em'), + (r.style.bottom = i + 'em'), + (r.width = a), + (r.height = n + i), + (r.depth = -i), + (r.maxFontSize = 1.125 * n * e.sizeMultiplier), + r + ); + }, + mathmlBuilder: function (t, e) { + var r = Tt(t.width, e), + a = Tt(t.height, e), + n = t.shift ? Tt(t.shift, e) : 0, + i = (e.color && e.getColor()) || 'black', + o = new ue.MathNode('mspace'); + o.setAttribute('mathbackground', i), o.setAttribute('width', r + 'em'), o.setAttribute('height', a + 'em'); + var s = new ue.MathNode('mpadded', [o]); + return ( + n >= 0 + ? s.setAttribute('height', '+' + n + 'em') + : (s.setAttribute('height', n + 'em'), s.setAttribute('depth', '+' + -n + 'em')), + s.setAttribute('voffset', n + 'em'), + s + ); + }, + }); + var jr = [ + '\\tiny', + '\\sixptsize', + '\\scriptsize', + '\\footnotesize', + '\\small', + '\\normalsize', + '\\large', + '\\Large', + '\\LARGE', + '\\huge', + '\\Huge', + ]; + _t({ + type: 'sizing', + names: jr, + props: { numArgs: 0, allowedInText: !0 }, + handler: function (t, e) { + var r = t.breakOnTokenText, + a = t.funcName, + n = t.parser, + i = n.parseExpression(!1, r); + return { type: 'sizing', mode: n.mode, size: jr.indexOf(a) + 1, body: i }; + }, + htmlBuilder: function (t, e) { + var r = e.havingSize(t.size); + return _r(t.body, r, e); + }, + mathmlBuilder: function (t, e) { + var r = e.havingSize(t.size), + a = ge(t.body, r), + n = new ue.MathNode('mstyle', a); + return n.setAttribute('mathsize', r.sizeMultiplier + 'em'), n; + }, + }), + _t({ + type: 'smash', + names: ['\\smash'], + props: { numArgs: 1, numOptionalArgs: 1, allowedInText: !0 }, + handler: function (t, e, r) { + var a = t.parser, + n = !1, + i = !1, + o = r[0] && Ce(r[0], 'ordgroup'); + if (o) + for (var s = '', l = 0; l < o.body.length; ++l) { + if ('t' === (s = o.body[l].text)) n = !0; + else { + if ('b' !== s) { + (n = !1), (i = !1); + break; + } + i = !0; + } + } + else (n = !0), (i = !0); + var h = e[0]; + return { type: 'smash', mode: a.mode, body: h, smashHeight: n, smashDepth: i }; + }, + htmlBuilder: function (t, e) { + var r = Dt.makeSpan([], [oe(t.body, e)]); + if (!t.smashHeight && !t.smashDepth) return r; + if (t.smashHeight && ((r.height = 0), r.children)) for (var a = 0; a < r.children.length; a++) r.children[a].height = 0; + if (t.smashDepth && ((r.depth = 0), r.children)) for (var n = 0; n < r.children.length; n++) r.children[n].depth = 0; + var i = Dt.makeVList({ positionType: 'firstBaseline', children: [{ type: 'elem', elem: r }] }, e); + return Dt.makeSpan(['mord'], [i], e); + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mpadded', [ve(t.body, e)]); + return t.smashHeight && r.setAttribute('height', '0px'), t.smashDepth && r.setAttribute('depth', '0px'), r; + }, + }), + _t({ + type: 'sqrt', + names: ['\\sqrt'], + props: { numArgs: 1, numOptionalArgs: 1 }, + handler: function (t, e, r) { + var a = t.parser, + n = r[0], + i = e[0]; + return { type: 'sqrt', mode: a.mode, body: i, index: n }; + }, + htmlBuilder: function (t, e) { + var r = oe(t.body, e.havingCrampedStyle()); + 0 === r.height && (r.height = e.fontMetrics().xHeight), (r = Dt.wrapFragment(r, e)); + var a = e.fontMetrics().defaultRuleThickness, + n = a; + e.style.id < w.TEXT.id && (n = e.fontMetrics().xHeight); + var i = a + n / 4, + o = r.height + r.depth + i + a, + s = ir(o, e), + l = s.span, + h = s.ruleWidth, + m = s.advanceWidth, + c = l.height - h; + c > r.height + r.depth + i && (i = (i + c - r.height - r.depth) / 2); + var u = l.height - r.height - i - h; + r.style.paddingLeft = m + 'em'; + var p = Dt.makeVList( + { + positionType: 'firstBaseline', + children: [ + { type: 'elem', elem: r, wrapperClasses: ['svg-align'] }, + { type: 'kern', size: -(r.height + u) }, + { type: 'elem', elem: l }, + { type: 'kern', size: h }, + ], + }, + e + ); + if (t.index) { + var d = e.havingStyle(w.SCRIPTSCRIPT), + f = oe(t.index, d, e), + g = 0.6 * (p.height - p.depth), + x = Dt.makeVList({ positionType: 'shift', positionData: -g, children: [{ type: 'elem', elem: f }] }, e), + v = Dt.makeSpan(['root'], [x]); + return Dt.makeSpan(['mord', 'sqrt'], [v, p], e); + } + return Dt.makeSpan(['mord', 'sqrt'], [p], e); + }, + mathmlBuilder: function (t, e) { + var r = t.body, + a = t.index; + return a ? new ue.MathNode('mroot', [ve(r, e), ve(a, e)]) : new ue.MathNode('msqrt', [ve(r, e)]); + }, + }); + var $r = { display: w.DISPLAY, text: w.TEXT, script: w.SCRIPT, scriptscript: w.SCRIPTSCRIPT }; + _t({ + type: 'styling', + names: ['\\displaystyle', '\\textstyle', '\\scriptstyle', '\\scriptscriptstyle'], + props: { numArgs: 0, allowedInText: !0 }, + handler: function (t, e) { + var r = t.breakOnTokenText, + a = t.funcName, + n = t.parser, + i = n.parseExpression(!0, r), + o = a.slice(1, a.length - 5); + return { type: 'styling', mode: n.mode, style: o, body: i }; + }, + htmlBuilder: function (t, e) { + var r = $r[t.style], + a = e.havingStyle(r).withFont(''); + return _r(t.body, a, e); + }, + mathmlBuilder: function (t, e) { + var r = $r[t.style], + a = e.havingStyle(r), + n = ge(t.body, a), + i = new ue.MathNode('mstyle', n), + o = { display: ['0', 'true'], text: ['0', 'false'], script: ['1', 'false'], scriptscript: ['2', 'false'] }[t.style]; + return i.setAttribute('scriptlevel', o[0]), i.setAttribute('displaystyle', o[1]), i; + }, + }); + jt({ + type: 'supsub', + htmlBuilder: function (t, e) { + var r = (function (t, e) { + var r = t.base; + return r + ? 'op' === r.type + ? r.limits && (e.style.size === w.DISPLAY.size || r.alwaysHandleSupSub) + ? Ur + : null + : 'operatorname' === r.type + ? r.alwaysHandleSupSub && (e.style.size === w.DISPLAY.size || r.limits) + ? Xr + : null + : 'accent' === r.type + ? c.isCharacterBox(r.base) + ? Ie + : null + : 'horizBrace' === r.type && !t.sub === r.isOver + ? Pr + : null + : null; + })(t, e); + if (r) return r(t, e); + var a, + n, + i, + o = t.base, + s = t.sup, + l = t.sub, + h = oe(o, e), + m = e.fontMetrics(), + u = 0, + p = 0, + d = o && c.isCharacterBox(o); + if (s) { + var f = e.havingStyle(e.style.sup()); + (a = oe(s, f, e)), d || (u = h.height - (f.fontMetrics().supDrop * f.sizeMultiplier) / e.sizeMultiplier); + } + if (l) { + var g = e.havingStyle(e.style.sub()); + (n = oe(l, g, e)), d || (p = h.depth + (g.fontMetrics().subDrop * g.sizeMultiplier) / e.sizeMultiplier); + } + i = e.style === w.DISPLAY ? m.sup1 : e.style.cramped ? m.sup3 : m.sup2; + var x, + v = e.sizeMultiplier, + b = 0.5 / m.ptPerEm / v + 'em', + y = null; + if (n) { + var k = t.base && 'op' === t.base.type && t.base.name && ('\\oiint' === t.base.name || '\\oiiint' === t.base.name); + (h instanceof E || k) && (y = -h.italic + 'em'); + } + if (a && n) { + (u = Math.max(u, i, a.depth + 0.25 * m.xHeight)), (p = Math.max(p, m.sub2)); + var S = 4 * m.defaultRuleThickness; + if (u - a.depth - (n.height - p) < S) { + p = S - (u - a.depth) + n.height; + var M = 0.8 * m.xHeight - (u - a.depth); + M > 0 && ((u += M), (p -= M)); + } + var z = [ + { type: 'elem', elem: n, shift: p, marginRight: b, marginLeft: y }, + { type: 'elem', elem: a, shift: -u, marginRight: b }, + ]; + x = Dt.makeVList({ positionType: 'individualShift', children: z }, e); + } else if (n) { + p = Math.max(p, m.sub1, n.height - 0.8 * m.xHeight); + var A = [{ type: 'elem', elem: n, marginLeft: y, marginRight: b }]; + x = Dt.makeVList({ positionType: 'shift', positionData: p, children: A }, e); + } else { + if (!a) throw new Error('supsub must have either sup or sub.'); + (u = Math.max(u, i, a.depth + 0.25 * m.xHeight)), + (x = Dt.makeVList({ positionType: 'shift', positionData: -u, children: [{ type: 'elem', elem: a, marginRight: b }] }, e)); + } + var T = ne(h, 'right') || 'mord'; + return Dt.makeSpan([T], [h, Dt.makeSpan(['msupsub'], [x])], e); + }, + mathmlBuilder: function (t, e) { + var r, + a = !1; + t.base && 'horizBrace' === t.base.type && !!t.sup === t.base.isOver && ((a = !0), (r = t.base.isOver)), + !t.base || ('op' !== t.base.type && 'operatorname' !== t.base.type) || (t.base.parentIsSupSub = !0); + var n, + i = [ve(t.base, e)]; + if ((t.sub && i.push(ve(t.sub, e)), t.sup && i.push(ve(t.sup, e)), a)) n = r ? 'mover' : 'munder'; + else if (t.sub) + if (t.sup) { + var o = t.base; + n = + o && 'op' === o.type && o.limits && e.style === w.DISPLAY + ? 'munderover' + : o && 'operatorname' === o.type && o.alwaysHandleSupSub && (e.style === w.DISPLAY || o.limits) + ? 'munderover' + : 'msubsup'; + } else { + var s = t.base; + n = + s && 'op' === s.type && s.limits && (e.style === w.DISPLAY || s.alwaysHandleSupSub) + ? 'munder' + : s && 'operatorname' === s.type && s.alwaysHandleSupSub && (s.limits || e.style === w.DISPLAY) + ? 'munder' + : 'msub'; + } + else { + var l = t.base; + n = + l && 'op' === l.type && l.limits && (e.style === w.DISPLAY || l.alwaysHandleSupSub) + ? 'mover' + : l && 'operatorname' === l.type && l.alwaysHandleSupSub && (l.limits || e.style === w.DISPLAY) + ? 'mover' + : 'msup'; + } + return new ue.MathNode(n, i); + }, + }), + jt({ + type: 'atom', + htmlBuilder: function (t, e) { + return Dt.mathsym(t.text, t.mode, e, ['m' + t.family]); + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mo', [pe(t.text, t.mode)]); + if ('bin' === t.family) { + var a = fe(t, e); + 'bold-italic' === a && r.setAttribute('mathvariant', a); + } else + 'punct' === t.family + ? r.setAttribute('separator', 'true') + : ('open' !== t.family && 'close' !== t.family) || r.setAttribute('stretchy', 'false'); + return r; + }, + }); + var Zr = { mi: 'italic', mn: 'normal', mtext: 'normal' }; + jt({ + type: 'mathord', + htmlBuilder: function (t, e) { + return Dt.makeOrd(t, e, 'mathord'); + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mi', [pe(t.text, t.mode, e)]), + a = fe(t, e) || 'italic'; + return a !== Zr[r.type] && r.setAttribute('mathvariant', a), r; + }, + }), + jt({ + type: 'textord', + htmlBuilder: function (t, e) { + return Dt.makeOrd(t, e, 'textord'); + }, + mathmlBuilder: function (t, e) { + var r, + a = pe(t.text, t.mode, e), + n = fe(t, e) || 'normal'; + return ( + (r = + 'text' === t.mode + ? new ue.MathNode('mtext', [a]) + : /[0-9]/.test(t.text) + ? new ue.MathNode('mn', [a]) + : '\\prime' === t.text + ? new ue.MathNode('mo', [a]) + : new ue.MathNode('mi', [a])), + n !== Zr[r.type] && r.setAttribute('mathvariant', n), + r + ); + }, + }); + var Kr = { '\\nobreak': 'nobreak', '\\allowbreak': 'allowbreak' }, + Jr = { ' ': {}, '\\ ': {}, '~': { className: 'nobreak' }, '\\space': {}, '\\nobreakspace': { className: 'nobreak' } }; + jt({ + type: 'spacing', + htmlBuilder: function (t, e) { + if (Jr.hasOwnProperty(t.text)) { + var r = Jr[t.text].className || ''; + if ('text' === t.mode) { + var a = Dt.makeOrd(t, e, 'textord'); + return a.classes.push(r), a; + } + return Dt.makeSpan(['mspace', r], [Dt.mathsym(t.text, t.mode, e)], e); + } + if (Kr.hasOwnProperty(t.text)) return Dt.makeSpan(['mspace', Kr[t.text]], [], e); + throw new o('Unknown type of space "' + t.text + '"'); + }, + mathmlBuilder: function (t, e) { + if (!Jr.hasOwnProperty(t.text)) { + if (Kr.hasOwnProperty(t.text)) return new ue.MathNode('mspace'); + throw new o('Unknown type of space "' + t.text + '"'); + } + return new ue.MathNode('mtext', [new ue.TextNode('\xa0')]); + }, + }); + var Qr = function () { + var t = new ue.MathNode('mtd', []); + return t.setAttribute('width', '50%'), t; + }; + jt({ + type: 'tag', + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mtable', [ + new ue.MathNode('mtr', [Qr(), new ue.MathNode('mtd', [xe(t.body, e)]), Qr(), new ue.MathNode('mtd', [xe(t.tag, e)])]), + ]); + return r.setAttribute('width', '100%'), r; + }, + }); + var ta = { '\\text': void 0, '\\textrm': 'textrm', '\\textsf': 'textsf', '\\texttt': 'texttt', '\\textnormal': 'textrm' }, + ea = { '\\textbf': 'textbf', '\\textmd': 'textmd' }, + ra = { '\\textit': 'textit', '\\textup': 'textup' }, + aa = function (t, e) { + var r = t.font; + return r ? (ta[r] ? e.withTextFontFamily(ta[r]) : ea[r] ? e.withTextFontWeight(ea[r]) : e.withTextFontShape(ra[r])) : e; + }; + _t({ + type: 'text', + names: ['\\text', '\\textrm', '\\textsf', '\\texttt', '\\textnormal', '\\textbf', '\\textmd', '\\textit', '\\textup'], + props: { numArgs: 1, argTypes: ['text'], greediness: 2, allowedInText: !0 }, + handler: function (t, e) { + var r = t.parser, + a = t.funcName, + n = e[0]; + return { type: 'text', mode: r.mode, body: $t(n), font: a }; + }, + htmlBuilder: function (t, e) { + var r = aa(t, e), + a = ee(t.body, r, !0); + return Dt.makeSpan(['mord', 'text'], Dt.tryCombineChars(a), r); + }, + mathmlBuilder: function (t, e) { + var r = aa(t, e); + return xe(t.body, r); + }, + }), + _t({ + type: 'underline', + names: ['\\underline'], + props: { numArgs: 1, allowedInText: !0 }, + handler: function (t, e) { + return { type: 'underline', mode: t.parser.mode, body: e[0] }; + }, + htmlBuilder: function (t, e) { + var r = oe(t.body, e), + a = Dt.makeLineSpan('underline-line', e), + n = e.fontMetrics().defaultRuleThickness, + i = Dt.makeVList( + { + positionType: 'top', + positionData: r.height, + children: [ + { type: 'kern', size: n }, + { type: 'elem', elem: a }, + { type: 'kern', size: 3 * n }, + { type: 'elem', elem: r }, + ], + }, + e + ); + return Dt.makeSpan(['mord', 'underline'], [i], e); + }, + mathmlBuilder: function (t, e) { + var r = new ue.MathNode('mo', [new ue.TextNode('\u203e')]); + r.setAttribute('stretchy', 'true'); + var a = new ue.MathNode('munder', [ve(t.body, e), r]); + return a.setAttribute('accentunder', 'true'), a; + }, + }), + _t({ + type: 'verb', + names: ['\\verb'], + props: { numArgs: 0, allowedInText: !0 }, + handler: function (t, e, r) { + throw new o('\\verb ended by end of line instead of matching delimiter'); + }, + htmlBuilder: function (t, e) { + for (var r = na(t), a = [], n = e.havingStyle(e.style.text()), i = 0; i < r.length; i++) { + var o = r[i]; + '~' === o && (o = '\\textasciitilde'), a.push(Dt.makeSymbol(o, 'Typewriter-Regular', t.mode, n, ['mord', 'texttt'])); + } + return Dt.makeSpan(['mord', 'text'].concat(n.sizingClasses(e)), Dt.tryCombineChars(a), n); + }, + mathmlBuilder: function (t, e) { + var r = new ue.TextNode(na(t)), + a = new ue.MathNode('mtext', [r]); + return a.setAttribute('mathvariant', 'monospace'), a; + }, + }); + var na = function (t) { + return t.body.replace(/ /g, t.star ? '\u2423' : '\xa0'); + }, + ia = Yt, + oa = new RegExp('^(\\\\[a-zA-Z@]+)[ \r\n\t]*$'), + sa = new RegExp('[\u0300-\u036f]+$'), + la = + '([ \r\n\t]+)|([!-\\[\\]-\u2027\u202a-\ud7ff\uf900-\uffff][\u0300-\u036f]*|[\ud800-\udbff][\udc00-\udfff][\u0300-\u036f]*|\\\\verb\\*([^]).*?\\3|\\\\verb([^*a-zA-Z]).*?\\4|\\\\operatorname\\*|\\\\[a-zA-Z@]+[ \r\n\t]*|\\\\[^\ud800-\udfff])', + ha = (function () { + function t(t, e) { + (this.input = void 0), + (this.settings = void 0), + (this.tokenRegex = void 0), + (this.catcodes = void 0), + (this.input = t), + (this.settings = e), + (this.tokenRegex = new RegExp(la, 'g')), + (this.catcodes = { '%': 14 }); + } + var e = t.prototype; + return ( + (e.setCatcode = function (t, e) { + this.catcodes[t] = e; + }), + (e.lex = function () { + var t = this.input, + e = this.tokenRegex.lastIndex; + if (e === t.length) return new n('EOF', new a(this, e, e)); + var r = this.tokenRegex.exec(t); + if (null === r || r.index !== e) throw new o("Unexpected character: '" + t[e] + "'", new n(t[e], new a(this, e, e + 1))); + var i = r[2] || ' '; + if (14 === this.catcodes[i]) { + var s = t.indexOf('\n', this.tokenRegex.lastIndex); + return ( + -1 === s + ? ((this.tokenRegex.lastIndex = t.length), + this.settings.reportNonstrict( + 'commentAtEnd', + '% comment has no terminating newline; LaTeX would fail because of commenting the end of math mode (e.g. $)' + )) + : (this.tokenRegex.lastIndex = s + 1), + this.lex() + ); + } + var l = i.match(oa); + return l && (i = l[1]), new n(i, new a(this, e, this.tokenRegex.lastIndex)); + }), + t + ); + })(), + ma = (function () { + function t(t, e) { + void 0 === t && (t = {}), + void 0 === e && (e = {}), + (this.current = void 0), + (this.builtins = void 0), + (this.undefStack = void 0), + (this.current = e), + (this.builtins = t), + (this.undefStack = []); + } + var e = t.prototype; + return ( + (e.beginGroup = function () { + this.undefStack.push({}); + }), + (e.endGroup = function () { + if (0 === this.undefStack.length) + throw new o('Unbalanced namespace destruction: attempt to pop global namespace; please report this as a bug'); + var t = this.undefStack.pop(); + for (var e in t) t.hasOwnProperty(e) && (void 0 === t[e] ? delete this.current[e] : (this.current[e] = t[e])); + }), + (e.has = function (t) { + return this.current.hasOwnProperty(t) || this.builtins.hasOwnProperty(t); + }), + (e.get = function (t) { + return this.current.hasOwnProperty(t) ? this.current[t] : this.builtins[t]; + }), + (e.set = function (t, e, r) { + if ((void 0 === r && (r = !1), r)) { + for (var a = 0; a < this.undefStack.length; a++) delete this.undefStack[a][t]; + this.undefStack.length > 0 && (this.undefStack[this.undefStack.length - 1][t] = e); + } else { + var n = this.undefStack[this.undefStack.length - 1]; + n && !n.hasOwnProperty(t) && (n[t] = this.current[t]); + } + this.current[t] = e; + }), + t + ); + })(), + ca = {}, + ua = ca; + function pa(t, e) { + ca[t] = e; + } + pa('\\noexpand', function (t) { + var e = t.popToken(); + return t.isExpandable(e.text) && ((e.noexpand = !0), (e.treatAsRelax = !0)), { tokens: [e], numArgs: 0 }; + }), + pa('\\expandafter', function (t) { + var e = t.popToken(); + return t.expandOnce(!0), { tokens: [e], numArgs: 0 }; + }), + pa('\\@firstoftwo', function (t) { + return { tokens: t.consumeArgs(2)[0], numArgs: 0 }; + }), + pa('\\@secondoftwo', function (t) { + return { tokens: t.consumeArgs(2)[1], numArgs: 0 }; + }), + pa('\\@ifnextchar', function (t) { + var e = t.consumeArgs(3); + t.consumeSpaces(); + var r = t.future(); + return 1 === e[0].length && e[0][0].text === r.text ? { tokens: e[1], numArgs: 0 } : { tokens: e[2], numArgs: 0 }; + }), + pa('\\@ifstar', '\\@ifnextchar *{\\@firstoftwo{#1}}'), + pa('\\TextOrMath', function (t) { + var e = t.consumeArgs(2); + return 'text' === t.mode ? { tokens: e[0], numArgs: 0 } : { tokens: e[1], numArgs: 0 }; + }); + var da = { + 0: 0, + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 5, + 6: 6, + 7: 7, + 8: 8, + 9: 9, + a: 10, + A: 10, + b: 11, + B: 11, + c: 12, + C: 12, + d: 13, + D: 13, + e: 14, + E: 14, + f: 15, + F: 15, + }; + pa('\\char', function (t) { + var e, + r = t.popToken(), + a = ''; + if ("'" === r.text) (e = 8), (r = t.popToken()); + else if ('"' === r.text) (e = 16), (r = t.popToken()); + else if ('`' === r.text) + if ('\\' === (r = t.popToken()).text[0]) a = r.text.charCodeAt(1); + else { + if ('EOF' === r.text) throw new o('\\char` missing argument'); + a = r.text.charCodeAt(0); + } + else e = 10; + if (e) { + if (null == (a = da[r.text]) || a >= e) throw new o('Invalid base-' + e + ' digit ' + r.text); + for (var n; null != (n = da[t.future().text]) && n < e; ) (a *= e), (a += n), t.popToken(); + } + return '\\@char{' + a + '}'; + }); + var fa = function (t, e, r) { + var a = t.consumeArgs(1)[0]; + if (1 !== a.length) throw new o("\\newcommand's first argument must be a macro name"); + var n = a[0].text, + i = t.isDefined(n); + if (i && !e) throw new o('\\newcommand{' + n + '} attempting to redefine ' + n + '; use \\renewcommand'); + if (!i && !r) throw new o('\\renewcommand{' + n + '} when command ' + n + ' does not yet exist; use \\newcommand'); + var s = 0; + if (1 === (a = t.consumeArgs(1)[0]).length && '[' === a[0].text) { + for (var l = '', h = t.expandNextToken(); ']' !== h.text && 'EOF' !== h.text; ) (l += h.text), (h = t.expandNextToken()); + if (!l.match(/^\s*[0-9]+\s*$/)) throw new o('Invalid number of arguments: ' + l); + (s = parseInt(l)), (a = t.consumeArgs(1)[0]); + } + return t.macros.set(n, { tokens: a, numArgs: s }), ''; + }; + pa('\\newcommand', function (t) { + return fa(t, !1, !0); + }), + pa('\\renewcommand', function (t) { + return fa(t, !0, !1); + }), + pa('\\providecommand', function (t) { + return fa(t, !0, !0); + }), + pa('\\message', function (t) { + var e = t.consumeArgs(1)[0]; + return ( + console.log( + e + .reverse() + .map(function (t) { + return t.text; + }) + .join('') + ), + '' + ); + }), + pa('\\errmessage', function (t) { + var e = t.consumeArgs(1)[0]; + return ( + console.error( + e + .reverse() + .map(function (t) { + return t.text; + }) + .join('') + ), + '' + ); + }), + pa('\\show', function (t) { + var e = t.popToken(), + r = e.text; + return console.log(e, t.macros.get(r), ia[r], j.math[r], j.text[r]), ''; + }), + pa('\\bgroup', '{'), + pa('\\egroup', '}'), + pa('\\lq', '`'), + pa('\\rq', "'"), + pa('\\aa', '\\r a'), + pa('\\AA', '\\r A'), + pa('\\textcopyright', '\\html@mathml{\\textcircled{c}}{\\char`\xa9}'), + pa('\\copyright', '\\TextOrMath{\\textcopyright}{\\text{\\textcopyright}}'), + pa('\\textregistered', '\\html@mathml{\\textcircled{\\scriptsize R}}{\\char`\xae}'), + pa('\u212c', '\\mathscr{B}'), + pa('\u2130', '\\mathscr{E}'), + pa('\u2131', '\\mathscr{F}'), + pa('\u210b', '\\mathscr{H}'), + pa('\u2110', '\\mathscr{I}'), + pa('\u2112', '\\mathscr{L}'), + pa('\u2133', '\\mathscr{M}'), + pa('\u211b', '\\mathscr{R}'), + pa('\u212d', '\\mathfrak{C}'), + pa('\u210c', '\\mathfrak{H}'), + pa('\u2128', '\\mathfrak{Z}'), + pa('\\Bbbk', '\\Bbb{k}'), + pa('\xb7', '\\cdotp'), + pa('\\llap', '\\mathllap{\\textrm{#1}}'), + pa('\\rlap', '\\mathrlap{\\textrm{#1}}'), + pa('\\clap', '\\mathclap{\\textrm{#1}}'), + pa('\\not', '\\html@mathml{\\mathrel{\\mathrlap\\@not}}{\\char"338}'), + pa('\\neq', '\\html@mathml{\\mathrel{\\not=}}{\\mathrel{\\char`\u2260}}'), + pa('\\ne', '\\neq'), + pa('\u2260', '\\neq'), + pa('\\notin', '\\html@mathml{\\mathrel{{\\in}\\mathllap{/\\mskip1mu}}}{\\mathrel{\\char`\u2209}}'), + pa('\u2209', '\\notin'), + pa('\u2258', '\\html@mathml{\\mathrel{=\\kern{-1em}\\raisebox{0.4em}{$\\scriptsize\\frown$}}}{\\mathrel{\\char`\u2258}}'), + pa('\u2259', '\\html@mathml{\\stackrel{\\tiny\\wedge}{=}}{\\mathrel{\\char`\u2258}}'), + pa('\u225a', '\\html@mathml{\\stackrel{\\tiny\\vee}{=}}{\\mathrel{\\char`\u225a}}'), + pa('\u225b', '\\html@mathml{\\stackrel{\\scriptsize\\star}{=}}{\\mathrel{\\char`\u225b}}'), + pa('\u225d', '\\html@mathml{\\stackrel{\\tiny\\mathrm{def}}{=}}{\\mathrel{\\char`\u225d}}'), + pa('\u225e', '\\html@mathml{\\stackrel{\\tiny\\mathrm{m}}{=}}{\\mathrel{\\char`\u225e}}'), + pa('\u225f', '\\html@mathml{\\stackrel{\\tiny?}{=}}{\\mathrel{\\char`\u225f}}'), + pa('\u27c2', '\\perp'), + pa('\u203c', '\\mathclose{!\\mkern-0.8mu!}'), + pa('\u220c', '\\notni'), + pa('\u231c', '\\ulcorner'), + pa('\u231d', '\\urcorner'), + pa('\u231e', '\\llcorner'), + pa('\u231f', '\\lrcorner'), + pa('\xa9', '\\copyright'), + pa('\xae', '\\textregistered'), + pa('\ufe0f', '\\textregistered'), + pa('\\ulcorner', '\\html@mathml{\\@ulcorner}{\\mathop{\\char"231c}}'), + pa('\\urcorner', '\\html@mathml{\\@urcorner}{\\mathop{\\char"231d}}'), + pa('\\llcorner', '\\html@mathml{\\@llcorner}{\\mathop{\\char"231e}}'), + pa('\\lrcorner', '\\html@mathml{\\@lrcorner}{\\mathop{\\char"231f}}'), + pa('\\vdots', '\\mathord{\\varvdots\\rule{0pt}{15pt}}'), + pa('\u22ee', '\\vdots'), + pa('\\varGamma', '\\mathit{\\Gamma}'), + pa('\\varDelta', '\\mathit{\\Delta}'), + pa('\\varTheta', '\\mathit{\\Theta}'), + pa('\\varLambda', '\\mathit{\\Lambda}'), + pa('\\varXi', '\\mathit{\\Xi}'), + pa('\\varPi', '\\mathit{\\Pi}'), + pa('\\varSigma', '\\mathit{\\Sigma}'), + pa('\\varUpsilon', '\\mathit{\\Upsilon}'), + pa('\\varPhi', '\\mathit{\\Phi}'), + pa('\\varPsi', '\\mathit{\\Psi}'), + pa('\\varOmega', '\\mathit{\\Omega}'), + pa('\\substack', '\\begin{subarray}{c}#1\\end{subarray}'), + pa('\\colon', '\\nobreak\\mskip2mu\\mathpunct{}\\mathchoice{\\mkern-3mu}{\\mkern-3mu}{}{}{:}\\mskip6mu'), + pa('\\boxed', '\\fbox{$\\displaystyle{#1}$}'), + pa('\\iff', '\\DOTSB\\;\\Longleftrightarrow\\;'), + pa('\\implies', '\\DOTSB\\;\\Longrightarrow\\;'), + pa('\\impliedby', '\\DOTSB\\;\\Longleftarrow\\;'); + var ga = { + ',': '\\dotsc', + '\\not': '\\dotsb', + '+': '\\dotsb', + '=': '\\dotsb', + '<': '\\dotsb', + '>': '\\dotsb', + '-': '\\dotsb', + '*': '\\dotsb', + ':': '\\dotsb', + '\\DOTSB': '\\dotsb', + '\\coprod': '\\dotsb', + '\\bigvee': '\\dotsb', + '\\bigwedge': '\\dotsb', + '\\biguplus': '\\dotsb', + '\\bigcap': '\\dotsb', + '\\bigcup': '\\dotsb', + '\\prod': '\\dotsb', + '\\sum': '\\dotsb', + '\\bigotimes': '\\dotsb', + '\\bigoplus': '\\dotsb', + '\\bigodot': '\\dotsb', + '\\bigsqcup': '\\dotsb', + '\\And': '\\dotsb', + '\\longrightarrow': '\\dotsb', + '\\Longrightarrow': '\\dotsb', + '\\longleftarrow': '\\dotsb', + '\\Longleftarrow': '\\dotsb', + '\\longleftrightarrow': '\\dotsb', + '\\Longleftrightarrow': '\\dotsb', + '\\mapsto': '\\dotsb', + '\\longmapsto': '\\dotsb', + '\\hookrightarrow': '\\dotsb', + '\\doteq': '\\dotsb', + '\\mathbin': '\\dotsb', + '\\mathrel': '\\dotsb', + '\\relbar': '\\dotsb', + '\\Relbar': '\\dotsb', + '\\xrightarrow': '\\dotsb', + '\\xleftarrow': '\\dotsb', + '\\DOTSI': '\\dotsi', + '\\int': '\\dotsi', + '\\oint': '\\dotsi', + '\\iint': '\\dotsi', + '\\iiint': '\\dotsi', + '\\iiiint': '\\dotsi', + '\\idotsint': '\\dotsi', + '\\DOTSX': '\\dotsx', + }; + pa('\\dots', function (t) { + var e = '\\dotso', + r = t.expandAfterFuture().text; + return ( + r in ga + ? (e = ga[r]) + : '\\not' === r.substr(0, 4) + ? (e = '\\dotsb') + : r in j.math && c.contains(['bin', 'rel'], j.math[r].group) && (e = '\\dotsb'), + e + ); + }); + var xa = { + ')': !0, + ']': !0, + '\\rbrack': !0, + '\\}': !0, + '\\rbrace': !0, + '\\rangle': !0, + '\\rceil': !0, + '\\rfloor': !0, + '\\rgroup': !0, + '\\rmoustache': !0, + '\\right': !0, + '\\bigr': !0, + '\\biggr': !0, + '\\Bigr': !0, + '\\Biggr': !0, + $: !0, + ';': !0, + '.': !0, + ',': !0, + }; + pa('\\dotso', function (t) { + return t.future().text in xa ? '\\ldots\\,' : '\\ldots'; + }), + pa('\\dotsc', function (t) { + var e = t.future().text; + return e in xa && ',' !== e ? '\\ldots\\,' : '\\ldots'; + }), + pa('\\cdots', function (t) { + return t.future().text in xa ? '\\@cdots\\,' : '\\@cdots'; + }), + pa('\\dotsb', '\\cdots'), + pa('\\dotsm', '\\cdots'), + pa('\\dotsi', '\\!\\cdots'), + pa('\\dotsx', '\\ldots\\,'), + pa('\\DOTSI', '\\relax'), + pa('\\DOTSB', '\\relax'), + pa('\\DOTSX', '\\relax'), + pa('\\tmspace', '\\TextOrMath{\\kern#1#3}{\\mskip#1#2}\\relax'), + pa('\\,', '\\tmspace+{3mu}{.1667em}'), + pa('\\thinspace', '\\,'), + pa('\\>', '\\mskip{4mu}'), + pa('\\:', '\\tmspace+{4mu}{.2222em}'), + pa('\\medspace', '\\:'), + pa('\\;', '\\tmspace+{5mu}{.2777em}'), + pa('\\thickspace', '\\;'), + pa('\\!', '\\tmspace-{3mu}{.1667em}'), + pa('\\negthinspace', '\\!'), + pa('\\negmedspace', '\\tmspace-{4mu}{.2222em}'), + pa('\\negthickspace', '\\tmspace-{5mu}{.277em}'), + pa('\\enspace', '\\kern.5em '), + pa('\\enskip', '\\hskip.5em\\relax'), + pa('\\quad', '\\hskip1em\\relax'), + pa('\\qquad', '\\hskip2em\\relax'), + pa('\\tag', '\\@ifstar\\tag@literal\\tag@paren'), + pa('\\tag@paren', '\\tag@literal{({#1})}'), + pa('\\tag@literal', function (t) { + if (t.macros.get('\\df@tag')) throw new o('Multiple \\tag'); + return '\\gdef\\df@tag{\\text{#1}}'; + }), + pa( + '\\bmod', + '\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}\\mathbin{\\rm mod}\\mathchoice{\\mskip1mu}{\\mskip1mu}{\\mskip5mu}{\\mskip5mu}' + ), + pa('\\pod', '\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern8mu}{\\mkern8mu}{\\mkern8mu}(#1)'), + pa('\\pmod', '\\pod{{\\rm mod}\\mkern6mu#1}'), + pa('\\mod', '\\allowbreak\\mathchoice{\\mkern18mu}{\\mkern12mu}{\\mkern12mu}{\\mkern12mu}{\\rm mod}\\,\\,#1'), + pa('\\pmb', '\\html@mathml{\\@binrel{#1}{\\mathrlap{#1}\\kern0.5px#1}}{\\mathbf{#1}}'), + pa('\\\\', '\\newline'), + pa('\\TeX', '\\textrm{\\html@mathml{T\\kern-.1667em\\raisebox{-.5ex}{E}\\kern-.125emX}{TeX}}'); + var va = F['Main-Regular']['T'.charCodeAt(0)][1] - 0.7 * F['Main-Regular']['A'.charCodeAt(0)][1] + 'em'; + pa('\\LaTeX', '\\textrm{\\html@mathml{L\\kern-.36em\\raisebox{' + va + '}{\\scriptstyle A}\\kern-.15em\\TeX}{LaTeX}}'), + pa('\\KaTeX', '\\textrm{\\html@mathml{K\\kern-.17em\\raisebox{' + va + '}{\\scriptstyle A}\\kern-.15em\\TeX}{KaTeX}}'), + pa('\\hspace', '\\@ifstar\\@hspacer\\@hspace'), + pa('\\@hspace', '\\hskip #1\\relax'), + pa('\\@hspacer', '\\rule{0pt}{0pt}\\hskip #1\\relax'), + pa('\\ordinarycolon', ':'), + pa('\\vcentcolon', '\\mathrel{\\mathop\\ordinarycolon}'), + pa('\\dblcolon', '\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-.9mu}\\vcentcolon}}{\\mathop{\\char"2237}}'), + pa('\\coloneqq', '\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2254}}'), + pa('\\Coloneqq', '\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}=}}{\\mathop{\\char"2237\\char"3d}}'), + pa('\\coloneq', '\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"3a\\char"2212}}'), + pa('\\Coloneq', '\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\mathrel{-}}}{\\mathop{\\char"2237\\char"2212}}'), + pa('\\eqqcolon', '\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2255}}'), + pa('\\Eqqcolon', '\\html@mathml{\\mathrel{=\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"3d\\char"2237}}'), + pa('\\eqcolon', '\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\vcentcolon}}{\\mathop{\\char"2239}}'), + pa('\\Eqcolon', '\\html@mathml{\\mathrel{\\mathrel{-}\\mathrel{\\mkern-1.2mu}\\dblcolon}}{\\mathop{\\char"2212\\char"2237}}'), + pa('\\colonapprox', '\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"3a\\char"2248}}'), + pa('\\Colonapprox', '\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\approx}}{\\mathop{\\char"2237\\char"2248}}'), + pa('\\colonsim', '\\html@mathml{\\mathrel{\\vcentcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"3a\\char"223c}}'), + pa('\\Colonsim', '\\html@mathml{\\mathrel{\\dblcolon\\mathrel{\\mkern-1.2mu}\\sim}}{\\mathop{\\char"2237\\char"223c}}'), + pa('\u2237', '\\dblcolon'), + pa('\u2239', '\\eqcolon'), + pa('\u2254', '\\coloneqq'), + pa('\u2255', '\\eqqcolon'), + pa('\u2a74', '\\Coloneqq'), + pa('\\ratio', '\\vcentcolon'), + pa('\\coloncolon', '\\dblcolon'), + pa('\\colonequals', '\\coloneqq'), + pa('\\coloncolonequals', '\\Coloneqq'), + pa('\\equalscolon', '\\eqqcolon'), + pa('\\equalscoloncolon', '\\Eqqcolon'), + pa('\\colonminus', '\\coloneq'), + pa('\\coloncolonminus', '\\Coloneq'), + pa('\\minuscolon', '\\eqcolon'), + pa('\\minuscoloncolon', '\\Eqcolon'), + pa('\\coloncolonapprox', '\\Colonapprox'), + pa('\\coloncolonsim', '\\Colonsim'), + pa('\\simcolon', '\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\vcentcolon}'), + pa('\\simcoloncolon', '\\mathrel{\\sim\\mathrel{\\mkern-1.2mu}\\dblcolon}'), + pa('\\approxcolon', '\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\vcentcolon}'), + pa('\\approxcoloncolon', '\\mathrel{\\approx\\mathrel{\\mkern-1.2mu}\\dblcolon}'), + pa('\\notni', '\\html@mathml{\\not\\ni}{\\mathrel{\\char`\u220c}}'), + pa('\\limsup', '\\DOTSB\\operatorname*{lim\\,sup}'), + pa('\\liminf', '\\DOTSB\\operatorname*{lim\\,inf}'), + pa('\\gvertneqq', '\\html@mathml{\\@gvertneqq}{\u2269}'), + pa('\\lvertneqq', '\\html@mathml{\\@lvertneqq}{\u2268}'), + pa('\\ngeqq', '\\html@mathml{\\@ngeqq}{\u2271}'), + pa('\\ngeqslant', '\\html@mathml{\\@ngeqslant}{\u2271}'), + pa('\\nleqq', '\\html@mathml{\\@nleqq}{\u2270}'), + pa('\\nleqslant', '\\html@mathml{\\@nleqslant}{\u2270}'), + pa('\\nshortmid', '\\html@mathml{\\@nshortmid}{\u2224}'), + pa('\\nshortparallel', '\\html@mathml{\\@nshortparallel}{\u2226}'), + pa('\\nsubseteqq', '\\html@mathml{\\@nsubseteqq}{\u2288}'), + pa('\\nsupseteqq', '\\html@mathml{\\@nsupseteqq}{\u2289}'), + pa('\\varsubsetneq', '\\html@mathml{\\@varsubsetneq}{\u228a}'), + pa('\\varsubsetneqq', '\\html@mathml{\\@varsubsetneqq}{\u2acb}'), + pa('\\varsupsetneq', '\\html@mathml{\\@varsupsetneq}{\u228b}'), + pa('\\varsupsetneqq', '\\html@mathml{\\@varsupsetneqq}{\u2acc}'), + pa('\\imath', '\\html@mathml{\\@imath}{\u0131}'), + pa('\\jmath', '\\html@mathml{\\@jmath}{\u0237}'), + pa('\\llbracket', '\\html@mathml{\\mathopen{[\\mkern-3.2mu[}}{\\mathopen{\\char`\u27e6}}'), + pa('\\rrbracket', '\\html@mathml{\\mathclose{]\\mkern-3.2mu]}}{\\mathclose{\\char`\u27e7}}'), + pa('\u27e6', '\\llbracket'), + pa('\u27e7', '\\rrbracket'), + pa('\\lBrace', '\\html@mathml{\\mathopen{\\{\\mkern-3.2mu[}}{\\mathopen{\\char`\u2983}}'), + pa('\\rBrace', '\\html@mathml{\\mathclose{]\\mkern-3.2mu\\}}}{\\mathclose{\\char`\u2984}}'), + pa('\u2983', '\\lBrace'), + pa('\u2984', '\\rBrace'), + pa( + '\\minuso', + '\\mathbin{\\html@mathml{{\\mathrlap{\\mathchoice{\\kern{0.145em}}{\\kern{0.145em}}{\\kern{0.1015em}}{\\kern{0.0725em}}\\circ}{-}}}{\\char`\u29b5}}' + ), + pa('\u29b5', '\\minuso'), + pa('\\darr', '\\downarrow'), + pa('\\dArr', '\\Downarrow'), + pa('\\Darr', '\\Downarrow'), + pa('\\lang', '\\langle'), + pa('\\rang', '\\rangle'), + pa('\\uarr', '\\uparrow'), + pa('\\uArr', '\\Uparrow'), + pa('\\Uarr', '\\Uparrow'), + pa('\\N', '\\mathbb{N}'), + pa('\\R', '\\mathbb{R}'), + pa('\\Z', '\\mathbb{Z}'), + pa('\\alef', '\\aleph'), + pa('\\alefsym', '\\aleph'), + pa('\\Alpha', '\\mathrm{A}'), + pa('\\Beta', '\\mathrm{B}'), + pa('\\bull', '\\bullet'), + pa('\\Chi', '\\mathrm{X}'), + pa('\\clubs', '\\clubsuit'), + pa('\\cnums', '\\mathbb{C}'), + pa('\\Complex', '\\mathbb{C}'), + pa('\\Dagger', '\\ddagger'), + pa('\\diamonds', '\\diamondsuit'), + pa('\\empty', '\\emptyset'), + pa('\\Epsilon', '\\mathrm{E}'), + pa('\\Eta', '\\mathrm{H}'), + pa('\\exist', '\\exists'), + pa('\\harr', '\\leftrightarrow'), + pa('\\hArr', '\\Leftrightarrow'), + pa('\\Harr', '\\Leftrightarrow'), + pa('\\hearts', '\\heartsuit'), + pa('\\image', '\\Im'), + pa('\\infin', '\\infty'), + pa('\\Iota', '\\mathrm{I}'), + pa('\\isin', '\\in'), + pa('\\Kappa', '\\mathrm{K}'), + pa('\\larr', '\\leftarrow'), + pa('\\lArr', '\\Leftarrow'), + pa('\\Larr', '\\Leftarrow'), + pa('\\lrarr', '\\leftrightarrow'), + pa('\\lrArr', '\\Leftrightarrow'), + pa('\\Lrarr', '\\Leftrightarrow'), + pa('\\Mu', '\\mathrm{M}'), + pa('\\natnums', '\\mathbb{N}'), + pa('\\Nu', '\\mathrm{N}'), + pa('\\Omicron', '\\mathrm{O}'), + pa('\\plusmn', '\\pm'), + pa('\\rarr', '\\rightarrow'), + pa('\\rArr', '\\Rightarrow'), + pa('\\Rarr', '\\Rightarrow'), + pa('\\real', '\\Re'), + pa('\\reals', '\\mathbb{R}'), + pa('\\Reals', '\\mathbb{R}'), + pa('\\Rho', '\\mathrm{P}'), + pa('\\sdot', '\\cdot'), + pa('\\sect', '\\S'), + pa('\\spades', '\\spadesuit'), + pa('\\sub', '\\subset'), + pa('\\sube', '\\subseteq'), + pa('\\supe', '\\supseteq'), + pa('\\Tau', '\\mathrm{T}'), + pa('\\thetasym', '\\vartheta'), + pa('\\weierp', '\\wp'), + pa('\\Zeta', '\\mathrm{Z}'), + pa('\\argmin', '\\DOTSB\\operatorname*{arg\\,min}'), + pa('\\argmax', '\\DOTSB\\operatorname*{arg\\,max}'), + pa('\\plim', '\\DOTSB\\mathop{\\operatorname{plim}}\\limits'), + pa('\\bra', '\\mathinner{\\langle{#1}|}'), + pa('\\ket', '\\mathinner{|{#1}\\rangle}'), + pa('\\braket', '\\mathinner{\\langle{#1}\\rangle}'), + pa('\\Bra', '\\left\\langle#1\\right|'), + pa('\\Ket', '\\left|#1\\right\\rangle'), + pa('\\blue', '\\textcolor{##6495ed}{#1}'), + pa('\\orange', '\\textcolor{##ffa500}{#1}'), + pa('\\pink', '\\textcolor{##ff00af}{#1}'), + pa('\\red', '\\textcolor{##df0030}{#1}'), + pa('\\green', '\\textcolor{##28ae7b}{#1}'), + pa('\\gray', '\\textcolor{gray}{#1}'), + pa('\\purple', '\\textcolor{##9d38bd}{#1}'), + pa('\\blueA', '\\textcolor{##ccfaff}{#1}'), + pa('\\blueB', '\\textcolor{##80f6ff}{#1}'), + pa('\\blueC', '\\textcolor{##63d9ea}{#1}'), + pa('\\blueD', '\\textcolor{##11accd}{#1}'), + pa('\\blueE', '\\textcolor{##0c7f99}{#1}'), + pa('\\tealA', '\\textcolor{##94fff5}{#1}'), + pa('\\tealB', '\\textcolor{##26edd5}{#1}'), + pa('\\tealC', '\\textcolor{##01d1c1}{#1}'), + pa('\\tealD', '\\textcolor{##01a995}{#1}'), + pa('\\tealE', '\\textcolor{##208170}{#1}'), + pa('\\greenA', '\\textcolor{##b6ffb0}{#1}'), + pa('\\greenB', '\\textcolor{##8af281}{#1}'), + pa('\\greenC', '\\textcolor{##74cf70}{#1}'), + pa('\\greenD', '\\textcolor{##1fab54}{#1}'), + pa('\\greenE', '\\textcolor{##0d923f}{#1}'), + pa('\\goldA', '\\textcolor{##ffd0a9}{#1}'), + pa('\\goldB', '\\textcolor{##ffbb71}{#1}'), + pa('\\goldC', '\\textcolor{##ff9c39}{#1}'), + pa('\\goldD', '\\textcolor{##e07d10}{#1}'), + pa('\\goldE', '\\textcolor{##a75a05}{#1}'), + pa('\\redA', '\\textcolor{##fca9a9}{#1}'), + pa('\\redB', '\\textcolor{##ff8482}{#1}'), + pa('\\redC', '\\textcolor{##f9685d}{#1}'), + pa('\\redD', '\\textcolor{##e84d39}{#1}'), + pa('\\redE', '\\textcolor{##bc2612}{#1}'), + pa('\\maroonA', '\\textcolor{##ffbde0}{#1}'), + pa('\\maroonB', '\\textcolor{##ff92c6}{#1}'), + pa('\\maroonC', '\\textcolor{##ed5fa6}{#1}'), + pa('\\maroonD', '\\textcolor{##ca337c}{#1}'), + pa('\\maroonE', '\\textcolor{##9e034e}{#1}'), + pa('\\purpleA', '\\textcolor{##ddd7ff}{#1}'), + pa('\\purpleB', '\\textcolor{##c6b9fc}{#1}'), + pa('\\purpleC', '\\textcolor{##aa87ff}{#1}'), + pa('\\purpleD', '\\textcolor{##7854ab}{#1}'), + pa('\\purpleE', '\\textcolor{##543b78}{#1}'), + pa('\\mintA', '\\textcolor{##f5f9e8}{#1}'), + pa('\\mintB', '\\textcolor{##edf2df}{#1}'), + pa('\\mintC', '\\textcolor{##e0e5cc}{#1}'), + pa('\\grayA', '\\textcolor{##f6f7f7}{#1}'), + pa('\\grayB', '\\textcolor{##f0f1f2}{#1}'), + pa('\\grayC', '\\textcolor{##e3e5e6}{#1}'), + pa('\\grayD', '\\textcolor{##d6d8da}{#1}'), + pa('\\grayE', '\\textcolor{##babec2}{#1}'), + pa('\\grayF', '\\textcolor{##888d93}{#1}'), + pa('\\grayG', '\\textcolor{##626569}{#1}'), + pa('\\grayH', '\\textcolor{##3b3e40}{#1}'), + pa('\\grayI', '\\textcolor{##21242c}{#1}'), + pa('\\kaBlue', '\\textcolor{##314453}{#1}'), + pa('\\kaGreen', '\\textcolor{##71B307}{#1}'); + var ba = { '\\relax': !0, '^': !0, _: !0, '\\limits': !0, '\\nolimits': !0 }, + ya = (function () { + function t(t, e, r) { + (this.settings = void 0), + (this.expansionCount = void 0), + (this.lexer = void 0), + (this.macros = void 0), + (this.stack = void 0), + (this.mode = void 0), + (this.settings = e), + (this.expansionCount = 0), + this.feed(t), + (this.macros = new ma(ua, e.macros)), + (this.mode = r), + (this.stack = []); + } + var e = t.prototype; + return ( + (e.feed = function (t) { + this.lexer = new ha(t, this.settings); + }), + (e.switchMode = function (t) { + this.mode = t; + }), + (e.beginGroup = function () { + this.macros.beginGroup(); + }), + (e.endGroup = function () { + this.macros.endGroup(); + }), + (e.future = function () { + return 0 === this.stack.length && this.pushToken(this.lexer.lex()), this.stack[this.stack.length - 1]; + }), + (e.popToken = function () { + return this.future(), this.stack.pop(); + }), + (e.pushToken = function (t) { + this.stack.push(t); + }), + (e.pushTokens = function (t) { + var e; + (e = this.stack).push.apply(e, t); + }), + (e.consumeSpaces = function () { + for (;;) { + if (' ' !== this.future().text) break; + this.stack.pop(); + } + }), + (e.consumeArgs = function (t) { + for (var e = [], r = 0; r < t; ++r) { + this.consumeSpaces(); + var a = this.popToken(); + if ('{' === a.text) { + for (var n = [], i = 1; 0 !== i; ) { + var s = this.popToken(); + if ((n.push(s), '{' === s.text)) ++i; + else if ('}' === s.text) --i; + else if ('EOF' === s.text) throw new o('End of input in macro argument', a); + } + n.pop(), n.reverse(), (e[r] = n); + } else { + if ('EOF' === a.text) throw new o('End of input expecting macro argument'); + e[r] = [a]; + } + } + return e; + }), + (e.expandOnce = function (t) { + var e = this.popToken(), + r = e.text, + a = e.noexpand ? null : this._getExpansion(r); + if (null == a || (t && a.unexpandable)) { + if (t && null == a && '\\' === r[0] && !this.isDefined(r)) throw new o('Undefined control sequence: ' + r); + return this.pushToken(e), e; + } + if ((this.expansionCount++, this.expansionCount > this.settings.maxExpand)) + throw new o('Too many expansions: infinite loop or need to increase maxExpand setting'); + var n = a.tokens; + if (a.numArgs) + for (var i = this.consumeArgs(a.numArgs), s = (n = n.slice()).length - 1; s >= 0; --s) { + var l = n[s]; + if ('#' === l.text) { + if (0 === s) throw new o('Incomplete placeholder at end of macro body', l); + if ('#' === (l = n[--s]).text) n.splice(s + 1, 1); + else { + if (!/^[1-9]$/.test(l.text)) throw new o('Not a valid argument number', l); + var h; + (h = n).splice.apply(h, [s, 2].concat(i[+l.text - 1])); + } + } + } + return this.pushTokens(n), n; + }), + (e.expandAfterFuture = function () { + return this.expandOnce(), this.future(); + }), + (e.expandNextToken = function () { + for (;;) { + var t = this.expandOnce(); + if (t instanceof n) { + if ('\\relax' !== t.text && !t.treatAsRelax) return this.stack.pop(); + this.stack.pop(); + } + } + throw new Error(); + }), + (e.expandMacro = function (t) { + return this.macros.has(t) ? this.expandTokens([new n(t)]) : void 0; + }), + (e.expandTokens = function (t) { + var e = [], + r = this.stack.length; + for (this.pushTokens(t); this.stack.length > r; ) { + var a = this.expandOnce(!0); + a instanceof n && (a.treatAsRelax && ((a.noexpand = !1), (a.treatAsRelax = !1)), e.push(this.stack.pop())); + } + return e; + }), + (e.expandMacroAsText = function (t) { + var e = this.expandMacro(t); + return e + ? e + .map(function (t) { + return t.text; + }) + .join('') + : e; + }), + (e._getExpansion = function (t) { + var e = this.macros.get(t); + if (null == e) return e; + var r = 'function' == typeof e ? e(this) : e; + if ('string' == typeof r) { + var a = 0; + if (-1 !== r.indexOf('#')) for (var n = r.replace(/##/g, ''); -1 !== n.indexOf('#' + (a + 1)); ) ++a; + for (var i = new ha(r, this.settings), o = [], s = i.lex(); 'EOF' !== s.text; ) o.push(s), (s = i.lex()); + return o.reverse(), { tokens: o, numArgs: a }; + } + return r; + }), + (e.isDefined = function (t) { + return ( + this.macros.has(t) || ia.hasOwnProperty(t) || j.math.hasOwnProperty(t) || j.text.hasOwnProperty(t) || ba.hasOwnProperty(t) + ); + }), + (e.isExpandable = function (t) { + var e = this.macros.get(t); + return null != e ? 'string' == typeof e || 'function' == typeof e || !e.unexpandable : ia.hasOwnProperty(t); + }), + t + ); + })(), + wa = { + '\u0301': { text: "\\'", math: '\\acute' }, + '\u0300': { text: '\\`', math: '\\grave' }, + '\u0308': { text: '\\"', math: '\\ddot' }, + '\u0303': { text: '\\~', math: '\\tilde' }, + '\u0304': { text: '\\=', math: '\\bar' }, + '\u0306': { text: '\\u', math: '\\breve' }, + '\u030c': { text: '\\v', math: '\\check' }, + '\u0302': { text: '\\^', math: '\\hat' }, + '\u0307': { text: '\\.', math: '\\dot' }, + '\u030a': { text: '\\r', math: '\\mathring' }, + '\u030b': { text: '\\H' }, + }, + ka = { + '\xe1': 'a\u0301', + '\xe0': 'a\u0300', + '\xe4': 'a\u0308', + '\u01df': 'a\u0308\u0304', + '\xe3': 'a\u0303', + '\u0101': 'a\u0304', + '\u0103': 'a\u0306', + '\u1eaf': 'a\u0306\u0301', + '\u1eb1': 'a\u0306\u0300', + '\u1eb5': 'a\u0306\u0303', + '\u01ce': 'a\u030c', + '\xe2': 'a\u0302', + '\u1ea5': 'a\u0302\u0301', + '\u1ea7': 'a\u0302\u0300', + '\u1eab': 'a\u0302\u0303', + '\u0227': 'a\u0307', + '\u01e1': 'a\u0307\u0304', + '\xe5': 'a\u030a', + '\u01fb': 'a\u030a\u0301', + '\u1e03': 'b\u0307', + '\u0107': 'c\u0301', + '\u010d': 'c\u030c', + '\u0109': 'c\u0302', + '\u010b': 'c\u0307', + '\u010f': 'd\u030c', + '\u1e0b': 'd\u0307', + '\xe9': 'e\u0301', + '\xe8': 'e\u0300', + '\xeb': 'e\u0308', + '\u1ebd': 'e\u0303', + '\u0113': 'e\u0304', + '\u1e17': 'e\u0304\u0301', + '\u1e15': 'e\u0304\u0300', + '\u0115': 'e\u0306', + '\u011b': 'e\u030c', + '\xea': 'e\u0302', + '\u1ebf': 'e\u0302\u0301', + '\u1ec1': 'e\u0302\u0300', + '\u1ec5': 'e\u0302\u0303', + '\u0117': 'e\u0307', + '\u1e1f': 'f\u0307', + '\u01f5': 'g\u0301', + '\u1e21': 'g\u0304', + '\u011f': 'g\u0306', + '\u01e7': 'g\u030c', + '\u011d': 'g\u0302', + '\u0121': 'g\u0307', + '\u1e27': 'h\u0308', + '\u021f': 'h\u030c', + '\u0125': 'h\u0302', + '\u1e23': 'h\u0307', + '\xed': 'i\u0301', + '\xec': 'i\u0300', + '\xef': 'i\u0308', + '\u1e2f': 'i\u0308\u0301', + '\u0129': 'i\u0303', + '\u012b': 'i\u0304', + '\u012d': 'i\u0306', + '\u01d0': 'i\u030c', + '\xee': 'i\u0302', + '\u01f0': 'j\u030c', + '\u0135': 'j\u0302', + '\u1e31': 'k\u0301', + '\u01e9': 'k\u030c', + '\u013a': 'l\u0301', + '\u013e': 'l\u030c', + '\u1e3f': 'm\u0301', + '\u1e41': 'm\u0307', + '\u0144': 'n\u0301', + '\u01f9': 'n\u0300', + '\xf1': 'n\u0303', + '\u0148': 'n\u030c', + '\u1e45': 'n\u0307', + '\xf3': 'o\u0301', + '\xf2': 'o\u0300', + '\xf6': 'o\u0308', + '\u022b': 'o\u0308\u0304', + '\xf5': 'o\u0303', + '\u1e4d': 'o\u0303\u0301', + '\u1e4f': 'o\u0303\u0308', + '\u022d': 'o\u0303\u0304', + '\u014d': 'o\u0304', + '\u1e53': 'o\u0304\u0301', + '\u1e51': 'o\u0304\u0300', + '\u014f': 'o\u0306', + '\u01d2': 'o\u030c', + '\xf4': 'o\u0302', + '\u1ed1': 'o\u0302\u0301', + '\u1ed3': 'o\u0302\u0300', + '\u1ed7': 'o\u0302\u0303', + '\u022f': 'o\u0307', + '\u0231': 'o\u0307\u0304', + '\u0151': 'o\u030b', + '\u1e55': 'p\u0301', + '\u1e57': 'p\u0307', + '\u0155': 'r\u0301', + '\u0159': 'r\u030c', + '\u1e59': 'r\u0307', + '\u015b': 's\u0301', + '\u1e65': 's\u0301\u0307', + '\u0161': 's\u030c', + '\u1e67': 's\u030c\u0307', + '\u015d': 's\u0302', + '\u1e61': 's\u0307', + '\u1e97': 't\u0308', + '\u0165': 't\u030c', + '\u1e6b': 't\u0307', + '\xfa': 'u\u0301', + '\xf9': 'u\u0300', + '\xfc': 'u\u0308', + '\u01d8': 'u\u0308\u0301', + '\u01dc': 'u\u0308\u0300', + '\u01d6': 'u\u0308\u0304', + '\u01da': 'u\u0308\u030c', + '\u0169': 'u\u0303', + '\u1e79': 'u\u0303\u0301', + '\u016b': 'u\u0304', + '\u1e7b': 'u\u0304\u0308', + '\u016d': 'u\u0306', + '\u01d4': 'u\u030c', + '\xfb': 'u\u0302', + '\u016f': 'u\u030a', + '\u0171': 'u\u030b', + '\u1e7d': 'v\u0303', + '\u1e83': 'w\u0301', + '\u1e81': 'w\u0300', + '\u1e85': 'w\u0308', + '\u0175': 'w\u0302', + '\u1e87': 'w\u0307', + '\u1e98': 'w\u030a', + '\u1e8d': 'x\u0308', + '\u1e8b': 'x\u0307', + '\xfd': 'y\u0301', + '\u1ef3': 'y\u0300', + '\xff': 'y\u0308', + '\u1ef9': 'y\u0303', + '\u0233': 'y\u0304', + '\u0177': 'y\u0302', + '\u1e8f': 'y\u0307', + '\u1e99': 'y\u030a', + '\u017a': 'z\u0301', + '\u017e': 'z\u030c', + '\u1e91': 'z\u0302', + '\u017c': 'z\u0307', + '\xc1': 'A\u0301', + '\xc0': 'A\u0300', + '\xc4': 'A\u0308', + '\u01de': 'A\u0308\u0304', + '\xc3': 'A\u0303', + '\u0100': 'A\u0304', + '\u0102': 'A\u0306', + '\u1eae': 'A\u0306\u0301', + '\u1eb0': 'A\u0306\u0300', + '\u1eb4': 'A\u0306\u0303', + '\u01cd': 'A\u030c', + '\xc2': 'A\u0302', + '\u1ea4': 'A\u0302\u0301', + '\u1ea6': 'A\u0302\u0300', + '\u1eaa': 'A\u0302\u0303', + '\u0226': 'A\u0307', + '\u01e0': 'A\u0307\u0304', + '\xc5': 'A\u030a', + '\u01fa': 'A\u030a\u0301', + '\u1e02': 'B\u0307', + '\u0106': 'C\u0301', + '\u010c': 'C\u030c', + '\u0108': 'C\u0302', + '\u010a': 'C\u0307', + '\u010e': 'D\u030c', + '\u1e0a': 'D\u0307', + '\xc9': 'E\u0301', + '\xc8': 'E\u0300', + '\xcb': 'E\u0308', + '\u1ebc': 'E\u0303', + '\u0112': 'E\u0304', + '\u1e16': 'E\u0304\u0301', + '\u1e14': 'E\u0304\u0300', + '\u0114': 'E\u0306', + '\u011a': 'E\u030c', + '\xca': 'E\u0302', + '\u1ebe': 'E\u0302\u0301', + '\u1ec0': 'E\u0302\u0300', + '\u1ec4': 'E\u0302\u0303', + '\u0116': 'E\u0307', + '\u1e1e': 'F\u0307', + '\u01f4': 'G\u0301', + '\u1e20': 'G\u0304', + '\u011e': 'G\u0306', + '\u01e6': 'G\u030c', + '\u011c': 'G\u0302', + '\u0120': 'G\u0307', + '\u1e26': 'H\u0308', + '\u021e': 'H\u030c', + '\u0124': 'H\u0302', + '\u1e22': 'H\u0307', + '\xcd': 'I\u0301', + '\xcc': 'I\u0300', + '\xcf': 'I\u0308', + '\u1e2e': 'I\u0308\u0301', + '\u0128': 'I\u0303', + '\u012a': 'I\u0304', + '\u012c': 'I\u0306', + '\u01cf': 'I\u030c', + '\xce': 'I\u0302', + '\u0130': 'I\u0307', + '\u0134': 'J\u0302', + '\u1e30': 'K\u0301', + '\u01e8': 'K\u030c', + '\u0139': 'L\u0301', + '\u013d': 'L\u030c', + '\u1e3e': 'M\u0301', + '\u1e40': 'M\u0307', + '\u0143': 'N\u0301', + '\u01f8': 'N\u0300', + '\xd1': 'N\u0303', + '\u0147': 'N\u030c', + '\u1e44': 'N\u0307', + '\xd3': 'O\u0301', + '\xd2': 'O\u0300', + '\xd6': 'O\u0308', + '\u022a': 'O\u0308\u0304', + '\xd5': 'O\u0303', + '\u1e4c': 'O\u0303\u0301', + '\u1e4e': 'O\u0303\u0308', + '\u022c': 'O\u0303\u0304', + '\u014c': 'O\u0304', + '\u1e52': 'O\u0304\u0301', + '\u1e50': 'O\u0304\u0300', + '\u014e': 'O\u0306', + '\u01d1': 'O\u030c', + '\xd4': 'O\u0302', + '\u1ed0': 'O\u0302\u0301', + '\u1ed2': 'O\u0302\u0300', + '\u1ed6': 'O\u0302\u0303', + '\u022e': 'O\u0307', + '\u0230': 'O\u0307\u0304', + '\u0150': 'O\u030b', + '\u1e54': 'P\u0301', + '\u1e56': 'P\u0307', + '\u0154': 'R\u0301', + '\u0158': 'R\u030c', + '\u1e58': 'R\u0307', + '\u015a': 'S\u0301', + '\u1e64': 'S\u0301\u0307', + '\u0160': 'S\u030c', + '\u1e66': 'S\u030c\u0307', + '\u015c': 'S\u0302', + '\u1e60': 'S\u0307', + '\u0164': 'T\u030c', + '\u1e6a': 'T\u0307', + '\xda': 'U\u0301', + '\xd9': 'U\u0300', + '\xdc': 'U\u0308', + '\u01d7': 'U\u0308\u0301', + '\u01db': 'U\u0308\u0300', + '\u01d5': 'U\u0308\u0304', + '\u01d9': 'U\u0308\u030c', + '\u0168': 'U\u0303', + '\u1e78': 'U\u0303\u0301', + '\u016a': 'U\u0304', + '\u1e7a': 'U\u0304\u0308', + '\u016c': 'U\u0306', + '\u01d3': 'U\u030c', + '\xdb': 'U\u0302', + '\u016e': 'U\u030a', + '\u0170': 'U\u030b', + '\u1e7c': 'V\u0303', + '\u1e82': 'W\u0301', + '\u1e80': 'W\u0300', + '\u1e84': 'W\u0308', + '\u0174': 'W\u0302', + '\u1e86': 'W\u0307', + '\u1e8c': 'X\u0308', + '\u1e8a': 'X\u0307', + '\xdd': 'Y\u0301', + '\u1ef2': 'Y\u0300', + '\u0178': 'Y\u0308', + '\u1ef8': 'Y\u0303', + '\u0232': 'Y\u0304', + '\u0176': 'Y\u0302', + '\u1e8e': 'Y\u0307', + '\u0179': 'Z\u0301', + '\u017d': 'Z\u030c', + '\u1e90': 'Z\u0302', + '\u017b': 'Z\u0307', + '\u03ac': '\u03b1\u0301', + '\u1f70': '\u03b1\u0300', + '\u1fb1': '\u03b1\u0304', + '\u1fb0': '\u03b1\u0306', + '\u03ad': '\u03b5\u0301', + '\u1f72': '\u03b5\u0300', + '\u03ae': '\u03b7\u0301', + '\u1f74': '\u03b7\u0300', + '\u03af': '\u03b9\u0301', + '\u1f76': '\u03b9\u0300', + '\u03ca': '\u03b9\u0308', + '\u0390': '\u03b9\u0308\u0301', + '\u1fd2': '\u03b9\u0308\u0300', + '\u1fd1': '\u03b9\u0304', + '\u1fd0': '\u03b9\u0306', + '\u03cc': '\u03bf\u0301', + '\u1f78': '\u03bf\u0300', + '\u03cd': '\u03c5\u0301', + '\u1f7a': '\u03c5\u0300', + '\u03cb': '\u03c5\u0308', + '\u03b0': '\u03c5\u0308\u0301', + '\u1fe2': '\u03c5\u0308\u0300', + '\u1fe1': '\u03c5\u0304', + '\u1fe0': '\u03c5\u0306', + '\u03ce': '\u03c9\u0301', + '\u1f7c': '\u03c9\u0300', + '\u038e': '\u03a5\u0301', + '\u1fea': '\u03a5\u0300', + '\u03ab': '\u03a5\u0308', + '\u1fe9': '\u03a5\u0304', + '\u1fe8': '\u03a5\u0306', + '\u038f': '\u03a9\u0301', + '\u1ffa': '\u03a9\u0300', + }, + Sa = (function () { + function t(t, e) { + (this.mode = void 0), + (this.gullet = void 0), + (this.settings = void 0), + (this.leftrightDepth = void 0), + (this.nextToken = void 0), + (this.mode = 'math'), + (this.gullet = new ya(t, e, this.mode)), + (this.settings = e), + (this.leftrightDepth = 0); + } + var e = t.prototype; + return ( + (e.expect = function (t, e) { + if ((void 0 === e && (e = !0), this.fetch().text !== t)) + throw new o("Expected '" + t + "', got '" + this.fetch().text + "'", this.fetch()); + e && this.consume(); + }), + (e.consume = function () { + this.nextToken = null; + }), + (e.fetch = function () { + return null == this.nextToken && (this.nextToken = this.gullet.expandNextToken()), this.nextToken; + }), + (e.switchMode = function (t) { + (this.mode = t), this.gullet.switchMode(t); + }), + (e.parse = function () { + this.settings.globalGroup || this.gullet.beginGroup(), + this.settings.colorIsTextColor && this.gullet.macros.set('\\color', '\\textcolor'); + var t = this.parseExpression(!1); + return this.expect('EOF'), this.settings.globalGroup || this.gullet.endGroup(), t; + }), + (e.parseExpression = function (e, r) { + for (var a = []; ; ) { + 'math' === this.mode && this.consumeSpaces(); + var n = this.fetch(); + if (-1 !== t.endOfExpression.indexOf(n.text)) break; + if (r && n.text === r) break; + if (e && ia[n.text] && ia[n.text].infix) break; + var i = this.parseAtom(r); + if (!i) break; + 'internal' !== i.type && a.push(i); + } + return 'text' === this.mode && this.formLigatures(a), this.handleInfixNodes(a); + }), + (e.handleInfixNodes = function (t) { + for (var e, r = -1, a = 0; a < t.length; a++) + if ('infix' === t[a].type) { + if (-1 !== r) throw new o('only one infix operator per group', t[a].token); + (r = a), (e = t[a].replaceWith); + } + if (-1 !== r && e) { + var n, + i, + s = t.slice(0, r), + l = t.slice(r + 1); + return ( + (n = 1 === s.length && 'ordgroup' === s[0].type ? s[0] : { type: 'ordgroup', mode: this.mode, body: s }), + (i = 1 === l.length && 'ordgroup' === l[0].type ? l[0] : { type: 'ordgroup', mode: this.mode, body: l }), + ['\\\\abovefrac' === e ? this.callFunction(e, [n, t[r], i], []) : this.callFunction(e, [n, i], [])] + ); + } + return t; + }), + (e.handleSupSubscript = function (e) { + var r = this.fetch(), + a = r.text; + this.consume(); + var n = this.parseGroup(e, !1, t.SUPSUB_GREEDINESS, void 0, void 0, !0); + if (!n) throw new o("Expected group after '" + a + "'", r); + return n; + }), + (e.formatUnsupportedCmd = function (t) { + for (var e = [], r = 0; r < t.length; r++) e.push({ type: 'textord', mode: 'text', text: t[r] }); + var a = { type: 'text', mode: this.mode, body: e }; + return { type: 'color', mode: this.mode, color: this.settings.errorColor, body: [a] }; + }), + (e.parseAtom = function (t) { + var e, + r, + a = this.parseGroup('atom', !1, null, t); + if ('text' === this.mode) return a; + for (;;) { + this.consumeSpaces(); + var n = this.fetch(); + if ('\\limits' === n.text || '\\nolimits' === n.text) { + if (a && 'op' === a.type) { + var i = '\\limits' === n.text; + (a.limits = i), (a.alwaysHandleSupSub = !0); + } else { + if (!a || 'operatorname' !== a.type || !a.alwaysHandleSupSub) + throw new o('Limit controls must follow a math operator', n); + var s = '\\limits' === n.text; + a.limits = s; + } + this.consume(); + } else if ('^' === n.text) { + if (e) throw new o('Double superscript', n); + e = this.handleSupSubscript('superscript'); + } else if ('_' === n.text) { + if (r) throw new o('Double subscript', n); + r = this.handleSupSubscript('subscript'); + } else { + if ("'" !== n.text) break; + if (e) throw new o('Double superscript', n); + var l = { type: 'textord', mode: this.mode, text: '\\prime' }, + h = [l]; + for (this.consume(); "'" === this.fetch().text; ) h.push(l), this.consume(); + '^' === this.fetch().text && h.push(this.handleSupSubscript('superscript')), + (e = { type: 'ordgroup', mode: this.mode, body: h }); + } + } + return e || r ? { type: 'supsub', mode: this.mode, base: a, sup: e, sub: r } : a; + }), + (e.parseFunction = function (t, e, r) { + var a = this.fetch(), + n = a.text, + i = ia[n]; + if (!i) return null; + if ((this.consume(), null != r && i.greediness <= r)) + throw new o("Got function '" + n + "' with no arguments" + (e ? ' as ' + e : ''), a); + if ('text' === this.mode && !i.allowedInText) throw new o("Can't use function '" + n + "' in text mode", a); + if ('math' === this.mode && !1 === i.allowedInMath) throw new o("Can't use function '" + n + "' in math mode", a); + var s = this.parseArguments(n, i), + l = s.args, + h = s.optArgs; + return this.callFunction(n, l, h, a, t); + }), + (e.callFunction = function (t, e, r, a, n) { + var i = { funcName: t, parser: this, token: a, breakOnTokenText: n }, + s = ia[t]; + if (s && s.handler) return s.handler(i, e, r); + throw new o('No function handler for ' + t); + }), + (e.parseArguments = function (t, e) { + var r = e.numArgs + e.numOptionalArgs; + if (0 === r) return { args: [], optArgs: [] }; + for (var a = e.greediness, n = [], i = [], s = 0; s < r; s++) { + var l = e.argTypes && e.argTypes[s], + h = s < e.numOptionalArgs, + m = (s > 0 && !h) || (0 === s && !h && 'math' === this.mode), + c = this.parseGroupOfType("argument to '" + t + "'", l, h, a, m); + if (!c) { + if (h) { + i.push(null); + continue; + } + throw new o("Expected group after '" + t + "'", this.fetch()); + } + (h ? i : n).push(c); + } + return { args: n, optArgs: i }; + }), + (e.parseGroupOfType = function (t, e, r, a, n) { + switch (e) { + case 'color': + return n && this.consumeSpaces(), this.parseColorGroup(r); + case 'size': + return n && this.consumeSpaces(), this.parseSizeGroup(r); + case 'url': + return this.parseUrlGroup(r, n); + case 'math': + case 'text': + return this.parseGroup(t, r, a, void 0, e, n); + case 'hbox': + var i = this.parseGroup(t, r, a, void 0, 'text', n); + return i ? { type: 'styling', mode: i.mode, body: [i], style: 'text' } : i; + case 'raw': + if ((n && this.consumeSpaces(), r && '{' === this.fetch().text)) return null; + var s = this.parseStringGroup('raw', r, !0); + if (s) return { type: 'raw', mode: 'text', string: s.text }; + throw new o('Expected raw group', this.fetch()); + case 'original': + case null: + case void 0: + return this.parseGroup(t, r, a, void 0, void 0, n); + default: + throw new o('Unknown group type as ' + t, this.fetch()); + } + }), + (e.consumeSpaces = function () { + for (; ' ' === this.fetch().text; ) this.consume(); + }), + (e.parseStringGroup = function (t, e, r) { + var a = e ? '[' : '{', + n = e ? ']' : '}', + i = this.fetch(); + if (i.text !== a) { + if (e) return null; + if (r && 'EOF' !== i.text && /[^{}[\]]/.test(i.text)) return this.consume(), i; + } + var s = this.mode; + (this.mode = 'text'), this.expect(a); + for (var l, h = '', m = this.fetch(), c = 0, u = m; (l = this.fetch()).text !== n || (r && c > 0); ) { + switch (l.text) { + case 'EOF': + throw new o('Unexpected end of input in ' + t, m.range(u, h)); + case a: + c++; + break; + case n: + c--; + } + (h += (u = l).text), this.consume(); + } + return this.expect(n), (this.mode = s), m.range(u, h); + }), + (e.parseRegexGroup = function (t, e) { + var r = this.mode; + this.mode = 'text'; + for (var a, n = this.fetch(), i = n, s = ''; 'EOF' !== (a = this.fetch()).text && t.test(s + a.text); ) + (s += (i = a).text), this.consume(); + if ('' === s) throw new o('Invalid ' + e + ": '" + n.text + "'", n); + return (this.mode = r), n.range(i, s); + }), + (e.parseColorGroup = function (t) { + var e = this.parseStringGroup('color', t); + if (!e) return null; + var r = /^(#[a-f0-9]{3}|#?[a-f0-9]{6}|[a-z]+)$/i.exec(e.text); + if (!r) throw new o("Invalid color: '" + e.text + "'", e); + var a = r[0]; + return /^[0-9a-f]{6}$/i.test(a) && (a = '#' + a), { type: 'color-token', mode: this.mode, color: a }; + }), + (e.parseSizeGroup = function (t) { + var e, + r = !1; + if ( + !(e = + t || '{' === this.fetch().text + ? this.parseStringGroup('size', t) + : this.parseRegexGroup(/^[-+]? *(?:$|\d+|\d+\.\d*|\.\d*) *[a-z]{0,2} *$/, 'size')) + ) + return null; + t || 0 !== e.text.length || ((e.text = '0pt'), (r = !0)); + var a = /([-+]?) *(\d+(?:\.\d*)?|\.\d+) *([a-z]{2})/.exec(e.text); + if (!a) throw new o("Invalid size: '" + e.text + "'", e); + var n = { number: +(a[1] + a[2]), unit: a[3] }; + if (!At(n)) throw new o("Invalid unit: '" + n.unit + "'", e); + return { type: 'size', mode: this.mode, value: n, isBlank: r }; + }), + (e.parseUrlGroup = function (t, e) { + this.gullet.lexer.setCatcode('%', 13); + var r = this.parseStringGroup('url', t, !0); + if ((this.gullet.lexer.setCatcode('%', 14), !r)) return null; + var a = r.text.replace(/\\([#$%&~_^{}])/g, '$1'); + return { type: 'url', mode: this.mode, url: a }; + }), + (e.parseGroup = function (e, r, n, i, s, l) { + var h = this.mode; + s && this.switchMode(s), l && this.consumeSpaces(); + var m, + c = this.fetch(), + u = c.text; + if (r ? '[' === u : '{' === u || '\\begingroup' === u) { + this.consume(); + var p = t.endOfGroup[u]; + this.gullet.beginGroup(); + var d = this.parseExpression(!1, p), + f = this.fetch(); + this.expect(p), + this.gullet.endGroup(), + (m = { type: 'ordgroup', mode: this.mode, loc: a.range(c, f), body: d, semisimple: '\\begingroup' === u || void 0 }); + } else if (r) m = null; + else if (null == (m = this.parseFunction(i, e, n) || this.parseSymbol()) && '\\' === u[0] && !ba.hasOwnProperty(u)) { + if (this.settings.throwOnError) throw new o('Undefined control sequence: ' + u, c); + (m = this.formatUnsupportedCmd(u)), this.consume(); + } + return s && this.switchMode(h), m; + }), + (e.formLigatures = function (t) { + for (var e = t.length - 1, r = 0; r < e; ++r) { + var n = t[r], + i = n.text; + '-' === i && + '-' === t[r + 1].text && + (r + 1 < e && '-' === t[r + 2].text + ? (t.splice(r, 3, { type: 'textord', mode: 'text', loc: a.range(n, t[r + 2]), text: '---' }), (e -= 2)) + : (t.splice(r, 2, { type: 'textord', mode: 'text', loc: a.range(n, t[r + 1]), text: '--' }), (e -= 1))), + ("'" !== i && '`' !== i) || + t[r + 1].text !== i || + (t.splice(r, 2, { type: 'textord', mode: 'text', loc: a.range(n, t[r + 1]), text: i + i }), (e -= 1)); + } + }), + (e.parseSymbol = function () { + var t = this.fetch(), + e = t.text; + if (/^\\verb[^a-zA-Z]/.test(e)) { + this.consume(); + var r = e.slice(5), + n = '*' === r.charAt(0); + if ((n && (r = r.slice(1)), r.length < 2 || r.charAt(0) !== r.slice(-1))) + throw new o('\\verb assertion failed --\n please report what input caused this bug'); + return { type: 'verb', mode: 'text', body: (r = r.slice(1, -1)), star: n }; + } + ka.hasOwnProperty(e[0]) && + !j[this.mode][e[0]] && + (this.settings.strict && + 'math' === this.mode && + this.settings.reportNonstrict( + 'unicodeTextInMathMode', + 'Accented Unicode text character "' + e[0] + '" used in math mode', + t + ), + (e = ka[e[0]] + e.substr(1))); + var i, + s = sa.exec(e); + if ((s && ('i' === (e = e.substring(0, s.index)) ? (e = '\u0131') : 'j' === e && (e = '\u0237')), j[this.mode][e])) { + this.settings.strict && + 'math' === this.mode && + '\xc7\xd0\xde\xe7\xfe'.indexOf(e) >= 0 && + this.settings.reportNonstrict( + 'unicodeTextInMathMode', + 'Latin-1/Unicode text character "' + e[0] + '" used in math mode', + t + ); + var l, + h = j[this.mode][e].group, + m = a.range(t); + if (W.hasOwnProperty(h)) { + var c = h; + l = { type: 'atom', mode: this.mode, family: c, loc: m, text: e }; + } else l = { type: h, mode: this.mode, loc: m, text: e }; + i = l; + } else { + if (!(e.charCodeAt(0) >= 128)) return null; + this.settings.strict && + (M(e.charCodeAt(0)) + ? 'math' === this.mode && + this.settings.reportNonstrict('unicodeTextInMathMode', 'Unicode text character "' + e[0] + '" used in math mode', t) + : this.settings.reportNonstrict( + 'unknownSymbol', + 'Unrecognized Unicode character "' + e[0] + '" (' + e.charCodeAt(0) + ')', + t + )), + (i = { type: 'textord', mode: 'text', loc: a.range(t), text: e }); + } + if ((this.consume(), s)) + for (var u = 0; u < s[0].length; u++) { + var p = s[0][u]; + if (!wa[p]) throw new o("Unknown accent ' " + p + "'", t); + var d = wa[p][this.mode]; + if (!d) throw new o('Accent ' + p + ' unsupported in ' + this.mode + ' mode', t); + i = { type: 'accent', mode: this.mode, loc: a.range(t), label: d, isStretchy: !1, isShifty: !0, base: i }; + } + return i; + }), + t + ); + })(); + (Sa.endOfExpression = ['}', '\\endgroup', '\\end', '\\right', '&']), + (Sa.endOfGroup = { '[': ']', '{': '}', '\\begingroup': '\\endgroup' }), + (Sa.SUPSUB_GREEDINESS = 1); + var Ma = function (t, e) { + if (!('string' == typeof t || t instanceof String)) throw new TypeError('KaTeX can only parse string typed expression'); + var r = new Sa(t, e); + delete r.gullet.macros.current['\\df@tag']; + var a = r.parse(); + if (r.gullet.macros.get('\\df@tag')) { + if (!e.displayMode) throw new o('\\tag works only in display equations'); + r.gullet.feed('\\df@tag'), (a = [{ type: 'tag', mode: 'text', body: a, tag: r.parse() }]); + } + return a; + }, + za = function (t, e, r) { + e.textContent = ''; + var a = Ta(t, r).toNode(); + e.appendChild(a); + }; + 'undefined' != typeof document && + 'CSS1Compat' !== document.compatMode && + ('undefined' != typeof console && + console.warn("Warning: KaTeX doesn't work in quirks mode. Make sure your website has a suitable doctype."), + (za = function () { + throw new o("KaTeX doesn't work in quirks mode."); + })); + var Aa = function (t, e, r) { + if (r.throwOnError || !(t instanceof o)) throw t; + var a = Dt.makeSpan(['katex-error'], [new E(e)]); + return a.setAttribute('title', t.toString()), a.setAttribute('style', 'color:' + r.errorColor), a; + }, + Ta = function (t, e) { + var r = new u(e); + try { + var a = Ma(t, r); + return ke(a, t, r); + } catch (e) { + return Aa(e, t, r); + } + }, + Ba = { + version: '0.12.0', + render: za, + renderToString: function (t, e) { + return Ta(t, e).toMarkup(); + }, + ParseError: o, + __parse: function (t, e) { + var r = new u(e); + return Ma(t, r); + }, + __renderToDomTree: Ta, + __renderToHTMLTree: function (t, e) { + var r = new u(e); + try { + return (function (t, e, r) { + var a = le(t, ye(r)), + n = Dt.makeSpan(['katex'], [a]); + return we(n, r); + })(Ma(t, r), 0, r); + } catch (e) { + return Aa(e, t, r); + } + }, + __setFontMetrics: function (t, e) { + F[t] = e; + }, + __defineSymbol: $, + __defineMacro: pa, + __domTree: { Span: N, Anchor: I, SymbolNode: E, SvgNode: L, PathNode: P, LineNode: D }, + }; + e.default = Ba; + }, + ]).default; +}); diff --git a/src/main/webapp/content/js/duplicate/prism.js b/src/main/webapp/content/js/duplicate/prism.js index 03688507c118f4c31d01c5edfe85294bf204317c..8de79d7b51af4e79405b0b570b0f7c1a8ea147eb 100644 --- a/src/main/webapp/content/js/duplicate/prism.js +++ b/src/main/webapp/content/js/duplicate/prism.js @@ -1,17 +1,15 @@ - /* ********************************************** Begin prism-core.js ********************************************** */ /// <reference lib="WebWorker"/> -var _self = (typeof window !== 'undefined') - ? window // if in browser - : ( - (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) - ? self // if in worker - : {} // if in node js - ); +var _self = + typeof window !== 'undefined' + ? window // if in browser + : typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope + ? self // if in worker + : {}; // if in node js /** * Prism: Lightweight, robust, elegant syntax highlighting @@ -21,1133 +19,1130 @@ var _self = (typeof window !== 'undefined') * @namespace * @public */ -var Prism = (function (_self){ - -// Private helper vars -var lang = /\blang(?:uage)?-([\w-]+)\b/i; -var uniqueId = 0; - - -var _ = { - /** - * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the - * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load - * additional languages or plugins yourself. - * - * By setting this value to `true`, Prism will not automatically highlight all code elements on the page. - * - * You obviously have to change this value before the automatic highlighting started. To do this, you can add an - * empty Prism object into the global scope before loading the Prism script like this: - * - * ```js - * window.Prism = window.Prism || {}; - * Prism.manual = true; - * // add a new <script> to load Prism's script - * ``` - * - * @default false - * @type {boolean} - * @memberof Prism - * @public - */ - manual: _self.Prism && _self.Prism.manual, - disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler, - - /** - * A namespace for utility methods. - * - * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may - * change or disappear at any time. - * - * @namespace - * @memberof Prism - */ - util: { - encode: function encode(tokens) { - if (tokens instanceof Token) { - return new Token(tokens.type, encode(tokens.content), tokens.alias); - } else if (Array.isArray(tokens)) { - return tokens.map(encode); - } else { - return tokens.replace(/&/g, '&').replace(/</g, '<').replace(/\u00a0/g, ' '); - } - }, - - /** - * Returns the name of the type of the given value. - * - * @param {any} o - * @returns {string} - * @example - * type(null) === 'Null' - * type(undefined) === 'Undefined' - * type(123) === 'Number' - * type('foo') === 'String' - * type(true) === 'Boolean' - * type([1, 2]) === 'Array' - * type({}) === 'Object' - * type(String) === 'Function' - * type(/abc+/) === 'RegExp' - */ - type: function (o) { - return Object.prototype.toString.call(o).slice(8, -1); - }, - - /** - * Returns a unique number for the given object. Later calls will still return the same number. - * - * @param {Object} obj - * @returns {number} - */ - objId: function (obj) { - if (!obj['__id']) { - Object.defineProperty(obj, '__id', { value: ++uniqueId }); - } - return obj['__id']; - }, - - /** - * Creates a deep clone of the given object. - * - * The main intended use of this function is to clone language definitions. - * - * @param {T} o - * @param {Record<number, any>} [visited] - * @returns {T} - * @template T - */ - clone: function deepClone(o, visited) { - visited = visited || {}; - - var clone, id; - switch (_.util.type(o)) { - case 'Object': - id = _.util.objId(o); - if (visited[id]) { - return visited[id]; - } - clone = /** @type {Record<string, any>} */ ({}); - visited[id] = clone; - - for (var key in o) { - if (o.hasOwnProperty(key)) { - clone[key] = deepClone(o[key], visited); - } - } - - return /** @type {any} */ (clone); - - case 'Array': - id = _.util.objId(o); - if (visited[id]) { - return visited[id]; - } - clone = []; - visited[id] = clone; - - (/** @type {Array} */(/** @type {any} */(o))).forEach(function (v, i) { - clone[i] = deepClone(v, visited); - }); - - return /** @type {any} */ (clone); - - default: - return o; - } - }, - - /** - * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class. - * - * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned. - * - * @param {Element} element - * @returns {string} - */ - getLanguage: function (element) { - while (element && !lang.test(element.className)) { - element = element.parentElement; - } - if (element) { - return (element.className.match(lang) || [, 'none'])[1].toLowerCase(); - } - return 'none'; - }, - - /** - * Returns the script element that is currently executing. - * - * This does __not__ work for line script element. - * - * @returns {HTMLScriptElement | null} - */ - currentScript: function () { - if (typeof document === 'undefined') { - return null; - } - if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) { - return /** @type {any} */ (document.currentScript); - } - - // IE11 workaround - // we'll get the src of the current script by parsing IE11's error stack trace - // this will not work for inline scripts - - try { - throw new Error(); - } catch (err) { - // Get file src url from stack. Specifically works with the format of stack traces in IE. - // A stack will look like this: - // - // Error - // at _.util.currentScript (http://localhost/components/prism-core.js:119:5) - // at Global code (http://localhost/components/prism-core.js:606:1) - - var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1]; - if (src) { - var scripts = document.getElementsByTagName('script'); - for (var i in scripts) { - if (scripts[i].src == src) { - return scripts[i]; - } - } - } - return null; - } - }, - - /** - * Returns whether a given class is active for `element`. - * - * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated - * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the - * given class is just the given class with a `no-` prefix. - * - * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is - * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its - * ancestors have the given class or the negated version of it, then the default activation will be returned. - * - * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated - * version of it, the class is considered active. - * - * @param {Element} element - * @param {string} className - * @param {boolean} [defaultActivation=false] - * @returns {boolean} - */ - isActive: function (element, className, defaultActivation) { - var no = 'no-' + className; - - while (element) { - var classList = element.classList; - if (classList.contains(className)) { - return true; - } - if (classList.contains(no)) { - return false; - } - element = element.parentElement; - } - return !!defaultActivation; - } - }, - - /** - * This namespace contains all currently loaded languages and the some helper functions to create and modify languages. - * - * @namespace - * @memberof Prism - * @public - */ - languages: { - /** - * Creates a deep copy of the language with the given id and appends the given tokens. - * - * If a token in `redef` also appears in the copied language, then the existing token in the copied language - * will be overwritten at its original position. - * - * ## Best practices - * - * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language) - * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to - * understand the language definition because, normally, the order of tokens matters in Prism grammars. - * - * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens. - * Furthermore, all non-overwriting tokens should be placed after the overwriting ones. - * - * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`. - * @param {Grammar} redef The new tokens to append. - * @returns {Grammar} The new language created. - * @public - * @example - * Prism.languages['css-with-colors'] = Prism.languages.extend('css', { - * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token - * // at its original position - * 'comment': { ... }, - * // CSS doesn't have a 'color' token, so this token will be appended - * 'color': /\b(?:red|green|blue)\b/ - * }); - */ - extend: function (id, redef) { - var lang = _.util.clone(_.languages[id]); - - for (var key in redef) { - lang[key] = redef[key]; - } - - return lang; - }, - - /** - * Inserts tokens _before_ another token in a language definition or any other grammar. - * - * ## Usage - * - * This helper method makes it easy to modify existing languages. For example, the CSS language definition - * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded - * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the - * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do - * this: - * - * ```js - * Prism.languages.markup.style = { - * // token - * }; - * ``` - * - * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens - * before existing tokens. For the CSS example above, you would use it like this: - * - * ```js - * Prism.languages.insertBefore('markup', 'cdata', { - * 'style': { - * // token - * } - * }); - * ``` - * - * ## Special cases - * - * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar - * will be ignored. - * - * This behavior can be used to insert tokens after `before`: - * - * ```js - * Prism.languages.insertBefore('markup', 'comment', { - * 'comment': Prism.languages.markup.comment, - * // tokens after 'comment' - * }); - * ``` - * - * ## Limitations - * - * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object - * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave - * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily - * deleting properties which is necessary to insert at arbitrary positions. - * - * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object. - * Instead, it will create a new object and replace all references to the target object with the new one. This - * can be done without temporarily deleting properties, so the iteration order is well-defined. - * - * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if - * you hold the target object in a variable, then the value of the variable will not change. - * - * ```js - * var oldMarkup = Prism.languages.markup; - * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... }); - * - * assert(oldMarkup !== Prism.languages.markup); - * assert(newMarkup === Prism.languages.markup); - * ``` - * - * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the - * object to be modified. - * @param {string} before The key to insert before. - * @param {Grammar} insert An object containing the key-value pairs to be inserted. - * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the - * object to be modified. - * - * Defaults to `Prism.languages`. - * @returns {Grammar} The new grammar object. - * @public - */ - insertBefore: function (inside, before, insert, root) { - root = root || /** @type {any} */ (_.languages); - var grammar = root[inside]; - /** @type {Grammar} */ - var ret = {}; - - for (var token in grammar) { - if (grammar.hasOwnProperty(token)) { - - if (token == before) { - for (var newToken in insert) { - if (insert.hasOwnProperty(newToken)) { - ret[newToken] = insert[newToken]; - } - } - } - - // Do not insert token which also occur in insert. See #1525 - if (!insert.hasOwnProperty(token)) { - ret[token] = grammar[token]; - } - } - } - - var old = root[inside]; - root[inside] = ret; - - // Update references in other language definitions - _.languages.DFS(_.languages, function(key, value) { - if (value === old && key != inside) { - this[key] = ret; - } - }); - - return ret; - }, - - // Traverse a language definition with Depth First Search - DFS: function DFS(o, callback, type, visited) { - visited = visited || {}; - - var objId = _.util.objId; - - for (var i in o) { - if (o.hasOwnProperty(i)) { - callback.call(o, i, o[i], type || i); - - var property = o[i], - propertyType = _.util.type(property); - - if (propertyType === 'Object' && !visited[objId(property)]) { - visited[objId(property)] = true; - DFS(property, callback, null, visited); - } - else if (propertyType === 'Array' && !visited[objId(property)]) { - visited[objId(property)] = true; - DFS(property, callback, i, visited); - } - } - } - } - }, - - plugins: {}, - - /** - * This is the most high-level function in Prism’s API. - * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on - * each one of them. - * - * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`. - * - * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}. - * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}. - * @memberof Prism - * @public - */ - highlightAll: function(async, callback) { - _.highlightAllUnder(document, async, callback); - }, - - /** - * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls - * {@link Prism.highlightElement} on each one of them. - * - * The following hooks will be run: - * 1. `before-highlightall` - * 2. `before-all-elements-highlight` - * 3. All hooks of {@link Prism.highlightElement} for each element. - * - * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted. - * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers. - * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done. - * @memberof Prism - * @public - */ - highlightAllUnder: function(container, async, callback) { - var env = { - callback: callback, - container: container, - selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code' - }; - - _.hooks.run('before-highlightall', env); - - env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector)); - - _.hooks.run('before-all-elements-highlight', env); - - for (var i = 0, element; element = env.elements[i++];) { - _.highlightElement(element, async === true, env.callback); - } - }, - - /** - * Highlights the code inside a single element. - * - * The following hooks will be run: - * 1. `before-sanity-check` - * 2. `before-highlight` - * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`. - * 4. `before-insert` - * 5. `after-highlight` - * 6. `complete` - * - * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for - * the element's language. - * - * @param {Element} element The element containing the code. - * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier. - * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers - * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is - * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default). - * - * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for - * asynchronous highlighting to work. You can build your own bundle on the - * [Download page](https://prismjs.com/download.html). - * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done. - * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously. - * @memberof Prism - * @public - */ - highlightElement: function(element, async, callback) { - // Find language - var language = _.util.getLanguage(element); - var grammar = _.languages[language]; - - // Set language on the element, if not present - element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; - - // Set language on the parent, for styling - var parent = element.parentElement; - if (parent && parent.nodeName.toLowerCase() === 'pre') { - parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; - } - - var code = element.textContent; - - var env = { - element: element, - language: language, - grammar: grammar, - code: code - }; - - function insertHighlightedCode(highlightedCode) { - env.highlightedCode = highlightedCode; - - _.hooks.run('before-insert', env); - - env.element.innerHTML = env.highlightedCode; - - _.hooks.run('after-highlight', env); - _.hooks.run('complete', env); - callback && callback.call(env.element); - } - - _.hooks.run('before-sanity-check', env); - - if (!env.code) { - _.hooks.run('complete', env); - callback && callback.call(env.element); - return; - } - - _.hooks.run('before-highlight', env); - - if (!env.grammar) { - insertHighlightedCode(_.util.encode(env.code)); - return; - } - - if (async && _self.Worker) { - var worker = new Worker(_.filename); - - worker.onmessage = function(evt) { - insertHighlightedCode(evt.data); - }; - - worker.postMessage(JSON.stringify({ - language: env.language, - code: env.code, - immediateClose: true - })); - } - else { - insertHighlightedCode(_.highlight(env.code, env.grammar, env.language)); - } - }, - - /** - * Low-level function, only use if you know what you’re doing. It accepts a string of text as input - * and the language definitions to use, and returns a string with the HTML produced. - * - * The following hooks will be run: - * 1. `before-tokenize` - * 2. `after-tokenize` - * 3. `wrap`: On each {@link Token}. - * - * @param {string} text A string with the code to be highlighted. - * @param {Grammar} grammar An object containing the tokens to use. - * - * Usually a language definition like `Prism.languages.markup`. - * @param {string} language The name of the language definition passed to `grammar`. - * @returns {string} The highlighted HTML. - * @memberof Prism - * @public - * @example - * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript'); - */ - highlight: function (text, grammar, language) { - var env = { - code: text, - grammar: grammar, - language: language - }; - _.hooks.run('before-tokenize', env); - env.tokens = _.tokenize(env.code, env.grammar); - _.hooks.run('after-tokenize', env); - return Token.stringify(_.util.encode(env.tokens), env.language); - }, - - /** - * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input - * and the language definitions to use, and returns an array with the tokenized code. - * - * When the language definition includes nested tokens, the function is called recursively on each of these tokens. - * - * This method could be useful in other contexts as well, as a very crude parser. - * - * @param {string} text A string with the code to be highlighted. - * @param {Grammar} grammar An object containing the tokens to use. - * - * Usually a language definition like `Prism.languages.markup`. - * @returns {TokenStream} An array of strings and tokens, a token stream. - * @memberof Prism - * @public - * @example - * let code = `var foo = 0;`; - * let tokens = Prism.tokenize(code, Prism.languages.javascript); - * tokens.forEach(token => { - * if (token instanceof Prism.Token && token.type === 'number') { - * console.log(`Found numeric literal: ${token.content}`); - * } - * }); - */ - tokenize: function(text, grammar) { - var rest = grammar.rest; - if (rest) { - for (var token in rest) { - grammar[token] = rest[token]; - } - - delete grammar.rest; - } - - var tokenList = new LinkedList(); - addAfter(tokenList, tokenList.head, text); - - matchGrammar(text, tokenList, grammar, tokenList.head, 0); - - return toArray(tokenList); - }, - - /** - * @namespace - * @memberof Prism - * @public - */ - hooks: { - all: {}, - - /** - * Adds the given callback to the list of callbacks for the given hook. - * - * The callback will be invoked when the hook it is registered for is run. - * Hooks are usually directly run by a highlight function but you can also run hooks yourself. - * - * One callback function can be registered to multiple hooks and the same hook multiple times. - * - * @param {string} name The name of the hook. - * @param {HookCallback} callback The callback function which is given environment variables. - * @public - */ - add: function (name, callback) { - var hooks = _.hooks.all; - - hooks[name] = hooks[name] || []; - - hooks[name].push(callback); - }, - - /** - * Runs a hook invoking all registered callbacks with the given environment variables. - * - * Callbacks will be invoked synchronously and in the order in which they were registered. - * - * @param {string} name The name of the hook. - * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered. - * @public - */ - run: function (name, env) { - var callbacks = _.hooks.all[name]; - - if (!callbacks || !callbacks.length) { - return; - } - - for (var i=0, callback; callback = callbacks[i++];) { - callback(env); - } - } - }, - - Token: Token -}; -_self.Prism = _; - - -// Typescript note: -// The following can be used to import the Token type in JSDoc: -// -// @typedef {InstanceType<import("./prism-core")["Token"]>} Token - -/** - * Creates a new token. - * - * @param {string} type See {@link Token#type type} - * @param {string | TokenStream} content See {@link Token#content content} - * @param {string|string[]} [alias] The alias(es) of the token. - * @param {string} [matchedStr=""] A copy of the full string this token was created from. - * @class - * @global - * @public - */ -function Token(type, content, alias, matchedStr) { - /** - * The type of the token. - * - * This is usually the key of a pattern in a {@link Grammar}. - * - * @type {string} - * @see GrammarToken - * @public - */ - this.type = type; - /** - * The strings or tokens contained by this token. - * - * This will be a token stream if the pattern matched also defined an `inside` grammar. - * - * @type {string | TokenStream} - * @public - */ - this.content = content; - /** - * The alias(es) of the token. - * - * @type {string|string[]} - * @see GrammarToken - * @public - */ - this.alias = alias; - // Copy of the full string this token was created from - this.length = (matchedStr || '').length | 0; -} - -/** - * A token stream is an array of strings and {@link Token Token} objects. - * - * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process - * them. - * - * 1. No adjacent strings. - * 2. No empty strings. - * - * The only exception here is the token stream that only contains the empty string and nothing else. - * - * @typedef {Array<string | Token>} TokenStream - * @global - * @public - */ - -/** - * Converts the given token or token stream to an HTML representation. - * - * The following hooks will be run: - * 1. `wrap`: On each {@link Token}. - * - * @param {string | Token | TokenStream} o The token or token stream to be converted. - * @param {string} language The name of current language. - * @returns {string} The HTML representation of the token or token stream. - * @memberof Token - * @static - */ -Token.stringify = function stringify(o, language) { - if (typeof o == 'string') { - return o; - } - if (Array.isArray(o)) { - var s = ''; - o.forEach(function (e) { - s += stringify(e, language); - }); - return s; - } - - var env = { - type: o.type, - content: stringify(o.content, language), - tag: 'span', - classes: ['token', o.type], - attributes: {}, - language: language - }; - - var aliases = o.alias; - if (aliases) { - if (Array.isArray(aliases)) { - Array.prototype.push.apply(env.classes, aliases); - } else { - env.classes.push(aliases); - } - } - - _.hooks.run('wrap', env); - - var attributes = ''; - for (var name in env.attributes) { - attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; - } - - return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>'; -}; - -/** - * @param {RegExp} pattern - * @param {number} pos - * @param {string} text - * @param {boolean} lookbehind - * @returns {RegExpExecArray | null} - */ -function matchPattern(pattern, pos, text, lookbehind) { - pattern.lastIndex = pos; - var match = pattern.exec(text); - if (match && lookbehind && match[1]) { - // change the match to remove the text matched by the Prism lookbehind group - var lookbehindLength = match[1].length; - match.index += lookbehindLength; - match[0] = match[0].slice(lookbehindLength); - } - return match; -} - -/** - * @param {string} text - * @param {LinkedList<string | Token>} tokenList - * @param {any} grammar - * @param {LinkedListNode<string | Token>} startNode - * @param {number} startPos - * @param {RematchOptions} [rematch] - * @returns {void} - * @private - * - * @typedef RematchOptions - * @property {string} cause - * @property {number} reach - */ -function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) { - for (var token in grammar) { - if (!grammar.hasOwnProperty(token) || !grammar[token]) { - continue; - } - - var patterns = grammar[token]; - patterns = Array.isArray(patterns) ? patterns : [patterns]; - - for (var j = 0; j < patterns.length; ++j) { - if (rematch && rematch.cause == token + ',' + j) { - return; - } - - var patternObj = patterns[j], - inside = patternObj.inside, - lookbehind = !!patternObj.lookbehind, - greedy = !!patternObj.greedy, - alias = patternObj.alias; - - if (greedy && !patternObj.pattern.global) { - // Without the global flag, lastIndex won't work - var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0]; - patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g'); - } - - /** @type {RegExp} */ - var pattern = patternObj.pattern || patternObj; - - for ( // iterate the token list and keep track of the current token/string position - var currentNode = startNode.next, pos = startPos; - currentNode !== tokenList.tail; - pos += currentNode.value.length, currentNode = currentNode.next - ) { - - if (rematch && pos >= rematch.reach) { - break; - } - - var str = currentNode.value; - - if (tokenList.length > text.length) { - // Something went terribly wrong, ABORT, ABORT! - return; - } - - if (str instanceof Token) { - continue; - } - - var removeCount = 1; // this is the to parameter of removeBetween - var match; - - if (greedy) { - match = matchPattern(pattern, pos, text, lookbehind); - if (!match) { - break; - } - - var from = match.index; - var to = match.index + match[0].length; - var p = pos; - - // find the node that contains the match - p += currentNode.value.length; - while (from >= p) { - currentNode = currentNode.next; - p += currentNode.value.length; - } - // adjust pos (and p) - p -= currentNode.value.length; - pos = p; - - // the current node is a Token, then the match starts inside another Token, which is invalid - if (currentNode.value instanceof Token) { - continue; - } - - // find the last node which is affected by this match - for ( - var k = currentNode; - k !== tokenList.tail && (p < to || typeof k.value === 'string'); - k = k.next - ) { - removeCount++; - p += k.value.length; - } - removeCount--; - - // replace with the new match - str = text.slice(pos, p); - match.index -= pos; - } else { - match = matchPattern(pattern, 0, str, lookbehind); - if (!match) { - continue; - } - } - - var from = match.index, - matchStr = match[0], - before = str.slice(0, from), - after = str.slice(from + matchStr.length); - - var reach = pos + str.length; - if (rematch && reach > rematch.reach) { - rematch.reach = reach; - } - - var removeFrom = currentNode.prev; - - if (before) { - removeFrom = addAfter(tokenList, removeFrom, before); - pos += before.length; - } - - removeRange(tokenList, removeFrom, removeCount); - - var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr); - currentNode = addAfter(tokenList, removeFrom, wrapped); - - if (after) { - addAfter(tokenList, currentNode, after); - } - - if (removeCount > 1) { - // at least one Token object was removed, so we have to do some rematching - // this can only happen if the current pattern is greedy - matchGrammar(text, tokenList, grammar, currentNode.prev, pos, { - cause: token + ',' + j, - reach: reach - }); - } - } - } - } -} - -/** - * @typedef LinkedListNode - * @property {T} value - * @property {LinkedListNode<T> | null} prev The previous node. - * @property {LinkedListNode<T> | null} next The next node. - * @template T - * @private - */ - -/** - * @template T - * @private - */ -function LinkedList() { - /** @type {LinkedListNode<T>} */ - var head = { value: null, prev: null, next: null }; - /** @type {LinkedListNode<T>} */ - var tail = { value: null, prev: head, next: null }; - head.next = tail; - - /** @type {LinkedListNode<T>} */ - this.head = head; - /** @type {LinkedListNode<T>} */ - this.tail = tail; - this.length = 0; -} - -/** - * Adds a new node with the given value to the list. - * @param {LinkedList<T>} list - * @param {LinkedListNode<T>} node - * @param {T} value - * @returns {LinkedListNode<T>} The added node. - * @template T - */ -function addAfter(list, node, value) { - // assumes that node != list.tail && values.length >= 0 - var next = node.next; - - var newNode = { value: value, prev: node, next: next }; - node.next = newNode; - next.prev = newNode; - list.length++; - - return newNode; -} -/** - * Removes `count` nodes after the given node. The given node will not be removed. - * @param {LinkedList<T>} list - * @param {LinkedListNode<T>} node - * @param {number} count - * @template T - */ -function removeRange(list, node, count) { - var next = node.next; - for (var i = 0; i < count && next !== list.tail; i++) { - next = next.next; - } - node.next = next; - next.prev = node; - list.length -= i; -} -/** - * @param {LinkedList<T>} list - * @returns {T[]} - * @template T - */ -function toArray(list) { - var array = []; - var node = list.head.next; - while (node !== list.tail) { - array.push(node.value); - node = node.next; - } - return array; -} - - -if (!_self.document) { - if (!_self.addEventListener) { - // in Node.js - return _; - } - - if (!_.disableWorkerMessageHandler) { - // In worker - _self.addEventListener('message', function (evt) { - var message = JSON.parse(evt.data), - lang = message.language, - code = message.code, - immediateClose = message.immediateClose; - - _self.postMessage(_.highlight(code, _.languages[lang], lang)); - if (immediateClose) { - _self.close(); - } - }, false); - } - - return _; -} - -// Get current script and highlight -var script = _.util.currentScript(); - -if (script) { - _.filename = script.src; - - if (script.hasAttribute('data-manual')) { - _.manual = true; - } -} - -function highlightAutomaticallyCallback() { - if (!_.manual) { - _.highlightAll(); - } -} - -if (!_.manual) { - // If the document state is "loading", then we'll use DOMContentLoaded. - // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the - // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they - // might take longer one animation frame to execute which can create a race condition where only some plugins have - // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded. - // See https://github.com/PrismJS/prism/issues/2102 - var readyState = document.readyState; - if (readyState === 'loading' || readyState === 'interactive' && script && script.defer) { - document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); - } else { - if (window.requestAnimationFrame) { - window.requestAnimationFrame(highlightAutomaticallyCallback); - } else { - window.setTimeout(highlightAutomaticallyCallback, 16); - } - } -} - -return _; - +var Prism = (function (_self) { + // Private helper vars + var lang = /\blang(?:uage)?-([\w-]+)\b/i; + var uniqueId = 0; + + var _ = { + /** + * By default, Prism will attempt to highlight all code elements (by calling {@link Prism.highlightAll}) on the + * current page after the page finished loading. This might be a problem if e.g. you wanted to asynchronously load + * additional languages or plugins yourself. + * + * By setting this value to `true`, Prism will not automatically highlight all code elements on the page. + * + * You obviously have to change this value before the automatic highlighting started. To do this, you can add an + * empty Prism object into the global scope before loading the Prism script like this: + * + * ```js + * window.Prism = window.Prism || {}; + * Prism.manual = true; + * // add a new <script> to load Prism's script + * ``` + * + * @default false + * @type {boolean} + * @memberof Prism + * @public + */ + manual: _self.Prism && _self.Prism.manual, + disableWorkerMessageHandler: _self.Prism && _self.Prism.disableWorkerMessageHandler, + + /** + * A namespace for utility methods. + * + * All function in this namespace that are not explicitly marked as _public_ are for __internal use only__ and may + * change or disappear at any time. + * + * @namespace + * @memberof Prism + */ + util: { + encode: function encode(tokens) { + if (tokens instanceof Token) { + return new Token(tokens.type, encode(tokens.content), tokens.alias); + } else if (Array.isArray(tokens)) { + return tokens.map(encode); + } else { + return tokens + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/\u00a0/g, ' '); + } + }, + + /** + * Returns the name of the type of the given value. + * + * @param {any} o + * @returns {string} + * @example + * type(null) === 'Null' + * type(undefined) === 'Undefined' + * type(123) === 'Number' + * type('foo') === 'String' + * type(true) === 'Boolean' + * type([1, 2]) === 'Array' + * type({}) === 'Object' + * type(String) === 'Function' + * type(/abc+/) === 'RegExp' + */ + type: function (o) { + return Object.prototype.toString.call(o).slice(8, -1); + }, + + /** + * Returns a unique number for the given object. Later calls will still return the same number. + * + * @param {Object} obj + * @returns {number} + */ + objId: function (obj) { + if (!obj['__id']) { + Object.defineProperty(obj, '__id', { value: ++uniqueId }); + } + return obj['__id']; + }, + + /** + * Creates a deep clone of the given object. + * + * The main intended use of this function is to clone language definitions. + * + * @param {T} o + * @param {Record<number, any>} [visited] + * @returns {T} + * @template T + */ + clone: function deepClone(o, visited) { + visited = visited || {}; + + var clone, id; + switch (_.util.type(o)) { + case 'Object': + id = _.util.objId(o); + if (visited[id]) { + return visited[id]; + } + clone = /** @type {Record<string, any>} */ ({}); + visited[id] = clone; + + for (var key in o) { + if (o.hasOwnProperty(key)) { + clone[key] = deepClone(o[key], visited); + } + } + + return /** @type {any} */ (clone); + + case 'Array': + id = _.util.objId(o); + if (visited[id]) { + return visited[id]; + } + clone = []; + visited[id] = clone; + + /** @type {Array} */ (/** @type {any} */ (o)).forEach(function (v, i) { + clone[i] = deepClone(v, visited); + }); + + return /** @type {any} */ (clone); + + default: + return o; + } + }, + + /** + * Returns the Prism language of the given element set by a `language-xxxx` or `lang-xxxx` class. + * + * If no language is set for the element or the element is `null` or `undefined`, `none` will be returned. + * + * @param {Element} element + * @returns {string} + */ + getLanguage: function (element) { + while (element && !lang.test(element.className)) { + element = element.parentElement; + } + if (element) { + return (element.className.match(lang) || [, 'none'])[1].toLowerCase(); + } + return 'none'; + }, + + /** + * Returns the script element that is currently executing. + * + * This does __not__ work for line script element. + * + * @returns {HTMLScriptElement | null} + */ + currentScript: function () { + if (typeof document === 'undefined') { + return null; + } + if ('currentScript' in document && 1 < 2 /* hack to trip TS' flow analysis */) { + return /** @type {any} */ (document.currentScript); + } + + // IE11 workaround + // we'll get the src of the current script by parsing IE11's error stack trace + // this will not work for inline scripts + + try { + throw new Error(); + } catch (err) { + // Get file src url from stack. Specifically works with the format of stack traces in IE. + // A stack will look like this: + // + // Error + // at _.util.currentScript (http://localhost/components/prism-core.js:119:5) + // at Global code (http://localhost/components/prism-core.js:606:1) + + var src = (/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(err.stack) || [])[1]; + if (src) { + var scripts = document.getElementsByTagName('script'); + for (var i in scripts) { + if (scripts[i].src == src) { + return scripts[i]; + } + } + } + return null; + } + }, + + /** + * Returns whether a given class is active for `element`. + * + * The class can be activated if `element` or one of its ancestors has the given class and it can be deactivated + * if `element` or one of its ancestors has the negated version of the given class. The _negated version_ of the + * given class is just the given class with a `no-` prefix. + * + * Whether the class is active is determined by the closest ancestor of `element` (where `element` itself is + * closest ancestor) that has the given class or the negated version of it. If neither `element` nor any of its + * ancestors have the given class or the negated version of it, then the default activation will be returned. + * + * In the paradoxical situation where the closest ancestor contains __both__ the given class and the negated + * version of it, the class is considered active. + * + * @param {Element} element + * @param {string} className + * @param {boolean} [defaultActivation=false] + * @returns {boolean} + */ + isActive: function (element, className, defaultActivation) { + var no = 'no-' + className; + + while (element) { + var classList = element.classList; + if (classList.contains(className)) { + return true; + } + if (classList.contains(no)) { + return false; + } + element = element.parentElement; + } + return !!defaultActivation; + }, + }, + + /** + * This namespace contains all currently loaded languages and the some helper functions to create and modify languages. + * + * @namespace + * @memberof Prism + * @public + */ + languages: { + /** + * Creates a deep copy of the language with the given id and appends the given tokens. + * + * If a token in `redef` also appears in the copied language, then the existing token in the copied language + * will be overwritten at its original position. + * + * ## Best practices + * + * Since the position of overwriting tokens (token in `redef` that overwrite tokens in the copied language) + * doesn't matter, they can technically be in any order. However, this can be confusing to others that trying to + * understand the language definition because, normally, the order of tokens matters in Prism grammars. + * + * Therefore, it is encouraged to order overwriting tokens according to the positions of the overwritten tokens. + * Furthermore, all non-overwriting tokens should be placed after the overwriting ones. + * + * @param {string} id The id of the language to extend. This has to be a key in `Prism.languages`. + * @param {Grammar} redef The new tokens to append. + * @returns {Grammar} The new language created. + * @public + * @example + * Prism.languages['css-with-colors'] = Prism.languages.extend('css', { + * // Prism.languages.css already has a 'comment' token, so this token will overwrite CSS' 'comment' token + * // at its original position + * 'comment': { ... }, + * // CSS doesn't have a 'color' token, so this token will be appended + * 'color': /\b(?:red|green|blue)\b/ + * }); + */ + extend: function (id, redef) { + var lang = _.util.clone(_.languages[id]); + + for (var key in redef) { + lang[key] = redef[key]; + } + + return lang; + }, + + /** + * Inserts tokens _before_ another token in a language definition or any other grammar. + * + * ## Usage + * + * This helper method makes it easy to modify existing languages. For example, the CSS language definition + * not only defines CSS highlighting for CSS documents, but also needs to define highlighting for CSS embedded + * in HTML through `<style>` elements. To do this, it needs to modify `Prism.languages.markup` and add the + * appropriate tokens. However, `Prism.languages.markup` is a regular JavaScript object literal, so if you do + * this: + * + * ```js + * Prism.languages.markup.style = { + * // token + * }; + * ``` + * + * then the `style` token will be added (and processed) at the end. `insertBefore` allows you to insert tokens + * before existing tokens. For the CSS example above, you would use it like this: + * + * ```js + * Prism.languages.insertBefore('markup', 'cdata', { + * 'style': { + * // token + * } + * }); + * ``` + * + * ## Special cases + * + * If the grammars of `inside` and `insert` have tokens with the same name, the tokens in `inside`'s grammar + * will be ignored. + * + * This behavior can be used to insert tokens after `before`: + * + * ```js + * Prism.languages.insertBefore('markup', 'comment', { + * 'comment': Prism.languages.markup.comment, + * // tokens after 'comment' + * }); + * ``` + * + * ## Limitations + * + * The main problem `insertBefore` has to solve is iteration order. Since ES2015, the iteration order for object + * properties is guaranteed to be the insertion order (except for integer keys) but some browsers behave + * differently when keys are deleted and re-inserted. So `insertBefore` can't be implemented by temporarily + * deleting properties which is necessary to insert at arbitrary positions. + * + * To solve this problem, `insertBefore` doesn't actually insert the given tokens into the target object. + * Instead, it will create a new object and replace all references to the target object with the new one. This + * can be done without temporarily deleting properties, so the iteration order is well-defined. + * + * However, only references that can be reached from `Prism.languages` or `insert` will be replaced. I.e. if + * you hold the target object in a variable, then the value of the variable will not change. + * + * ```js + * var oldMarkup = Prism.languages.markup; + * var newMarkup = Prism.languages.insertBefore('markup', 'comment', { ... }); + * + * assert(oldMarkup !== Prism.languages.markup); + * assert(newMarkup === Prism.languages.markup); + * ``` + * + * @param {string} inside The property of `root` (e.g. a language id in `Prism.languages`) that contains the + * object to be modified. + * @param {string} before The key to insert before. + * @param {Grammar} insert An object containing the key-value pairs to be inserted. + * @param {Object<string, any>} [root] The object containing `inside`, i.e. the object that contains the + * object to be modified. + * + * Defaults to `Prism.languages`. + * @returns {Grammar} The new grammar object. + * @public + */ + insertBefore: function (inside, before, insert, root) { + root = root || /** @type {any} */ (_.languages); + var grammar = root[inside]; + /** @type {Grammar} */ + var ret = {}; + + for (var token in grammar) { + if (grammar.hasOwnProperty(token)) { + if (token == before) { + for (var newToken in insert) { + if (insert.hasOwnProperty(newToken)) { + ret[newToken] = insert[newToken]; + } + } + } + + // Do not insert token which also occur in insert. See #1525 + if (!insert.hasOwnProperty(token)) { + ret[token] = grammar[token]; + } + } + } + + var old = root[inside]; + root[inside] = ret; + + // Update references in other language definitions + _.languages.DFS(_.languages, function (key, value) { + if (value === old && key != inside) { + this[key] = ret; + } + }); + + return ret; + }, + + // Traverse a language definition with Depth First Search + DFS: function DFS(o, callback, type, visited) { + visited = visited || {}; + + var objId = _.util.objId; + + for (var i in o) { + if (o.hasOwnProperty(i)) { + callback.call(o, i, o[i], type || i); + + var property = o[i], + propertyType = _.util.type(property); + + if (propertyType === 'Object' && !visited[objId(property)]) { + visited[objId(property)] = true; + DFS(property, callback, null, visited); + } else if (propertyType === 'Array' && !visited[objId(property)]) { + visited[objId(property)] = true; + DFS(property, callback, i, visited); + } + } + } + }, + }, + + plugins: {}, + + /** + * This is the most high-level function in Prism’s API. + * It fetches all the elements that have a `.language-xxxx` class and then calls {@link Prism.highlightElement} on + * each one of them. + * + * This is equivalent to `Prism.highlightAllUnder(document, async, callback)`. + * + * @param {boolean} [async=false] Same as in {@link Prism.highlightAllUnder}. + * @param {HighlightCallback} [callback] Same as in {@link Prism.highlightAllUnder}. + * @memberof Prism + * @public + */ + highlightAll: function (async, callback) { + _.highlightAllUnder(document, async, callback); + }, + + /** + * Fetches all the descendants of `container` that have a `.language-xxxx` class and then calls + * {@link Prism.highlightElement} on each one of them. + * + * The following hooks will be run: + * 1. `before-highlightall` + * 2. `before-all-elements-highlight` + * 3. All hooks of {@link Prism.highlightElement} for each element. + * + * @param {ParentNode} container The root element, whose descendants that have a `.language-xxxx` class will be highlighted. + * @param {boolean} [async=false] Whether each element is to be highlighted asynchronously using Web Workers. + * @param {HighlightCallback} [callback] An optional callback to be invoked on each element after its highlighting is done. + * @memberof Prism + * @public + */ + highlightAllUnder: function (container, async, callback) { + var env = { + callback: callback, + container: container, + selector: 'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code', + }; + + _.hooks.run('before-highlightall', env); + + env.elements = Array.prototype.slice.apply(env.container.querySelectorAll(env.selector)); + + _.hooks.run('before-all-elements-highlight', env); + + for (var i = 0, element; (element = env.elements[i++]); ) { + _.highlightElement(element, async === true, env.callback); + } + }, + + /** + * Highlights the code inside a single element. + * + * The following hooks will be run: + * 1. `before-sanity-check` + * 2. `before-highlight` + * 3. All hooks of {@link Prism.highlight}. These hooks will be run by an asynchronous worker if `async` is `true`. + * 4. `before-insert` + * 5. `after-highlight` + * 6. `complete` + * + * Some the above hooks will be skipped if the element doesn't contain any text or there is no grammar loaded for + * the element's language. + * + * @param {Element} element The element containing the code. + * It must have a class of `language-xxxx` to be processed, where `xxxx` is a valid language identifier. + * @param {boolean} [async=false] Whether the element is to be highlighted asynchronously using Web Workers + * to improve performance and avoid blocking the UI when highlighting very large chunks of code. This option is + * [disabled by default](https://prismjs.com/faq.html#why-is-asynchronous-highlighting-disabled-by-default). + * + * Note: All language definitions required to highlight the code must be included in the main `prism.js` file for + * asynchronous highlighting to work. You can build your own bundle on the + * [Download page](https://prismjs.com/download.html). + * @param {HighlightCallback} [callback] An optional callback to be invoked after the highlighting is done. + * Mostly useful when `async` is `true`, since in that case, the highlighting is done asynchronously. + * @memberof Prism + * @public + */ + highlightElement: function (element, async, callback) { + // Find language + var language = _.util.getLanguage(element); + var grammar = _.languages[language]; + + // Set language on the element, if not present + element.className = element.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; + + // Set language on the parent, for styling + var parent = element.parentElement; + if (parent && parent.nodeName.toLowerCase() === 'pre') { + parent.className = parent.className.replace(lang, '').replace(/\s+/g, ' ') + ' language-' + language; + } + + var code = element.textContent; + + var env = { + element: element, + language: language, + grammar: grammar, + code: code, + }; + + function insertHighlightedCode(highlightedCode) { + env.highlightedCode = highlightedCode; + + _.hooks.run('before-insert', env); + + env.element.innerHTML = env.highlightedCode; + + _.hooks.run('after-highlight', env); + _.hooks.run('complete', env); + callback && callback.call(env.element); + } + + _.hooks.run('before-sanity-check', env); + + if (!env.code) { + _.hooks.run('complete', env); + callback && callback.call(env.element); + return; + } + + _.hooks.run('before-highlight', env); + + if (!env.grammar) { + insertHighlightedCode(_.util.encode(env.code)); + return; + } + + if (async && _self.Worker) { + var worker = new Worker(_.filename); + + worker.onmessage = function (evt) { + insertHighlightedCode(evt.data); + }; + + worker.postMessage( + JSON.stringify({ + language: env.language, + code: env.code, + immediateClose: true, + }) + ); + } else { + insertHighlightedCode(_.highlight(env.code, env.grammar, env.language)); + } + }, + + /** + * Low-level function, only use if you know what you’re doing. It accepts a string of text as input + * and the language definitions to use, and returns a string with the HTML produced. + * + * The following hooks will be run: + * 1. `before-tokenize` + * 2. `after-tokenize` + * 3. `wrap`: On each {@link Token}. + * + * @param {string} text A string with the code to be highlighted. + * @param {Grammar} grammar An object containing the tokens to use. + * + * Usually a language definition like `Prism.languages.markup`. + * @param {string} language The name of the language definition passed to `grammar`. + * @returns {string} The highlighted HTML. + * @memberof Prism + * @public + * @example + * Prism.highlight('var foo = true;', Prism.languages.javascript, 'javascript'); + */ + highlight: function (text, grammar, language) { + var env = { + code: text, + grammar: grammar, + language: language, + }; + _.hooks.run('before-tokenize', env); + env.tokens = _.tokenize(env.code, env.grammar); + _.hooks.run('after-tokenize', env); + return Token.stringify(_.util.encode(env.tokens), env.language); + }, + + /** + * This is the heart of Prism, and the most low-level function you can use. It accepts a string of text as input + * and the language definitions to use, and returns an array with the tokenized code. + * + * When the language definition includes nested tokens, the function is called recursively on each of these tokens. + * + * This method could be useful in other contexts as well, as a very crude parser. + * + * @param {string} text A string with the code to be highlighted. + * @param {Grammar} grammar An object containing the tokens to use. + * + * Usually a language definition like `Prism.languages.markup`. + * @returns {TokenStream} An array of strings and tokens, a token stream. + * @memberof Prism + * @public + * @example + * let code = `var foo = 0;`; + * let tokens = Prism.tokenize(code, Prism.languages.javascript); + * tokens.forEach(token => { + * if (token instanceof Prism.Token && token.type === 'number') { + * console.log(`Found numeric literal: ${token.content}`); + * } + * }); + */ + tokenize: function (text, grammar) { + var rest = grammar.rest; + if (rest) { + for (var token in rest) { + grammar[token] = rest[token]; + } + + delete grammar.rest; + } + + var tokenList = new LinkedList(); + addAfter(tokenList, tokenList.head, text); + + matchGrammar(text, tokenList, grammar, tokenList.head, 0); + + return toArray(tokenList); + }, + + /** + * @namespace + * @memberof Prism + * @public + */ + hooks: { + all: {}, + + /** + * Adds the given callback to the list of callbacks for the given hook. + * + * The callback will be invoked when the hook it is registered for is run. + * Hooks are usually directly run by a highlight function but you can also run hooks yourself. + * + * One callback function can be registered to multiple hooks and the same hook multiple times. + * + * @param {string} name The name of the hook. + * @param {HookCallback} callback The callback function which is given environment variables. + * @public + */ + add: function (name, callback) { + var hooks = _.hooks.all; + + hooks[name] = hooks[name] || []; + + hooks[name].push(callback); + }, + + /** + * Runs a hook invoking all registered callbacks with the given environment variables. + * + * Callbacks will be invoked synchronously and in the order in which they were registered. + * + * @param {string} name The name of the hook. + * @param {Object<string, any>} env The environment variables of the hook passed to all callbacks registered. + * @public + */ + run: function (name, env) { + var callbacks = _.hooks.all[name]; + + if (!callbacks || !callbacks.length) { + return; + } + + for (var i = 0, callback; (callback = callbacks[i++]); ) { + callback(env); + } + }, + }, + + Token: Token, + }; + _self.Prism = _; + + // Typescript note: + // The following can be used to import the Token type in JSDoc: + // + // @typedef {InstanceType<import("./prism-core")["Token"]>} Token + + /** + * Creates a new token. + * + * @param {string} type See {@link Token#type type} + * @param {string | TokenStream} content See {@link Token#content content} + * @param {string|string[]} [alias] The alias(es) of the token. + * @param {string} [matchedStr=""] A copy of the full string this token was created from. + * @class + * @global + * @public + */ + function Token(type, content, alias, matchedStr) { + /** + * The type of the token. + * + * This is usually the key of a pattern in a {@link Grammar}. + * + * @type {string} + * @see GrammarToken + * @public + */ + this.type = type; + /** + * The strings or tokens contained by this token. + * + * This will be a token stream if the pattern matched also defined an `inside` grammar. + * + * @type {string | TokenStream} + * @public + */ + this.content = content; + /** + * The alias(es) of the token. + * + * @type {string|string[]} + * @see GrammarToken + * @public + */ + this.alias = alias; + // Copy of the full string this token was created from + this.length = (matchedStr || '').length | 0; + } + + /** + * A token stream is an array of strings and {@link Token Token} objects. + * + * Token streams have to fulfill a few properties that are assumed by most functions (mostly internal ones) that process + * them. + * + * 1. No adjacent strings. + * 2. No empty strings. + * + * The only exception here is the token stream that only contains the empty string and nothing else. + * + * @typedef {Array<string | Token>} TokenStream + * @global + * @public + */ + + /** + * Converts the given token or token stream to an HTML representation. + * + * The following hooks will be run: + * 1. `wrap`: On each {@link Token}. + * + * @param {string | Token | TokenStream} o The token or token stream to be converted. + * @param {string} language The name of current language. + * @returns {string} The HTML representation of the token or token stream. + * @memberof Token + * @static + */ + Token.stringify = function stringify(o, language) { + if (typeof o == 'string') { + return o; + } + if (Array.isArray(o)) { + var s = ''; + o.forEach(function (e) { + s += stringify(e, language); + }); + return s; + } + + var env = { + type: o.type, + content: stringify(o.content, language), + tag: 'span', + classes: ['token', o.type], + attributes: {}, + language: language, + }; + + var aliases = o.alias; + if (aliases) { + if (Array.isArray(aliases)) { + Array.prototype.push.apply(env.classes, aliases); + } else { + env.classes.push(aliases); + } + } + + _.hooks.run('wrap', env); + + var attributes = ''; + for (var name in env.attributes) { + attributes += ' ' + name + '="' + (env.attributes[name] || '').replace(/"/g, '"') + '"'; + } + + return '<' + env.tag + ' class="' + env.classes.join(' ') + '"' + attributes + '>' + env.content + '</' + env.tag + '>'; + }; + + /** + * @param {RegExp} pattern + * @param {number} pos + * @param {string} text + * @param {boolean} lookbehind + * @returns {RegExpExecArray | null} + */ + function matchPattern(pattern, pos, text, lookbehind) { + pattern.lastIndex = pos; + var match = pattern.exec(text); + if (match && lookbehind && match[1]) { + // change the match to remove the text matched by the Prism lookbehind group + var lookbehindLength = match[1].length; + match.index += lookbehindLength; + match[0] = match[0].slice(lookbehindLength); + } + return match; + } + + /** + * @param {string} text + * @param {LinkedList<string | Token>} tokenList + * @param {any} grammar + * @param {LinkedListNode<string | Token>} startNode + * @param {number} startPos + * @param {RematchOptions} [rematch] + * @returns {void} + * @private + * + * @typedef RematchOptions + * @property {string} cause + * @property {number} reach + */ + function matchGrammar(text, tokenList, grammar, startNode, startPos, rematch) { + for (var token in grammar) { + if (!grammar.hasOwnProperty(token) || !grammar[token]) { + continue; + } + + var patterns = grammar[token]; + patterns = Array.isArray(patterns) ? patterns : [patterns]; + + for (var j = 0; j < patterns.length; ++j) { + if (rematch && rematch.cause == token + ',' + j) { + return; + } + + var patternObj = patterns[j], + inside = patternObj.inside, + lookbehind = !!patternObj.lookbehind, + greedy = !!patternObj.greedy, + alias = patternObj.alias; + + if (greedy && !patternObj.pattern.global) { + // Without the global flag, lastIndex won't work + var flags = patternObj.pattern.toString().match(/[imsuy]*$/)[0]; + patternObj.pattern = RegExp(patternObj.pattern.source, flags + 'g'); + } + + /** @type {RegExp} */ + var pattern = patternObj.pattern || patternObj; + + for ( + // iterate the token list and keep track of the current token/string position + var currentNode = startNode.next, pos = startPos; + currentNode !== tokenList.tail; + pos += currentNode.value.length, currentNode = currentNode.next + ) { + if (rematch && pos >= rematch.reach) { + break; + } + + var str = currentNode.value; + + if (tokenList.length > text.length) { + // Something went terribly wrong, ABORT, ABORT! + return; + } + + if (str instanceof Token) { + continue; + } + + var removeCount = 1; // this is the to parameter of removeBetween + var match; + + if (greedy) { + match = matchPattern(pattern, pos, text, lookbehind); + if (!match) { + break; + } + + var from = match.index; + var to = match.index + match[0].length; + var p = pos; + + // find the node that contains the match + p += currentNode.value.length; + while (from >= p) { + currentNode = currentNode.next; + p += currentNode.value.length; + } + // adjust pos (and p) + p -= currentNode.value.length; + pos = p; + + // the current node is a Token, then the match starts inside another Token, which is invalid + if (currentNode.value instanceof Token) { + continue; + } + + // find the last node which is affected by this match + for (var k = currentNode; k !== tokenList.tail && (p < to || typeof k.value === 'string'); k = k.next) { + removeCount++; + p += k.value.length; + } + removeCount--; + + // replace with the new match + str = text.slice(pos, p); + match.index -= pos; + } else { + match = matchPattern(pattern, 0, str, lookbehind); + if (!match) { + continue; + } + } + + var from = match.index, + matchStr = match[0], + before = str.slice(0, from), + after = str.slice(from + matchStr.length); + + var reach = pos + str.length; + if (rematch && reach > rematch.reach) { + rematch.reach = reach; + } + + var removeFrom = currentNode.prev; + + if (before) { + removeFrom = addAfter(tokenList, removeFrom, before); + pos += before.length; + } + + removeRange(tokenList, removeFrom, removeCount); + + var wrapped = new Token(token, inside ? _.tokenize(matchStr, inside) : matchStr, alias, matchStr); + currentNode = addAfter(tokenList, removeFrom, wrapped); + + if (after) { + addAfter(tokenList, currentNode, after); + } + + if (removeCount > 1) { + // at least one Token object was removed, so we have to do some rematching + // this can only happen if the current pattern is greedy + matchGrammar(text, tokenList, grammar, currentNode.prev, pos, { + cause: token + ',' + j, + reach: reach, + }); + } + } + } + } + } + + /** + * @typedef LinkedListNode + * @property {T} value + * @property {LinkedListNode<T> | null} prev The previous node. + * @property {LinkedListNode<T> | null} next The next node. + * @template T + * @private + */ + + /** + * @template T + * @private + */ + function LinkedList() { + /** @type {LinkedListNode<T>} */ + var head = { value: null, prev: null, next: null }; + /** @type {LinkedListNode<T>} */ + var tail = { value: null, prev: head, next: null }; + head.next = tail; + + /** @type {LinkedListNode<T>} */ + this.head = head; + /** @type {LinkedListNode<T>} */ + this.tail = tail; + this.length = 0; + } + + /** + * Adds a new node with the given value to the list. + * @param {LinkedList<T>} list + * @param {LinkedListNode<T>} node + * @param {T} value + * @returns {LinkedListNode<T>} The added node. + * @template T + */ + function addAfter(list, node, value) { + // assumes that node != list.tail && values.length >= 0 + var next = node.next; + + var newNode = { value: value, prev: node, next: next }; + node.next = newNode; + next.prev = newNode; + list.length++; + + return newNode; + } + /** + * Removes `count` nodes after the given node. The given node will not be removed. + * @param {LinkedList<T>} list + * @param {LinkedListNode<T>} node + * @param {number} count + * @template T + */ + function removeRange(list, node, count) { + var next = node.next; + for (var i = 0; i < count && next !== list.tail; i++) { + next = next.next; + } + node.next = next; + next.prev = node; + list.length -= i; + } + /** + * @param {LinkedList<T>} list + * @returns {T[]} + * @template T + */ + function toArray(list) { + var array = []; + var node = list.head.next; + while (node !== list.tail) { + array.push(node.value); + node = node.next; + } + return array; + } + + if (!_self.document) { + if (!_self.addEventListener) { + // in Node.js + return _; + } + + if (!_.disableWorkerMessageHandler) { + // In worker + _self.addEventListener( + 'message', + function (evt) { + var message = JSON.parse(evt.data), + lang = message.language, + code = message.code, + immediateClose = message.immediateClose; + + _self.postMessage(_.highlight(code, _.languages[lang], lang)); + if (immediateClose) { + _self.close(); + } + }, + false + ); + } + + return _; + } + + // Get current script and highlight + var script = _.util.currentScript(); + + if (script) { + _.filename = script.src; + + if (script.hasAttribute('data-manual')) { + _.manual = true; + } + } + + function highlightAutomaticallyCallback() { + if (!_.manual) { + _.highlightAll(); + } + } + + if (!_.manual) { + // If the document state is "loading", then we'll use DOMContentLoaded. + // If the document state is "interactive" and the prism.js script is deferred, then we'll also use the + // DOMContentLoaded event because there might be some plugins or languages which have also been deferred and they + // might take longer one animation frame to execute which can create a race condition where only some plugins have + // been loaded when Prism.highlightAll() is executed, depending on how fast resources are loaded. + // See https://github.com/PrismJS/prism/issues/2102 + var readyState = document.readyState; + if (readyState === 'loading' || (readyState === 'interactive' && script && script.defer)) { + document.addEventListener('DOMContentLoaded', highlightAutomaticallyCallback); + } else { + if (window.requestAnimationFrame) { + window.requestAnimationFrame(highlightAutomaticallyCallback); + } else { + window.setTimeout(highlightAutomaticallyCallback, 16); + } + } + } + + return _; })(_self); if (typeof module !== 'undefined' && module.exports) { - module.exports = Prism; + module.exports = Prism; } // hack for components to work correctly in node.js if (typeof global !== 'undefined') { - global.Prism = Prism; + global.Prism = Prism; } // some additional documentation/types @@ -1171,7 +1166,7 @@ if (typeof global !== 'undefined') { * each another. * @global * @public -*/ + */ /** * @typedef Grammar @@ -1189,7 +1184,7 @@ if (typeof global !== 'undefined') { * @returns {void} * @global * @public -*/ + */ /** * @callback HookCallback @@ -1199,131 +1194,132 @@ if (typeof global !== 'undefined') { * @public */ - /* ********************************************** Begin prism-markup.js ********************************************** */ Prism.languages.markup = { - 'comment': /<!--[\s\S]*?-->/, - 'prolog': /<\?[\s\S]+?\?>/, - 'doctype': { - // https://www.w3.org/TR/xml/#NT-doctypedecl - pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i, - greedy: true, - inside: { - 'internal-subset': { - pattern: /(\[)[\s\S]+(?=\]>$)/, - lookbehind: true, - greedy: true, - inside: null // see below - }, - 'string': { - pattern: /"[^"]*"|'[^']*'/, - greedy: true - }, - 'punctuation': /^<!|>$|[[\]]/, - 'doctype-tag': /^DOCTYPE/, - 'name': /[^\s<>'"]+/ - } - }, - 'cdata': /<!\[CDATA\[[\s\S]*?]]>/i, - 'tag': { - pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/, - greedy: true, - inside: { - 'tag': { - pattern: /^<\/?[^\s>\/]+/, - inside: { - 'punctuation': /^<\/?/, - 'namespace': /^[^\s>\/:]+:/ - } - }, - 'attr-value': { - pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/, - inside: { - 'punctuation': [ - { - pattern: /^=/, - alias: 'attr-equals' - }, - /"|'/ - ] - } - }, - 'punctuation': /\/?>/, - 'attr-name': { - pattern: /[^\s>\/]+/, - inside: { - 'namespace': /^[^\s>\/:]+:/ - } - } - - } - }, - 'entity': [ - { - pattern: /&[\da-z]{1,8};/i, - alias: 'named-entity' - }, - /&#x?[\da-f]{1,8};/i - ] + comment: /<!--[\s\S]*?-->/, + prolog: /<\?[\s\S]+?\?>/, + doctype: { + // https://www.w3.org/TR/xml/#NT-doctypedecl + pattern: /<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i, + greedy: true, + inside: { + 'internal-subset': { + pattern: /(\[)[\s\S]+(?=\]>$)/, + lookbehind: true, + greedy: true, + inside: null, // see below + }, + string: { + pattern: /"[^"]*"|'[^']*'/, + greedy: true, + }, + punctuation: /^<!|>$|[[\]]/, + 'doctype-tag': /^DOCTYPE/, + name: /[^\s<>'"]+/, + }, + }, + cdata: /<!\[CDATA\[[\s\S]*?]]>/i, + tag: { + pattern: /<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/, + greedy: true, + inside: { + tag: { + pattern: /^<\/?[^\s>\/]+/, + inside: { + punctuation: /^<\/?/, + namespace: /^[^\s>\/:]+:/, + }, + }, + 'attr-value': { + pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/, + inside: { + punctuation: [ + { + pattern: /^=/, + alias: 'attr-equals', + }, + /"|'/, + ], + }, + }, + punctuation: /\/?>/, + 'attr-name': { + pattern: /[^\s>\/]+/, + inside: { + namespace: /^[^\s>\/:]+:/, + }, + }, + }, + }, + entity: [ + { + pattern: /&[\da-z]{1,8};/i, + alias: 'named-entity', + }, + /&#x?[\da-f]{1,8};/i, + ], }; -Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] = - Prism.languages.markup['entity']; +Prism.languages.markup['tag'].inside['attr-value'].inside['entity'] = Prism.languages.markup['entity']; Prism.languages.markup['doctype'].inside['internal-subset'].inside = Prism.languages.markup; // Plugin to make entity title show the real entity, idea by Roman Komarov Prism.hooks.add('wrap', function (env) { - - if (env.type === 'entity') { - env.attributes['title'] = env.content.replace(/&/, '&'); - } + if (env.type === 'entity') { + env.attributes['title'] = env.content.replace(/&/, '&'); + } }); Object.defineProperty(Prism.languages.markup.tag, 'addInlined', { - /** - * Adds an inlined language to markup. - * - * An example of an inlined language is CSS with `<style>` tags. - * - * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as - * case insensitive. - * @param {string} lang The language key. - * @example - * addInlined('style', 'css'); - */ - value: function addInlined(tagName, lang) { - var includedCdataInside = {}; - includedCdataInside['language-' + lang] = { - pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, - lookbehind: true, - inside: Prism.languages[lang] - }; - includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i; - - var inside = { - 'included-cdata': { - pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i, - inside: includedCdataInside - } - }; - inside['language-' + lang] = { - pattern: /[\s\S]+/, - inside: Prism.languages[lang] - }; - - var def = {}; - def[tagName] = { - pattern: RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { return tagName; }), 'i'), - lookbehind: true, - greedy: true, - inside: inside - }; - - Prism.languages.insertBefore('markup', 'cdata', def); - } + /** + * Adds an inlined language to markup. + * + * An example of an inlined language is CSS with `<style>` tags. + * + * @param {string} tagName The name of the tag that contains the inlined language. This name will be treated as + * case insensitive. + * @param {string} lang The language key. + * @example + * addInlined('style', 'css'); + */ + value: function addInlined(tagName, lang) { + var includedCdataInside = {}; + includedCdataInside['language-' + lang] = { + pattern: /(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i, + lookbehind: true, + inside: Prism.languages[lang], + }; + includedCdataInside['cdata'] = /^<!\[CDATA\[|\]\]>$/i; + + var inside = { + 'included-cdata': { + pattern: /<!\[CDATA\[[\s\S]*?\]\]>/i, + inside: includedCdataInside, + }, + }; + inside['language-' + lang] = { + pattern: /[\s\S]+/, + inside: Prism.languages[lang], + }; + + var def = {}; + def[tagName] = { + pattern: RegExp( + /(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g, function () { + return tagName; + }), + 'i' + ), + lookbehind: true, + greedy: true, + inside: inside, + }; + + Prism.languages.insertBefore('markup', 'cdata', def); + }, }); Prism.languages.html = Prism.languages.markup; @@ -1335,386 +1331,388 @@ Prism.languages.ssml = Prism.languages.xml; Prism.languages.atom = Prism.languages.xml; Prism.languages.rss = Prism.languages.xml; - /* ********************************************** Begin prism-css.js ********************************************** */ (function (Prism) { - - var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/; - - Prism.languages.css = { - 'comment': /\/\*[\s\S]*?\*\//, - 'atrule': { - pattern: /@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/, - inside: { - 'rule': /^@[\w-]+/, - 'selector-function-argument': { - pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/, - lookbehind: true, - alias: 'selector' - }, - 'keyword': { - pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/, - lookbehind: true - } - // See rest below - } - }, - 'url': { - // https://drafts.csswg.org/css-values-3/#urls - pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'), - greedy: true, - inside: { - 'function': /^url/i, - 'punctuation': /^\(|\)$/, - 'string': { - pattern: RegExp('^' + string.source + '$'), - alias: 'url' - } - } - }, - 'selector': RegExp('[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'), - 'string': { - pattern: string, - greedy: true - }, - 'property': /(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i, - 'important': /!important\b/i, - 'function': /[-a-z0-9]+(?=\()/i, - 'punctuation': /[(){};:,]/ - }; - - Prism.languages.css['atrule'].inside.rest = Prism.languages.css; - - var markup = Prism.languages.markup; - if (markup) { - markup.tag.addInlined('style', 'css'); - - Prism.languages.insertBefore('inside', 'attr-value', { - 'style-attr': { - pattern: /(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i, - lookbehind: true, - inside: { - 'attr-value': { - pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/, - inside: { - 'style': { - pattern: /(["'])[\s\S]+(?=["']$)/, - lookbehind: true, - alias: 'language-css', - inside: Prism.languages.css - }, - 'punctuation': [ - { - pattern: /^=/, - alias: 'attr-equals' - }, - /"|'/ - ] - } - }, - 'attr-name': /^style/i - } - } - }, markup.tag); - } - -}(Prism)); - + var string = /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/; + + Prism.languages.css = { + comment: /\/\*[\s\S]*?\*\//, + atrule: { + pattern: /@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/, + inside: { + rule: /^@[\w-]+/, + 'selector-function-argument': { + pattern: /(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/, + lookbehind: true, + alias: 'selector', + }, + keyword: { + pattern: /(^|[^\w-])(?:and|not|only|or)(?![\w-])/, + lookbehind: true, + }, + // See rest below + }, + }, + url: { + // https://drafts.csswg.org/css-values-3/#urls + pattern: RegExp('\\burl\\((?:' + string.source + '|' + /(?:[^\\\r\n()"']|\\[\s\S])*/.source + ')\\)', 'i'), + greedy: true, + inside: { + function: /^url/i, + punctuation: /^\(|\)$/, + string: { + pattern: RegExp('^' + string.source + '$'), + alias: 'url', + }, + }, + }, + selector: RegExp('[^{}\\s](?:[^{};"\'\\s]|\\s+(?![\\s{])|' + string.source + ')*(?=\\s*\\{)'), + string: { + pattern: string, + greedy: true, + }, + property: /(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i, + important: /!important\b/i, + function: /[-a-z0-9]+(?=\()/i, + punctuation: /[(){};:,]/, + }; + + Prism.languages.css['atrule'].inside.rest = Prism.languages.css; + + var markup = Prism.languages.markup; + if (markup) { + markup.tag.addInlined('style', 'css'); + + Prism.languages.insertBefore( + 'inside', + 'attr-value', + { + 'style-attr': { + pattern: /(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i, + lookbehind: true, + inside: { + 'attr-value': { + pattern: /=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/, + inside: { + style: { + pattern: /(["'])[\s\S]+(?=["']$)/, + lookbehind: true, + alias: 'language-css', + inside: Prism.languages.css, + }, + punctuation: [ + { + pattern: /^=/, + alias: 'attr-equals', + }, + /"|'/, + ], + }, + }, + 'attr-name': /^style/i, + }, + }, + }, + markup.tag + ); + } +})(Prism); /* ********************************************** Begin prism-clike.js ********************************************** */ Prism.languages.clike = { - 'comment': [ - { - pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, - lookbehind: true, - greedy: true - }, - { - pattern: /(^|[^\\:])\/\/.*/, - lookbehind: true, - greedy: true - } - ], - 'string': { - pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, - greedy: true - }, - 'class-name': { - pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i, - lookbehind: true, - inside: { - 'punctuation': /[.\\]/ - } - }, - 'keyword': /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, - 'boolean': /\b(?:true|false)\b/, - 'function': /\w+(?=\()/, - 'number': /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, - 'operator': /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, - 'punctuation': /[{}[\];(),.:]/ + comment: [ + { + pattern: /(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/, + lookbehind: true, + greedy: true, + }, + { + pattern: /(^|[^\\:])\/\/.*/, + lookbehind: true, + greedy: true, + }, + ], + string: { + pattern: /(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/, + greedy: true, + }, + 'class-name': { + pattern: /(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i, + lookbehind: true, + inside: { + punctuation: /[.\\]/, + }, + }, + keyword: /\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/, + boolean: /\b(?:true|false)\b/, + function: /\w+(?=\()/, + number: /\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i, + operator: /[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/, + punctuation: /[{}[\];(),.:]/, }; - /* ********************************************** Begin prism-javascript.js ********************************************** */ Prism.languages.javascript = Prism.languages.extend('clike', { - 'class-name': [ - Prism.languages.clike['class-name'], - { - pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/, - lookbehind: true - } - ], - 'keyword': [ - { - pattern: /((?:^|})\s*)(?:catch|finally)\b/, - lookbehind: true - }, - { - pattern: /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, - lookbehind: true - }, - ], - // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) - 'function': /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, - 'number': /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/, - 'operator': /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/ + 'class-name': [ + Prism.languages.clike['class-name'], + { + pattern: /(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/, + lookbehind: true, + }, + ], + keyword: [ + { + pattern: /((?:^|})\s*)(?:catch|finally)\b/, + lookbehind: true, + }, + { + pattern: + /(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|function|(?:get|set)(?=\s*[\[$\w\xA0-\uFFFF])|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/, + lookbehind: true, + }, + ], + // Allow for all non-ASCII characters (See http://stackoverflow.com/a/2008444) + function: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/, + number: + /\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/, + operator: /--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/, }); Prism.languages.javascript['class-name'][0].pattern = /(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/; Prism.languages.insertBefore('javascript', 'keyword', { - 'regex': { - pattern: /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/, - lookbehind: true, - greedy: true, - inside: { - 'regex-source': { - pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/, - lookbehind: true, - alias: 'language-regex', - inside: Prism.languages.regex - }, - 'regex-flags': /[a-z]+$/, - 'regex-delimiter': /^\/|\/$/ - } - }, - // This must be declared before keyword because we use "function" inside the look-forward - 'function-variable': { - pattern: /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/, - alias: 'function' - }, - 'parameter': [ - { - pattern: /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/, - lookbehind: true, - inside: Prism.languages.javascript - }, - { - pattern: /(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i, - inside: Prism.languages.javascript - }, - { - pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/, - lookbehind: true, - inside: Prism.languages.javascript - }, - { - pattern: /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/, - lookbehind: true, - inside: Prism.languages.javascript - } - ], - 'constant': /\b[A-Z](?:[A-Z_]|\dx?)*\b/ + regex: { + pattern: + /((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/, + lookbehind: true, + greedy: true, + inside: { + 'regex-source': { + pattern: /^(\/)[\s\S]+(?=\/[a-z]*$)/, + lookbehind: true, + alias: 'language-regex', + inside: Prism.languages.regex, + }, + 'regex-flags': /[a-z]+$/, + 'regex-delimiter': /^\/|\/$/, + }, + }, + // This must be declared before keyword because we use "function" inside the look-forward + 'function-variable': { + pattern: + /#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/, + alias: 'function', + }, + parameter: [ + { + pattern: + /(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/, + lookbehind: true, + inside: Prism.languages.javascript, + }, + { + pattern: /(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i, + inside: Prism.languages.javascript, + }, + { + pattern: /(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/, + lookbehind: true, + inside: Prism.languages.javascript, + }, + { + pattern: + /((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/, + lookbehind: true, + inside: Prism.languages.javascript, + }, + ], + constant: /\b[A-Z](?:[A-Z_]|\dx?)*\b/, }); Prism.languages.insertBefore('javascript', 'string', { - 'template-string': { - pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/, - greedy: true, - inside: { - 'template-punctuation': { - pattern: /^`|`$/, - alias: 'string' - }, - 'interpolation': { - pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/, - lookbehind: true, - inside: { - 'interpolation-punctuation': { - pattern: /^\${|}$/, - alias: 'punctuation' - }, - rest: Prism.languages.javascript - } - }, - 'string': /[\s\S]+/ - } - } + 'template-string': { + pattern: /`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/, + greedy: true, + inside: { + 'template-punctuation': { + pattern: /^`|`$/, + alias: 'string', + }, + interpolation: { + pattern: /((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/, + lookbehind: true, + inside: { + 'interpolation-punctuation': { + pattern: /^\${|}$/, + alias: 'punctuation', + }, + rest: Prism.languages.javascript, + }, + }, + string: /[\s\S]+/, + }, + }, }); if (Prism.languages.markup) { - Prism.languages.markup.tag.addInlined('script', 'javascript'); + Prism.languages.markup.tag.addInlined('script', 'javascript'); } Prism.languages.js = Prism.languages.javascript; - /* ********************************************** Begin prism-file-highlight.js ********************************************** */ (function () { - if (typeof self === 'undefined' || !self.Prism || !self.document) { - return; - } - - // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill - if (!Element.prototype.matches) { - Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; - } - - var Prism = window.Prism; - - var LOADING_MESSAGE = 'Loading…'; - var FAILURE_MESSAGE = function (status, message) { - return '✖ Error ' + status + ' while fetching file: ' + message; - }; - var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty'; - - var EXTENSIONS = { - 'js': 'javascript', - 'py': 'python', - 'rb': 'ruby', - 'ps1': 'powershell', - 'psm1': 'powershell', - 'sh': 'bash', - 'bat': 'batch', - 'h': 'c', - 'tex': 'latex' - }; - - var STATUS_ATTR = 'data-src-status'; - var STATUS_LOADING = 'loading'; - var STATUS_LOADED = 'loaded'; - var STATUS_FAILED = 'failed'; - - var SELECTOR = 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])' - + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])'; - - var lang = /\blang(?:uage)?-([\w-]+)\b/i; - - /** - * Sets the Prism `language-xxxx` or `lang-xxxx` class to the given language. - * - * @param {HTMLElement} element - * @param {string} language - * @returns {void} - */ - function setLanguageClass(element, language) { - var className = element.className; - className = className.replace(lang, ' ') + ' language-' + language; - element.className = className.replace(/\s+/g, ' ').trim(); - } - - - Prism.hooks.add('before-highlightall', function (env) { - env.selector += ', ' + SELECTOR; - }); - - Prism.hooks.add('before-sanity-check', function (env) { - var pre = /** @type {HTMLPreElement} */ (env.element); - if (pre.matches(SELECTOR)) { - env.code = ''; // fast-path the whole thing and go to complete - - pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading - - // add code element with loading message - var code = pre.appendChild(document.createElement('CODE')); - code.textContent = LOADING_MESSAGE; - - var src = pre.getAttribute('data-src'); - - var language = env.language; - if (language === 'none') { - // the language might be 'none' because there is no language set; - // in this case, we want to use the extension as the language - var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1]; - language = EXTENSIONS[extension] || extension; - } - - // set language classes - setLanguageClass(code, language); - setLanguageClass(pre, language); - - // preload the language - var autoloader = Prism.plugins.autoloader; - if (autoloader) { - autoloader.loadLanguages(language); - } - - // load file - var xhr = new XMLHttpRequest(); - xhr.open('GET', src, true); - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (xhr.status < 400 && xhr.responseText) { - // mark as loaded - pre.setAttribute(STATUS_ATTR, STATUS_LOADED); - - // highlight code - code.textContent = xhr.responseText; - Prism.highlightElement(code); - - } else { - // mark as failed - pre.setAttribute(STATUS_ATTR, STATUS_FAILED); - - if (xhr.status >= 400) { - code.textContent = FAILURE_MESSAGE(xhr.status, xhr.statusText); - } else { - code.textContent = FAILURE_EMPTY_MESSAGE; - } - } - } - }; - xhr.send(null); - } - }); - - Prism.plugins.fileHighlight = { - /** - * Executes the File Highlight plugin for all matching `pre` elements under the given container. - * - * Note: Elements which are already loaded or currently loading will not be touched by this method. - * - * @param {ParentNode} [container=document] - */ - highlight: function highlight(container) { - var elements = (container || document).querySelectorAll(SELECTOR); - - for (var i = 0, element; element = elements[i++];) { - Prism.highlightElement(element); - } - } - }; - - var logged = false; - /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */ - Prism.fileHighlight = function () { - if (!logged) { - console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.'); - logged = true; - } - Prism.plugins.fileHighlight.highlight.apply(this, arguments); - } - + if (typeof self === 'undefined' || !self.Prism || !self.document) { + return; + } + + // https://developer.mozilla.org/en-US/docs/Web/API/Element/matches#Polyfill + if (!Element.prototype.matches) { + Element.prototype.matches = Element.prototype.msMatchesSelector || Element.prototype.webkitMatchesSelector; + } + + var Prism = window.Prism; + + var LOADING_MESSAGE = 'Loading…'; + var FAILURE_MESSAGE = function (status, message) { + return '✖ Error ' + status + ' while fetching file: ' + message; + }; + var FAILURE_EMPTY_MESSAGE = '✖ Error: File does not exist or is empty'; + + var EXTENSIONS = { + js: 'javascript', + py: 'python', + rb: 'ruby', + ps1: 'powershell', + psm1: 'powershell', + sh: 'bash', + bat: 'batch', + h: 'c', + tex: 'latex', + }; + + var STATUS_ATTR = 'data-src-status'; + var STATUS_LOADING = 'loading'; + var STATUS_LOADED = 'loaded'; + var STATUS_FAILED = 'failed'; + + var SELECTOR = + 'pre[data-src]:not([' + STATUS_ATTR + '="' + STATUS_LOADED + '"])' + ':not([' + STATUS_ATTR + '="' + STATUS_LOADING + '"])'; + + var lang = /\blang(?:uage)?-([\w-]+)\b/i; + + /** + * Sets the Prism `language-xxxx` or `lang-xxxx` class to the given language. + * + * @param {HTMLElement} element + * @param {string} language + * @returns {void} + */ + function setLanguageClass(element, language) { + var className = element.className; + className = className.replace(lang, ' ') + ' language-' + language; + element.className = className.replace(/\s+/g, ' ').trim(); + } + + Prism.hooks.add('before-highlightall', function (env) { + env.selector += ', ' + SELECTOR; + }); + + Prism.hooks.add('before-sanity-check', function (env) { + var pre = /** @type {HTMLPreElement} */ (env.element); + if (pre.matches(SELECTOR)) { + env.code = ''; // fast-path the whole thing and go to complete + + pre.setAttribute(STATUS_ATTR, STATUS_LOADING); // mark as loading + + // add code element with loading message + var code = pre.appendChild(document.createElement('CODE')); + code.textContent = LOADING_MESSAGE; + + var src = pre.getAttribute('data-src'); + + var language = env.language; + if (language === 'none') { + // the language might be 'none' because there is no language set; + // in this case, we want to use the extension as the language + var extension = (/\.(\w+)$/.exec(src) || [, 'none'])[1]; + language = EXTENSIONS[extension] || extension; + } + + // set language classes + setLanguageClass(code, language); + setLanguageClass(pre, language); + + // preload the language + var autoloader = Prism.plugins.autoloader; + if (autoloader) { + autoloader.loadLanguages(language); + } + + // load file + var xhr = new XMLHttpRequest(); + xhr.open('GET', src, true); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + if (xhr.status < 400 && xhr.responseText) { + // mark as loaded + pre.setAttribute(STATUS_ATTR, STATUS_LOADED); + + // highlight code + code.textContent = xhr.responseText; + Prism.highlightElement(code); + } else { + // mark as failed + pre.setAttribute(STATUS_ATTR, STATUS_FAILED); + + if (xhr.status >= 400) { + code.textContent = FAILURE_MESSAGE(xhr.status, xhr.statusText); + } else { + code.textContent = FAILURE_EMPTY_MESSAGE; + } + } + } + }; + xhr.send(null); + } + }); + + Prism.plugins.fileHighlight = { + /** + * Executes the File Highlight plugin for all matching `pre` elements under the given container. + * + * Note: Elements which are already loaded or currently loading will not be touched by this method. + * + * @param {ParentNode} [container=document] + */ + highlight: function highlight(container) { + var elements = (container || document).querySelectorAll(SELECTOR); + + for (var i = 0, element; (element = elements[i++]); ) { + Prism.highlightElement(element); + } + }, + }; + + var logged = false; + /** @deprecated Use `Prism.plugins.fileHighlight.highlight` instead. */ + Prism.fileHighlight = function () { + if (!logged) { + console.warn('Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead.'); + logged = true; + } + Prism.plugins.fileHighlight.highlight.apply(this, arguments); + }; })(); diff --git a/src/main/webapp/content/js/jquery3.5.1.min.js b/src/main/webapp/content/js/jquery3.5.1.min.js index b0614034ad3a95e4ae9f53c2b015eeb3e8d68bde..1ff1cd4043a621cb6e9d0464a29715b63dc86b44 100644 --- a/src/main/webapp/content/js/jquery3.5.1.min.js +++ b/src/main/webapp/content/js/jquery3.5.1.min.js @@ -1,2 +1,4539 @@ /*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),D=function(e,t){return e===t&&(l=!0),0},j={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&j.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(D),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(D).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(D(this,e||[],!1))},not:function(e){return this.pushStack(D(this,e||[],!0))},is:function(e){return!!D(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var j,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^key/,we=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Te=/^([^.]*)(?:\.(.+)|)/;function Ce(){return!0}function Ee(){return!1}function Se(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function ke(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)ke(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Ee;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Ae(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,Ce)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=Te.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=Te.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click",Ce),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Ae(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?Ce:Ee,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Ee,isPropagationStopped:Ee,isImmediatePropagationStopped:Ee,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=Ce,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=Ce,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=Ce,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:function(e){var t=e.button;return null==e.which&&be.test(e.type)?null!=e.charCode?e.charCode:e.keyCode:!e.which&&void 0!==t&&we.test(e.type)?1&t?1:2&t?3:4&t?2:0:e.which}},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Ae(this,e,Se),!1},trigger:function(){return Ae(this,e),!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return ke(this,e,t,n,r)},one:function(e,t,n,r){return ke(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Ee),this.each(function(){S.event.remove(this,e,n,t)})}});var Ne=/<script|<style|<link/i,De=/checked\s*(?:[^=]|=\s*.checked.)/i,je=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function Pe(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&De.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),Pe(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),Le)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,He),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(je,""),u,l))}return n}function Re(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Oe(o[r],a[r]);else Oe(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Re(this,e,!0)},remove:function(e){return Re(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return Pe(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||qe(this,e).appendChild(e)})},prepend:function(){return Pe(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=qe(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return Pe(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!Ne.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return Pe(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Me=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Ie=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},We=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Fe=new RegExp(ne.join("|"),"i");function Be(e,t,n){var r,i,o,a,s=e.style;return(n=n||Ie(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Me.test(a)&&Fe.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function $e(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px",t.style.height="1px",n.style.height="9px",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=3<parseInt(r.height),re.removeChild(e)),a}}))}();var _e=["Webkit","Moz","ms"],ze=E.createElement("div").style,Ue={};function Xe(e){var t=S.cssProps[e]||Ue[e];return t||(e in ze?e:Ue[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=_e.length;while(n--)if((e=_e[n]+t)in ze)return e}(e)||e)}var Ve=/^(none|table(?!-c[ea]).+)/,Ge=/^--/,Ye={position:"absolute",visibility:"hidden",display:"block"},Qe={letterSpacing:"0",fontWeight:"400"};function Je(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Ke(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Ze(e,t,n){var r=Ie(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=Be(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Me.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Ke(e,t,n||(i?"border":"content"),o,r,a)+"px"}function et(e,t,n,r,i){return new et.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Be(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Ge.test(t),l=e.style;if(u||(t=Xe(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Ge.test(t)||(t=Xe(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=Be(e,t,r)),"normal"===i&&t in Qe&&(i=Qe[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ve.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Ze(e,u,n):We(e,Ye,function(){return Ze(e,u,n)})},set:function(e,t,n){var r,i=Ie(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Ke(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Ke(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Je(0,t,s)}}}),S.cssHooks.marginLeft=$e(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(Be(e,"marginLeft"))||e.getBoundingClientRect().left-We(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Je)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Ie(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=et).prototype={constructor:et,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=et.propHooks[this.prop];return e&&e.get?e.get(this):et.propHooks._default.get(this)},run:function(e){var t,n=et.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):et.propHooks._default.set(this),this}}).init.prototype=et.prototype,(et.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[Xe(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=et.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=et.prototype.init,S.fx.step={};var tt,nt,rt,it,ot=/^(?:toggle|show|hide)$/,at=/queueHooks$/;function st(){nt&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(st):C.setTimeout(st,S.fx.interval),S.fx.tick())}function ut(){return C.setTimeout(function(){tt=void 0}),tt=Date.now()}function lt(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ct(e,t,n){for(var r,i=(ft.tweeners[t]||[]).concat(ft.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function ft(o,e,t){var n,a,r=0,i=ft.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=tt||ut(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:tt||ut(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=ft.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ct,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(ft,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],ft.tweeners[n]=ft.tweeners[n]||[],ft.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],ot.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ct(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?ft.prefilters.unshift(e):ft.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=ft(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&at.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(lt(r,!0),e,t,n)}}),S.each({slideDown:lt("show"),slideUp:lt("hide"),slideToggle:lt("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(tt=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),tt=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){nt||(nt=!0,st())},S.fx.stop=function(){nt=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},rt=E.createElement("input"),it=E.createElement("select").appendChild(E.createElement("option")),rt.type="checkbox",y.checkOn=""!==rt.value,y.optSelected=it.selected,(rt=E.createElement("input")).value="t",rt.type="radio",y.radioValue="t"===rt.value;var pt,dt=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?pt:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),pt={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=dt[t]||S.find.attr;dt[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=dt[o],dt[o]=r,r=null!=a(e,t,n)?o:null,dt[o]=i),r}});var ht=/^(?:input|select|textarea|button)$/i,gt=/^(?:a|area)$/i;function vt(e){return(e.match(P)||[]).join(" ")}function yt(e){return e.getAttribute&&e.getAttribute("class")||""}function mt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):ht.test(e.nodeName)||gt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,yt(this)))});if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,yt(this)))});if(!arguments.length)return this.attr("class","");if((e=mt(t)).length)while(n=this[u++])if(i=yt(n),r=1===n.nodeType&&" "+vt(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=vt(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,yt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=mt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=yt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+vt(yt(n))+" ").indexOf(t))return!0;return!1}});var xt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(xt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:vt(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var bt=/^(?:focusinfocus|focusoutblur)$/,wt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!bt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,bt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,wt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,wt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var Tt=C.location,Ct={guid:Date.now()},Et=/\?/;S.parseXML=function(e){var t;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){t=void 0}return t&&!t.getElementsByTagName("parsererror").length||S.error("Invalid XML: "+e),t};var St=/\[\]$/,kt=/\r?\n/g,At=/^(?:submit|button|image|reset|file)$/i,Nt=/^(?:input|select|textarea|keygen)/i;function Dt(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||St.test(n)?i(n,t):Dt(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)Dt(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)Dt(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&Nt.test(this.nodeName)&&!At.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(kt,"\r\n")}}):{name:t.name,value:n.replace(kt,"\r\n")}}).get()}});var jt=/%20/g,qt=/#.*$/,Lt=/([?&])_=[^&]*/,Ht=/^(.*?):[ \t]*([^\r\n]*)$/gm,Ot=/^(?:GET|HEAD)$/,Pt=/^\/\//,Rt={},Mt={},It="*/".concat("*"),Wt=E.createElement("a");function Ft(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Bt(t,i,o,a){var s={},u=t===Mt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function $t(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Wt.href=Tt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Tt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":It,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?$t($t(e,S.ajaxSettings),t):$t(S.ajaxSettings,e)},ajaxPrefilter:Ft(Rt),ajaxTransport:Ft(Mt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=Ht.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||Tt.href)+"").replace(Pt,Tt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Wt.protocol+"//"+Wt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Bt(Rt,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Ot.test(v.type),f=v.url.replace(qt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(jt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Et.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Lt,"$1"),o=(Et.test(f)?"&":"?")+"_="+Ct.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+It+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Bt(Mt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var _t={0:200,1223:204},zt=S.ajaxSettings.xhr();y.cors=!!zt&&"withCredentials"in zt,y.ajax=zt=!!zt,S.ajaxTransport(function(i){var o,a;if(y.cors||zt&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(_t[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=vt(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Gt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Gt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Yt=C.jQuery,Qt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Qt),e&&C.jQuery===S&&(C.jQuery=Yt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S}); +!(function (e, t) { + 'use strict'; + 'object' == typeof module && 'object' == typeof module.exports + ? (module.exports = e.document + ? t(e, !0) + : function (e) { + if (!e.document) throw new Error('jQuery requires a window with a document'); + return t(e); + }) + : t(e); +})('undefined' != typeof window ? window : this, function (C, e) { + 'use strict'; + var t = [], + r = Object.getPrototypeOf, + s = t.slice, + g = t.flat + ? function (e) { + return t.flat.call(e); + } + : function (e) { + return t.concat.apply([], e); + }, + u = t.push, + i = t.indexOf, + n = {}, + o = n.toString, + v = n.hasOwnProperty, + a = v.toString, + l = a.call(Object), + y = {}, + m = function (e) { + return 'function' == typeof e && 'number' != typeof e.nodeType; + }, + x = function (e) { + return null != e && e === e.window; + }, + E = C.document, + c = { type: !0, src: !0, nonce: !0, noModule: !0 }; + function b(e, t, n) { + var r, + i, + o = (n = n || E).createElement('script'); + if (((o.text = e), t)) for (r in c) (i = t[r] || (t.getAttribute && t.getAttribute(r))) && o.setAttribute(r, i); + n.head.appendChild(o).parentNode.removeChild(o); + } + function w(e) { + return null == e ? e + '' : 'object' == typeof e || 'function' == typeof e ? n[o.call(e)] || 'object' : typeof e; + } + var f = '3.5.1', + S = function (e, t) { + return new S.fn.init(e, t); + }; + function p(e) { + var t = !!e && 'length' in e && e.length, + n = w(e); + return !m(e) && !x(e) && ('array' === n || 0 === t || ('number' == typeof t && 0 < t && t - 1 in e)); + } + (S.fn = S.prototype = + { + jquery: f, + constructor: S, + length: 0, + toArray: function () { + return s.call(this); + }, + get: function (e) { + return null == e ? s.call(this) : e < 0 ? this[e + this.length] : this[e]; + }, + pushStack: function (e) { + var t = S.merge(this.constructor(), e); + return (t.prevObject = this), t; + }, + each: function (e) { + return S.each(this, e); + }, + map: function (n) { + return this.pushStack( + S.map(this, function (e, t) { + return n.call(e, t, e); + }) + ); + }, + slice: function () { + return this.pushStack(s.apply(this, arguments)); + }, + first: function () { + return this.eq(0); + }, + last: function () { + return this.eq(-1); + }, + even: function () { + return this.pushStack( + S.grep(this, function (e, t) { + return (t + 1) % 2; + }) + ); + }, + odd: function () { + return this.pushStack( + S.grep(this, function (e, t) { + return t % 2; + }) + ); + }, + eq: function (e) { + var t = this.length, + n = +e + (e < 0 ? t : 0); + return this.pushStack(0 <= n && n < t ? [this[n]] : []); + }, + end: function () { + return this.prevObject || this.constructor(); + }, + push: u, + sort: t.sort, + splice: t.splice, + }), + (S.extend = S.fn.extend = + function () { + var e, + t, + n, + r, + i, + o, + a = arguments[0] || {}, + s = 1, + u = arguments.length, + l = !1; + for ( + 'boolean' == typeof a && ((l = a), (a = arguments[s] || {}), s++), + 'object' == typeof a || m(a) || (a = {}), + s === u && ((a = this), s--); + s < u; + s++ + ) + if (null != (e = arguments[s])) + for (t in e) + (r = e[t]), + '__proto__' !== t && + a !== r && + (l && r && (S.isPlainObject(r) || (i = Array.isArray(r))) + ? ((n = a[t]), + (o = i && !Array.isArray(n) ? [] : i || S.isPlainObject(n) ? n : {}), + (i = !1), + (a[t] = S.extend(l, o, r))) + : void 0 !== r && (a[t] = r)); + return a; + }), + S.extend({ + expando: 'jQuery' + (f + Math.random()).replace(/\D/g, ''), + isReady: !0, + error: function (e) { + throw new Error(e); + }, + noop: function () {}, + isPlainObject: function (e) { + var t, n; + return ( + !(!e || '[object Object]' !== o.call(e)) && + (!(t = r(e)) || ('function' == typeof (n = v.call(t, 'constructor') && t.constructor) && a.call(n) === l)) + ); + }, + isEmptyObject: function (e) { + var t; + for (t in e) return !1; + return !0; + }, + globalEval: function (e, t, n) { + b(e, { nonce: t && t.nonce }, n); + }, + each: function (e, t) { + var n, + r = 0; + if (p(e)) { + for (n = e.length; r < n; r++) if (!1 === t.call(e[r], r, e[r])) break; + } else for (r in e) if (!1 === t.call(e[r], r, e[r])) break; + return e; + }, + makeArray: function (e, t) { + var n = t || []; + return null != e && (p(Object(e)) ? S.merge(n, 'string' == typeof e ? [e] : e) : u.call(n, e)), n; + }, + inArray: function (e, t, n) { + return null == t ? -1 : i.call(t, e, n); + }, + merge: function (e, t) { + for (var n = +t.length, r = 0, i = e.length; r < n; r++) e[i++] = t[r]; + return (e.length = i), e; + }, + grep: function (e, t, n) { + for (var r = [], i = 0, o = e.length, a = !n; i < o; i++) !t(e[i], i) !== a && r.push(e[i]); + return r; + }, + map: function (e, t, n) { + var r, + i, + o = 0, + a = []; + if (p(e)) for (r = e.length; o < r; o++) null != (i = t(e[o], o, n)) && a.push(i); + else for (o in e) null != (i = t(e[o], o, n)) && a.push(i); + return g(a); + }, + guid: 1, + support: y, + }), + 'function' == typeof Symbol && (S.fn[Symbol.iterator] = t[Symbol.iterator]), + S.each('Boolean Number String Function Array Date RegExp Object Error Symbol'.split(' '), function (e, t) { + n['[object ' + t + ']'] = t.toLowerCase(); + }); + var d = (function (n) { + var e, + d, + b, + o, + i, + h, + f, + g, + w, + u, + l, + T, + C, + a, + E, + v, + s, + c, + y, + S = 'sizzle' + 1 * new Date(), + p = n.document, + k = 0, + r = 0, + m = ue(), + x = ue(), + A = ue(), + N = ue(), + D = function (e, t) { + return e === t && (l = !0), 0; + }, + j = {}.hasOwnProperty, + t = [], + q = t.pop, + L = t.push, + H = t.push, + O = t.slice, + P = function (e, t) { + for (var n = 0, r = e.length; n < r; n++) if (e[n] === t) return n; + return -1; + }, + R = 'checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped', + M = '[\\x20\\t\\r\\n\\f]', + I = '(?:\\\\[\\da-fA-F]{1,6}' + M + '?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+', + W = + '\\[' + + M + + '*(' + + I + + ')(?:' + + M + + '*([*^$|!~]?=)' + + M + + '*(?:\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)"|(' + + I + + '))|)' + + M + + '*\\]', + F = ':(' + I + ')(?:\\(((\'((?:\\\\.|[^\\\\\'])*)\'|"((?:\\\\.|[^\\\\"])*)")|((?:\\\\.|[^\\\\()[\\]]|' + W + ')*)|.*)\\)|)', + B = new RegExp(M + '+', 'g'), + $ = new RegExp('^' + M + '+|((?:^|[^\\\\])(?:\\\\.)*)' + M + '+$', 'g'), + _ = new RegExp('^' + M + '*,' + M + '*'), + z = new RegExp('^' + M + '*([>+~]|' + M + ')' + M + '*'), + U = new RegExp(M + '|>'), + X = new RegExp(F), + V = new RegExp('^' + I + '$'), + G = { + ID: new RegExp('^#(' + I + ')'), + CLASS: new RegExp('^\\.(' + I + ')'), + TAG: new RegExp('^(' + I + '|[*])'), + ATTR: new RegExp('^' + W), + PSEUDO: new RegExp('^' + F), + CHILD: new RegExp( + '^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(' + + M + + '*(even|odd|(([+-]|)(\\d*)n|)' + + M + + '*(?:([+-]|)' + + M + + '*(\\d+)|))' + + M + + '*\\)|)', + 'i' + ), + bool: new RegExp('^(?:' + R + ')$', 'i'), + needsContext: new RegExp( + '^' + M + '*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(' + M + '*((?:-\\d)?\\d*)' + M + '*\\)|)(?=[^-]|$)', + 'i' + ), + }, + Y = /HTML$/i, + Q = /^(?:input|select|textarea|button)$/i, + J = /^h\d$/i, + K = /^[^{]+\{\s*\[native \w/, + Z = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + ee = /[+~]/, + te = new RegExp('\\\\[\\da-fA-F]{1,6}' + M + '?|\\\\([^\\r\\n\\f])', 'g'), + ne = function (e, t) { + var n = '0x' + e.slice(1) - 65536; + return t || (n < 0 ? String.fromCharCode(n + 65536) : String.fromCharCode((n >> 10) | 55296, (1023 & n) | 56320)); + }, + re = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, + ie = function (e, t) { + return t ? ('\0' === e ? '\ufffd' : e.slice(0, -1) + '\\' + e.charCodeAt(e.length - 1).toString(16) + ' ') : '\\' + e; + }, + oe = function () { + T(); + }, + ae = be( + function (e) { + return !0 === e.disabled && 'fieldset' === e.nodeName.toLowerCase(); + }, + { dir: 'parentNode', next: 'legend' } + ); + try { + H.apply((t = O.call(p.childNodes)), p.childNodes), t[p.childNodes.length].nodeType; + } catch (e) { + H = { + apply: t.length + ? function (e, t) { + L.apply(e, O.call(t)); + } + : function (e, t) { + var n = e.length, + r = 0; + while ((e[n++] = t[r++])); + e.length = n - 1; + }, + }; + } + function se(t, e, n, r) { + var i, + o, + a, + s, + u, + l, + c, + f = e && e.ownerDocument, + p = e ? e.nodeType : 9; + if (((n = n || []), 'string' != typeof t || !t || (1 !== p && 9 !== p && 11 !== p))) return n; + if (!r && (T(e), (e = e || C), E)) { + if (11 !== p && (u = Z.exec(t))) + if ((i = u[1])) { + if (9 === p) { + if (!(a = e.getElementById(i))) return n; + if (a.id === i) return n.push(a), n; + } else if (f && (a = f.getElementById(i)) && y(e, a) && a.id === i) return n.push(a), n; + } else { + if (u[2]) return H.apply(n, e.getElementsByTagName(t)), n; + if ((i = u[3]) && d.getElementsByClassName && e.getElementsByClassName) return H.apply(n, e.getElementsByClassName(i)), n; + } + if (d.qsa && !N[t + ' '] && (!v || !v.test(t)) && (1 !== p || 'object' !== e.nodeName.toLowerCase())) { + if (((c = t), (f = e), 1 === p && (U.test(t) || z.test(t)))) { + ((f = (ee.test(t) && ye(e.parentNode)) || e) === e && d.scope) || + ((s = e.getAttribute('id')) ? (s = s.replace(re, ie)) : e.setAttribute('id', (s = S))), + (o = (l = h(t)).length); + while (o--) l[o] = (s ? '#' + s : ':scope') + ' ' + xe(l[o]); + c = l.join(','); + } + try { + return H.apply(n, f.querySelectorAll(c)), n; + } catch (e) { + N(t, !0); + } finally { + s === S && e.removeAttribute('id'); + } + } + } + return g(t.replace($, '$1'), e, n, r); + } + function ue() { + var r = []; + return function e(t, n) { + return r.push(t + ' ') > b.cacheLength && delete e[r.shift()], (e[t + ' '] = n); + }; + } + function le(e) { + return (e[S] = !0), e; + } + function ce(e) { + var t = C.createElement('fieldset'); + try { + return !!e(t); + } catch (e) { + return !1; + } finally { + t.parentNode && t.parentNode.removeChild(t), (t = null); + } + } + function fe(e, t) { + var n = e.split('|'), + r = n.length; + while (r--) b.attrHandle[n[r]] = t; + } + function pe(e, t) { + var n = t && e, + r = n && 1 === e.nodeType && 1 === t.nodeType && e.sourceIndex - t.sourceIndex; + if (r) return r; + if (n) while ((n = n.nextSibling)) if (n === t) return -1; + return e ? 1 : -1; + } + function de(t) { + return function (e) { + return 'input' === e.nodeName.toLowerCase() && e.type === t; + }; + } + function he(n) { + return function (e) { + var t = e.nodeName.toLowerCase(); + return ('input' === t || 'button' === t) && e.type === n; + }; + } + function ge(t) { + return function (e) { + return 'form' in e + ? e.parentNode && !1 === e.disabled + ? 'label' in e + ? 'label' in e.parentNode + ? e.parentNode.disabled === t + : e.disabled === t + : e.isDisabled === t || (e.isDisabled !== !t && ae(e) === t) + : e.disabled === t + : 'label' in e && e.disabled === t; + }; + } + function ve(a) { + return le(function (o) { + return ( + (o = +o), + le(function (e, t) { + var n, + r = a([], e.length, o), + i = r.length; + while (i--) e[(n = r[i])] && (e[n] = !(t[n] = e[n])); + }) + ); + }); + } + function ye(e) { + return e && 'undefined' != typeof e.getElementsByTagName && e; + } + for (e in ((d = se.support = {}), + (i = se.isXML = + function (e) { + var t = e.namespaceURI, + n = (e.ownerDocument || e).documentElement; + return !Y.test(t || (n && n.nodeName) || 'HTML'); + }), + (T = se.setDocument = + function (e) { + var t, + n, + r = e ? e.ownerDocument || e : p; + return ( + r != C && + 9 === r.nodeType && + r.documentElement && + ((a = (C = r).documentElement), + (E = !i(C)), + p != C && + (n = C.defaultView) && + n.top !== n && + (n.addEventListener ? n.addEventListener('unload', oe, !1) : n.attachEvent && n.attachEvent('onunload', oe)), + (d.scope = ce(function (e) { + return ( + a.appendChild(e).appendChild(C.createElement('div')), + 'undefined' != typeof e.querySelectorAll && !e.querySelectorAll(':scope fieldset div').length + ); + })), + (d.attributes = ce(function (e) { + return (e.className = 'i'), !e.getAttribute('className'); + })), + (d.getElementsByTagName = ce(function (e) { + return e.appendChild(C.createComment('')), !e.getElementsByTagName('*').length; + })), + (d.getElementsByClassName = K.test(C.getElementsByClassName)), + (d.getById = ce(function (e) { + return (a.appendChild(e).id = S), !C.getElementsByName || !C.getElementsByName(S).length; + })), + d.getById + ? ((b.filter.ID = function (e) { + var t = e.replace(te, ne); + return function (e) { + return e.getAttribute('id') === t; + }; + }), + (b.find.ID = function (e, t) { + if ('undefined' != typeof t.getElementById && E) { + var n = t.getElementById(e); + return n ? [n] : []; + } + })) + : ((b.filter.ID = function (e) { + var n = e.replace(te, ne); + return function (e) { + var t = 'undefined' != typeof e.getAttributeNode && e.getAttributeNode('id'); + return t && t.value === n; + }; + }), + (b.find.ID = function (e, t) { + if ('undefined' != typeof t.getElementById && E) { + var n, + r, + i, + o = t.getElementById(e); + if (o) { + if ((n = o.getAttributeNode('id')) && n.value === e) return [o]; + (i = t.getElementsByName(e)), (r = 0); + while ((o = i[r++])) if ((n = o.getAttributeNode('id')) && n.value === e) return [o]; + } + return []; + } + })), + (b.find.TAG = d.getElementsByTagName + ? function (e, t) { + return 'undefined' != typeof t.getElementsByTagName ? t.getElementsByTagName(e) : d.qsa ? t.querySelectorAll(e) : void 0; + } + : function (e, t) { + var n, + r = [], + i = 0, + o = t.getElementsByTagName(e); + if ('*' === e) { + while ((n = o[i++])) 1 === n.nodeType && r.push(n); + return r; + } + return o; + }), + (b.find.CLASS = + d.getElementsByClassName && + function (e, t) { + if ('undefined' != typeof t.getElementsByClassName && E) return t.getElementsByClassName(e); + }), + (s = []), + (v = []), + (d.qsa = K.test(C.querySelectorAll)) && + (ce(function (e) { + var t; + (a.appendChild(e).innerHTML = + "<a id='" + S + "'></a><select id='" + S + "-\r\\' msallowcapture=''><option selected=''></option></select>"), + e.querySelectorAll("[msallowcapture^='']").length && v.push('[*^$]=' + M + '*(?:\'\'|"")'), + e.querySelectorAll('[selected]').length || v.push('\\[' + M + '*(?:value|' + R + ')'), + e.querySelectorAll('[id~=' + S + '-]').length || v.push('~='), + (t = C.createElement('input')).setAttribute('name', ''), + e.appendChild(t), + e.querySelectorAll("[name='']").length || v.push('\\[' + M + '*name' + M + '*=' + M + '*(?:\'\'|"")'), + e.querySelectorAll(':checked').length || v.push(':checked'), + e.querySelectorAll('a#' + S + '+*').length || v.push('.#.+[+~]'), + e.querySelectorAll('\\\f'), + v.push('[\\r\\n\\f]'); + }), + ce(function (e) { + e.innerHTML = "<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>"; + var t = C.createElement('input'); + t.setAttribute('type', 'hidden'), + e.appendChild(t).setAttribute('name', 'D'), + e.querySelectorAll('[name=d]').length && v.push('name' + M + '*[*^$|!~]?='), + 2 !== e.querySelectorAll(':enabled').length && v.push(':enabled', ':disabled'), + (a.appendChild(e).disabled = !0), + 2 !== e.querySelectorAll(':disabled').length && v.push(':enabled', ':disabled'), + e.querySelectorAll('*,:x'), + v.push(',.*:'); + })), + (d.matchesSelector = K.test( + (c = a.matches || a.webkitMatchesSelector || a.mozMatchesSelector || a.oMatchesSelector || a.msMatchesSelector) + )) && + ce(function (e) { + (d.disconnectedMatch = c.call(e, '*')), c.call(e, "[s!='']:x"), s.push('!=', F); + }), + (v = v.length && new RegExp(v.join('|'))), + (s = s.length && new RegExp(s.join('|'))), + (t = K.test(a.compareDocumentPosition)), + (y = + t || K.test(a.contains) + ? function (e, t) { + var n = 9 === e.nodeType ? e.documentElement : e, + r = t && t.parentNode; + return ( + e === r || + !( + !r || + 1 !== r.nodeType || + !(n.contains ? n.contains(r) : e.compareDocumentPosition && 16 & e.compareDocumentPosition(r)) + ) + ); + } + : function (e, t) { + if (t) while ((t = t.parentNode)) if (t === e) return !0; + return !1; + }), + (D = t + ? function (e, t) { + if (e === t) return (l = !0), 0; + var n = !e.compareDocumentPosition - !t.compareDocumentPosition; + return ( + n || + (1 & (n = (e.ownerDocument || e) == (t.ownerDocument || t) ? e.compareDocumentPosition(t) : 1) || + (!d.sortDetached && t.compareDocumentPosition(e) === n) + ? e == C || (e.ownerDocument == p && y(p, e)) + ? -1 + : t == C || (t.ownerDocument == p && y(p, t)) + ? 1 + : u + ? P(u, e) - P(u, t) + : 0 + : 4 & n + ? -1 + : 1) + ); + } + : function (e, t) { + if (e === t) return (l = !0), 0; + var n, + r = 0, + i = e.parentNode, + o = t.parentNode, + a = [e], + s = [t]; + if (!i || !o) return e == C ? -1 : t == C ? 1 : i ? -1 : o ? 1 : u ? P(u, e) - P(u, t) : 0; + if (i === o) return pe(e, t); + n = e; + while ((n = n.parentNode)) a.unshift(n); + n = t; + while ((n = n.parentNode)) s.unshift(n); + while (a[r] === s[r]) r++; + return r ? pe(a[r], s[r]) : a[r] == p ? -1 : s[r] == p ? 1 : 0; + })), + C + ); + }), + (se.matches = function (e, t) { + return se(e, null, null, t); + }), + (se.matchesSelector = function (e, t) { + if ((T(e), d.matchesSelector && E && !N[t + ' '] && (!s || !s.test(t)) && (!v || !v.test(t)))) + try { + var n = c.call(e, t); + if (n || d.disconnectedMatch || (e.document && 11 !== e.document.nodeType)) return n; + } catch (e) { + N(t, !0); + } + return 0 < se(t, C, null, [e]).length; + }), + (se.contains = function (e, t) { + return (e.ownerDocument || e) != C && T(e), y(e, t); + }), + (se.attr = function (e, t) { + (e.ownerDocument || e) != C && T(e); + var n = b.attrHandle[t.toLowerCase()], + r = n && j.call(b.attrHandle, t.toLowerCase()) ? n(e, t, !E) : void 0; + return void 0 !== r ? r : d.attributes || !E ? e.getAttribute(t) : (r = e.getAttributeNode(t)) && r.specified ? r.value : null; + }), + (se.escape = function (e) { + return (e + '').replace(re, ie); + }), + (se.error = function (e) { + throw new Error('Syntax error, unrecognized expression: ' + e); + }), + (se.uniqueSort = function (e) { + var t, + n = [], + r = 0, + i = 0; + if (((l = !d.detectDuplicates), (u = !d.sortStable && e.slice(0)), e.sort(D), l)) { + while ((t = e[i++])) t === e[i] && (r = n.push(i)); + while (r--) e.splice(n[r], 1); + } + return (u = null), e; + }), + (o = se.getText = + function (e) { + var t, + n = '', + r = 0, + i = e.nodeType; + if (i) { + if (1 === i || 9 === i || 11 === i) { + if ('string' == typeof e.textContent) return e.textContent; + for (e = e.firstChild; e; e = e.nextSibling) n += o(e); + } else if (3 === i || 4 === i) return e.nodeValue; + } else while ((t = e[r++])) n += o(t); + return n; + }), + ((b = se.selectors = + { + cacheLength: 50, + createPseudo: le, + match: G, + attrHandle: {}, + find: {}, + relative: { + '>': { dir: 'parentNode', first: !0 }, + ' ': { dir: 'parentNode' }, + '+': { dir: 'previousSibling', first: !0 }, + '~': { dir: 'previousSibling' }, + }, + preFilter: { + ATTR: function (e) { + return ( + (e[1] = e[1].replace(te, ne)), + (e[3] = (e[3] || e[4] || e[5] || '').replace(te, ne)), + '~=' === e[2] && (e[3] = ' ' + e[3] + ' '), + e.slice(0, 4) + ); + }, + CHILD: function (e) { + return ( + (e[1] = e[1].toLowerCase()), + 'nth' === e[1].slice(0, 3) + ? (e[3] || se.error(e[0]), + (e[4] = +(e[4] ? e[5] + (e[6] || 1) : 2 * ('even' === e[3] || 'odd' === e[3]))), + (e[5] = +(e[7] + e[8] || 'odd' === e[3]))) + : e[3] && se.error(e[0]), + e + ); + }, + PSEUDO: function (e) { + var t, + n = !e[6] && e[2]; + return G.CHILD.test(e[0]) + ? null + : (e[3] + ? (e[2] = e[4] || e[5] || '') + : n && + X.test(n) && + (t = h(n, !0)) && + (t = n.indexOf(')', n.length - t) - n.length) && + ((e[0] = e[0].slice(0, t)), (e[2] = n.slice(0, t))), + e.slice(0, 3)); + }, + }, + filter: { + TAG: function (e) { + var t = e.replace(te, ne).toLowerCase(); + return '*' === e + ? function () { + return !0; + } + : function (e) { + return e.nodeName && e.nodeName.toLowerCase() === t; + }; + }, + CLASS: function (e) { + var t = m[e + ' ']; + return ( + t || + ((t = new RegExp('(^|' + M + ')' + e + '(' + M + '|$)')) && + m(e, function (e) { + return t.test( + ('string' == typeof e.className && e.className) || + ('undefined' != typeof e.getAttribute && e.getAttribute('class')) || + '' + ); + })) + ); + }, + ATTR: function (n, r, i) { + return function (e) { + var t = se.attr(e, n); + return null == t + ? '!=' === r + : !r || + ((t += ''), + '=' === r + ? t === i + : '!=' === r + ? t !== i + : '^=' === r + ? i && 0 === t.indexOf(i) + : '*=' === r + ? i && -1 < t.indexOf(i) + : '$=' === r + ? i && t.slice(-i.length) === i + : '~=' === r + ? -1 < (' ' + t.replace(B, ' ') + ' ').indexOf(i) + : '|=' === r && (t === i || t.slice(0, i.length + 1) === i + '-')); + }; + }, + CHILD: function (h, e, t, g, v) { + var y = 'nth' !== h.slice(0, 3), + m = 'last' !== h.slice(-4), + x = 'of-type' === e; + return 1 === g && 0 === v + ? function (e) { + return !!e.parentNode; + } + : function (e, t, n) { + var r, + i, + o, + a, + s, + u, + l = y !== m ? 'nextSibling' : 'previousSibling', + c = e.parentNode, + f = x && e.nodeName.toLowerCase(), + p = !n && !x, + d = !1; + if (c) { + if (y) { + while (l) { + a = e; + while ((a = a[l])) if (x ? a.nodeName.toLowerCase() === f : 1 === a.nodeType) return !1; + u = l = 'only' === h && !u && 'nextSibling'; + } + return !0; + } + if (((u = [m ? c.firstChild : c.lastChild]), m && p)) { + (d = + (s = (r = (i = (o = (a = c)[S] || (a[S] = {}))[a.uniqueID] || (o[a.uniqueID] = {}))[h] || [])[0] === k && r[1]) && + r[2]), + (a = s && c.childNodes[s]); + while ((a = (++s && a && a[l]) || (d = s = 0) || u.pop())) + if (1 === a.nodeType && ++d && a === e) { + i[h] = [k, s, d]; + break; + } + } else if ( + (p && + (d = s = (r = (i = (o = (a = e)[S] || (a[S] = {}))[a.uniqueID] || (o[a.uniqueID] = {}))[h] || [])[0] === k && r[1]), + !1 === d) + ) + while ((a = (++s && a && a[l]) || (d = s = 0) || u.pop())) + if ( + (x ? a.nodeName.toLowerCase() === f : 1 === a.nodeType) && + ++d && + (p && ((i = (o = a[S] || (a[S] = {}))[a.uniqueID] || (o[a.uniqueID] = {}))[h] = [k, d]), a === e) + ) + break; + return (d -= v) === g || (d % g == 0 && 0 <= d / g); + } + }; + }, + PSEUDO: function (e, o) { + var t, + a = b.pseudos[e] || b.setFilters[e.toLowerCase()] || se.error('unsupported pseudo: ' + e); + return a[S] + ? a(o) + : 1 < a.length + ? ((t = [e, e, '', o]), + b.setFilters.hasOwnProperty(e.toLowerCase()) + ? le(function (e, t) { + var n, + r = a(e, o), + i = r.length; + while (i--) e[(n = P(e, r[i]))] = !(t[n] = r[i]); + }) + : function (e) { + return a(e, 0, t); + }) + : a; + }, + }, + pseudos: { + not: le(function (e) { + var r = [], + i = [], + s = f(e.replace($, '$1')); + return s[S] + ? le(function (e, t, n, r) { + var i, + o = s(e, null, r, []), + a = e.length; + while (a--) (i = o[a]) && (e[a] = !(t[a] = i)); + }) + : function (e, t, n) { + return (r[0] = e), s(r, null, n, i), (r[0] = null), !i.pop(); + }; + }), + has: le(function (t) { + return function (e) { + return 0 < se(t, e).length; + }; + }), + contains: le(function (t) { + return ( + (t = t.replace(te, ne)), + function (e) { + return -1 < (e.textContent || o(e)).indexOf(t); + } + ); + }), + lang: le(function (n) { + return ( + V.test(n || '') || se.error('unsupported lang: ' + n), + (n = n.replace(te, ne).toLowerCase()), + function (e) { + var t; + do { + if ((t = E ? e.lang : e.getAttribute('xml:lang') || e.getAttribute('lang'))) + return (t = t.toLowerCase()) === n || 0 === t.indexOf(n + '-'); + } while ((e = e.parentNode) && 1 === e.nodeType); + return !1; + } + ); + }), + target: function (e) { + var t = n.location && n.location.hash; + return t && t.slice(1) === e.id; + }, + root: function (e) { + return e === a; + }, + focus: function (e) { + return e === C.activeElement && (!C.hasFocus || C.hasFocus()) && !!(e.type || e.href || ~e.tabIndex); + }, + enabled: ge(!1), + disabled: ge(!0), + checked: function (e) { + var t = e.nodeName.toLowerCase(); + return ('input' === t && !!e.checked) || ('option' === t && !!e.selected); + }, + selected: function (e) { + return e.parentNode && e.parentNode.selectedIndex, !0 === e.selected; + }, + empty: function (e) { + for (e = e.firstChild; e; e = e.nextSibling) if (e.nodeType < 6) return !1; + return !0; + }, + parent: function (e) { + return !b.pseudos.empty(e); + }, + header: function (e) { + return J.test(e.nodeName); + }, + input: function (e) { + return Q.test(e.nodeName); + }, + button: function (e) { + var t = e.nodeName.toLowerCase(); + return ('input' === t && 'button' === e.type) || 'button' === t; + }, + text: function (e) { + var t; + return ( + 'input' === e.nodeName.toLowerCase() && + 'text' === e.type && + (null == (t = e.getAttribute('type')) || 'text' === t.toLowerCase()) + ); + }, + first: ve(function () { + return [0]; + }), + last: ve(function (e, t) { + return [t - 1]; + }), + eq: ve(function (e, t, n) { + return [n < 0 ? n + t : n]; + }), + even: ve(function (e, t) { + for (var n = 0; n < t; n += 2) e.push(n); + return e; + }), + odd: ve(function (e, t) { + for (var n = 1; n < t; n += 2) e.push(n); + return e; + }), + lt: ve(function (e, t, n) { + for (var r = n < 0 ? n + t : t < n ? t : n; 0 <= --r; ) e.push(r); + return e; + }), + gt: ve(function (e, t, n) { + for (var r = n < 0 ? n + t : n; ++r < t; ) e.push(r); + return e; + }), + }, + }).pseudos.nth = b.pseudos.eq), + { radio: !0, checkbox: !0, file: !0, password: !0, image: !0 })) + b.pseudos[e] = de(e); + for (e in { submit: !0, reset: !0 }) b.pseudos[e] = he(e); + function me() {} + function xe(e) { + for (var t = 0, n = e.length, r = ''; t < n; t++) r += e[t].value; + return r; + } + function be(s, e, t) { + var u = e.dir, + l = e.next, + c = l || u, + f = t && 'parentNode' === c, + p = r++; + return e.first + ? function (e, t, n) { + while ((e = e[u])) if (1 === e.nodeType || f) return s(e, t, n); + return !1; + } + : function (e, t, n) { + var r, + i, + o, + a = [k, p]; + if (n) { + while ((e = e[u])) if ((1 === e.nodeType || f) && s(e, t, n)) return !0; + } else + while ((e = e[u])) + if (1 === e.nodeType || f) + if (((i = (o = e[S] || (e[S] = {}))[e.uniqueID] || (o[e.uniqueID] = {})), l && l === e.nodeName.toLowerCase())) + e = e[u] || e; + else { + if ((r = i[c]) && r[0] === k && r[1] === p) return (a[2] = r[2]); + if (((i[c] = a)[2] = s(e, t, n))) return !0; + } + return !1; + }; + } + function we(i) { + return 1 < i.length + ? function (e, t, n) { + var r = i.length; + while (r--) if (!i[r](e, t, n)) return !1; + return !0; + } + : i[0]; + } + function Te(e, t, n, r, i) { + for (var o, a = [], s = 0, u = e.length, l = null != t; s < u; s++) (o = e[s]) && ((n && !n(o, r, i)) || (a.push(o), l && t.push(s))); + return a; + } + function Ce(d, h, g, v, y, e) { + return ( + v && !v[S] && (v = Ce(v)), + y && !y[S] && (y = Ce(y, e)), + le(function (e, t, n, r) { + var i, + o, + a, + s = [], + u = [], + l = t.length, + c = + e || + (function (e, t, n) { + for (var r = 0, i = t.length; r < i; r++) se(e, t[r], n); + return n; + })(h || '*', n.nodeType ? [n] : n, []), + f = !d || (!e && h) ? c : Te(c, s, d, n, r), + p = g ? (y || (e ? d : l || v) ? [] : t) : f; + if ((g && g(f, p, n, r), v)) { + (i = Te(p, u)), v(i, [], n, r), (o = i.length); + while (o--) (a = i[o]) && (p[u[o]] = !(f[u[o]] = a)); + } + if (e) { + if (y || d) { + if (y) { + (i = []), (o = p.length); + while (o--) (a = p[o]) && i.push((f[o] = a)); + y(null, (p = []), i, r); + } + o = p.length; + while (o--) (a = p[o]) && -1 < (i = y ? P(e, a) : s[o]) && (e[i] = !(t[i] = a)); + } + } else (p = Te(p === t ? p.splice(l, p.length) : p)), y ? y(null, t, p, r) : H.apply(t, p); + }) + ); + } + function Ee(e) { + for ( + var i, + t, + n, + r = e.length, + o = b.relative[e[0].type], + a = o || b.relative[' '], + s = o ? 1 : 0, + u = be( + function (e) { + return e === i; + }, + a, + !0 + ), + l = be( + function (e) { + return -1 < P(i, e); + }, + a, + !0 + ), + c = [ + function (e, t, n) { + var r = (!o && (n || t !== w)) || ((i = t).nodeType ? u(e, t, n) : l(e, t, n)); + return (i = null), r; + }, + ]; + s < r; + s++ + ) + if ((t = b.relative[e[s].type])) c = [be(we(c), t)]; + else { + if ((t = b.filter[e[s].type].apply(null, e[s].matches))[S]) { + for (n = ++s; n < r; n++) if (b.relative[e[n].type]) break; + return Ce( + 1 < s && we(c), + 1 < s && xe(e.slice(0, s - 1).concat({ value: ' ' === e[s - 2].type ? '*' : '' })).replace($, '$1'), + t, + s < n && Ee(e.slice(s, n)), + n < r && Ee((e = e.slice(n))), + n < r && xe(e) + ); + } + c.push(t); + } + return we(c); + } + return ( + (me.prototype = b.filters = b.pseudos), + (b.setFilters = new me()), + (h = se.tokenize = + function (e, t) { + var n, + r, + i, + o, + a, + s, + u, + l = x[e + ' ']; + if (l) return t ? 0 : l.slice(0); + (a = e), (s = []), (u = b.preFilter); + while (a) { + for (o in ((n && !(r = _.exec(a))) || (r && (a = a.slice(r[0].length) || a), s.push((i = []))), + (n = !1), + (r = z.exec(a)) && ((n = r.shift()), i.push({ value: n, type: r[0].replace($, ' ') }), (a = a.slice(n.length))), + b.filter)) + !(r = G[o].exec(a)) || + (u[o] && !(r = u[o](r))) || + ((n = r.shift()), i.push({ value: n, type: o, matches: r }), (a = a.slice(n.length))); + if (!n) break; + } + return t ? a.length : a ? se.error(e) : x(e, s).slice(0); + }), + (f = se.compile = + function (e, t) { + var n, + v, + y, + m, + x, + r, + i = [], + o = [], + a = A[e + ' ']; + if (!a) { + t || (t = h(e)), (n = t.length); + while (n--) (a = Ee(t[n]))[S] ? i.push(a) : o.push(a); + (a = A( + e, + ((v = o), + (m = 0 < (y = i).length), + (x = 0 < v.length), + (r = function (e, t, n, r, i) { + var o, + a, + s, + u = 0, + l = '0', + c = e && [], + f = [], + p = w, + d = e || (x && b.find.TAG('*', i)), + h = (k += null == p ? 1 : Math.random() || 0.1), + g = d.length; + for (i && (w = t == C || t || i); l !== g && null != (o = d[l]); l++) { + if (x && o) { + (a = 0), t || o.ownerDocument == C || (T(o), (n = !E)); + while ((s = v[a++])) + if (s(o, t || C, n)) { + r.push(o); + break; + } + i && (k = h); + } + m && ((o = !s && o) && u--, e && c.push(o)); + } + if (((u += l), m && l !== u)) { + a = 0; + while ((s = y[a++])) s(c, f, t, n); + if (e) { + if (0 < u) while (l--) c[l] || f[l] || (f[l] = q.call(r)); + f = Te(f); + } + H.apply(r, f), i && !e && 0 < f.length && 1 < u + y.length && se.uniqueSort(r); + } + return i && ((k = h), (w = p)), c; + }), + m ? le(r) : r) + )).selector = e; + } + return a; + }), + (g = se.select = + function (e, t, n, r) { + var i, + o, + a, + s, + u, + l = 'function' == typeof e && e, + c = !r && h((e = l.selector || e)); + if (((n = n || []), 1 === c.length)) { + if (2 < (o = c[0] = c[0].slice(0)).length && 'ID' === (a = o[0]).type && 9 === t.nodeType && E && b.relative[o[1].type]) { + if (!(t = (b.find.ID(a.matches[0].replace(te, ne), t) || [])[0])) return n; + l && (t = t.parentNode), (e = e.slice(o.shift().value.length)); + } + i = G.needsContext.test(e) ? 0 : o.length; + while (i--) { + if (((a = o[i]), b.relative[(s = a.type)])) break; + if ((u = b.find[s]) && (r = u(a.matches[0].replace(te, ne), (ee.test(o[0].type) && ye(t.parentNode)) || t))) { + if ((o.splice(i, 1), !(e = r.length && xe(o)))) return H.apply(n, r), n; + break; + } + } + } + return (l || f(e, c))(r, t, !E, n, !t || (ee.test(e) && ye(t.parentNode)) || t), n; + }), + (d.sortStable = S.split('').sort(D).join('') === S), + (d.detectDuplicates = !!l), + T(), + (d.sortDetached = ce(function (e) { + return 1 & e.compareDocumentPosition(C.createElement('fieldset')); + })), + ce(function (e) { + return (e.innerHTML = "<a href='#'></a>"), '#' === e.firstChild.getAttribute('href'); + }) || + fe('type|href|height|width', function (e, t, n) { + if (!n) return e.getAttribute(t, 'type' === t.toLowerCase() ? 1 : 2); + }), + (d.attributes && + ce(function (e) { + return (e.innerHTML = '<input/>'), e.firstChild.setAttribute('value', ''), '' === e.firstChild.getAttribute('value'); + })) || + fe('value', function (e, t, n) { + if (!n && 'input' === e.nodeName.toLowerCase()) return e.defaultValue; + }), + ce(function (e) { + return null == e.getAttribute('disabled'); + }) || + fe(R, function (e, t, n) { + var r; + if (!n) return !0 === e[t] ? t.toLowerCase() : (r = e.getAttributeNode(t)) && r.specified ? r.value : null; + }), + se + ); + })(C); + (S.find = d), + (S.expr = d.selectors), + (S.expr[':'] = S.expr.pseudos), + (S.uniqueSort = S.unique = d.uniqueSort), + (S.text = d.getText), + (S.isXMLDoc = d.isXML), + (S.contains = d.contains), + (S.escapeSelector = d.escape); + var h = function (e, t, n) { + var r = [], + i = void 0 !== n; + while ((e = e[t]) && 9 !== e.nodeType) + if (1 === e.nodeType) { + if (i && S(e).is(n)) break; + r.push(e); + } + return r; + }, + T = function (e, t) { + for (var n = []; e; e = e.nextSibling) 1 === e.nodeType && e !== t && n.push(e); + return n; + }, + k = S.expr.match.needsContext; + function A(e, t) { + return e.nodeName && e.nodeName.toLowerCase() === t.toLowerCase(); + } + var N = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i; + function D(e, n, r) { + return m(n) + ? S.grep(e, function (e, t) { + return !!n.call(e, t, e) !== r; + }) + : n.nodeType + ? S.grep(e, function (e) { + return (e === n) !== r; + }) + : 'string' != typeof n + ? S.grep(e, function (e) { + return -1 < i.call(n, e) !== r; + }) + : S.filter(n, e, r); + } + (S.filter = function (e, t, n) { + var r = t[0]; + return ( + n && (e = ':not(' + e + ')'), + 1 === t.length && 1 === r.nodeType + ? S.find.matchesSelector(r, e) + ? [r] + : [] + : S.find.matches( + e, + S.grep(t, function (e) { + return 1 === e.nodeType; + }) + ) + ); + }), + S.fn.extend({ + find: function (e) { + var t, + n, + r = this.length, + i = this; + if ('string' != typeof e) + return this.pushStack( + S(e).filter(function () { + for (t = 0; t < r; t++) if (S.contains(i[t], this)) return !0; + }) + ); + for (n = this.pushStack([]), t = 0; t < r; t++) S.find(e, i[t], n); + return 1 < r ? S.uniqueSort(n) : n; + }, + filter: function (e) { + return this.pushStack(D(this, e || [], !1)); + }, + not: function (e) { + return this.pushStack(D(this, e || [], !0)); + }, + is: function (e) { + return !!D(this, 'string' == typeof e && k.test(e) ? S(e) : e || [], !1).length; + }, + }); + var j, + q = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/; + ((S.fn.init = function (e, t, n) { + var r, i; + if (!e) return this; + if (((n = n || j), 'string' == typeof e)) { + if (!(r = '<' === e[0] && '>' === e[e.length - 1] && 3 <= e.length ? [null, e, null] : q.exec(e)) || (!r[1] && t)) + return !t || t.jquery ? (t || n).find(e) : this.constructor(t).find(e); + if (r[1]) { + if ( + ((t = t instanceof S ? t[0] : t), + S.merge(this, S.parseHTML(r[1], t && t.nodeType ? t.ownerDocument || t : E, !0)), + N.test(r[1]) && S.isPlainObject(t)) + ) + for (r in t) m(this[r]) ? this[r](t[r]) : this.attr(r, t[r]); + return this; + } + return (i = E.getElementById(r[2])) && ((this[0] = i), (this.length = 1)), this; + } + return e.nodeType ? ((this[0] = e), (this.length = 1), this) : m(e) ? (void 0 !== n.ready ? n.ready(e) : e(S)) : S.makeArray(e, this); + }).prototype = S.fn), + (j = S(E)); + var L = /^(?:parents|prev(?:Until|All))/, + H = { children: !0, contents: !0, next: !0, prev: !0 }; + function O(e, t) { + while ((e = e[t]) && 1 !== e.nodeType); + return e; + } + S.fn.extend({ + has: function (e) { + var t = S(e, this), + n = t.length; + return this.filter(function () { + for (var e = 0; e < n; e++) if (S.contains(this, t[e])) return !0; + }); + }, + closest: function (e, t) { + var n, + r = 0, + i = this.length, + o = [], + a = 'string' != typeof e && S(e); + if (!k.test(e)) + for (; r < i; r++) + for (n = this[r]; n && n !== t; n = n.parentNode) + if (n.nodeType < 11 && (a ? -1 < a.index(n) : 1 === n.nodeType && S.find.matchesSelector(n, e))) { + o.push(n); + break; + } + return this.pushStack(1 < o.length ? S.uniqueSort(o) : o); + }, + index: function (e) { + return e + ? 'string' == typeof e + ? i.call(S(e), this[0]) + : i.call(this, e.jquery ? e[0] : e) + : this[0] && this[0].parentNode + ? this.first().prevAll().length + : -1; + }, + add: function (e, t) { + return this.pushStack(S.uniqueSort(S.merge(this.get(), S(e, t)))); + }, + addBack: function (e) { + return this.add(null == e ? this.prevObject : this.prevObject.filter(e)); + }, + }), + S.each( + { + parent: function (e) { + var t = e.parentNode; + return t && 11 !== t.nodeType ? t : null; + }, + parents: function (e) { + return h(e, 'parentNode'); + }, + parentsUntil: function (e, t, n) { + return h(e, 'parentNode', n); + }, + next: function (e) { + return O(e, 'nextSibling'); + }, + prev: function (e) { + return O(e, 'previousSibling'); + }, + nextAll: function (e) { + return h(e, 'nextSibling'); + }, + prevAll: function (e) { + return h(e, 'previousSibling'); + }, + nextUntil: function (e, t, n) { + return h(e, 'nextSibling', n); + }, + prevUntil: function (e, t, n) { + return h(e, 'previousSibling', n); + }, + siblings: function (e) { + return T((e.parentNode || {}).firstChild, e); + }, + children: function (e) { + return T(e.firstChild); + }, + contents: function (e) { + return null != e.contentDocument && r(e.contentDocument) + ? e.contentDocument + : (A(e, 'template') && (e = e.content || e), S.merge([], e.childNodes)); + }, + }, + function (r, i) { + S.fn[r] = function (e, t) { + var n = S.map(this, i, e); + return ( + 'Until' !== r.slice(-5) && (t = e), + t && 'string' == typeof t && (n = S.filter(t, n)), + 1 < this.length && (H[r] || S.uniqueSort(n), L.test(r) && n.reverse()), + this.pushStack(n) + ); + }; + } + ); + var P = /[^\x20\t\r\n\f]+/g; + function R(e) { + return e; + } + function M(e) { + throw e; + } + function I(e, t, n, r) { + var i; + try { + e && m((i = e.promise)) ? i.call(e).done(t).fail(n) : e && m((i = e.then)) ? i.call(e, t, n) : t.apply(void 0, [e].slice(r)); + } catch (e) { + n.apply(void 0, [e]); + } + } + (S.Callbacks = function (r) { + var e, n; + r = + 'string' == typeof r + ? ((e = r), + (n = {}), + S.each(e.match(P) || [], function (e, t) { + n[t] = !0; + }), + n) + : S.extend({}, r); + var i, + t, + o, + a, + s = [], + u = [], + l = -1, + c = function () { + for (a = a || r.once, o = i = !0; u.length; l = -1) { + t = u.shift(); + while (++l < s.length) !1 === s[l].apply(t[0], t[1]) && r.stopOnFalse && ((l = s.length), (t = !1)); + } + r.memory || (t = !1), (i = !1), a && (s = t ? [] : ''); + }, + f = { + add: function () { + return ( + s && + (t && !i && ((l = s.length - 1), u.push(t)), + (function n(e) { + S.each(e, function (e, t) { + m(t) ? (r.unique && f.has(t)) || s.push(t) : t && t.length && 'string' !== w(t) && n(t); + }); + })(arguments), + t && !i && c()), + this + ); + }, + remove: function () { + return ( + S.each(arguments, function (e, t) { + var n; + while (-1 < (n = S.inArray(t, s, n))) s.splice(n, 1), n <= l && l--; + }), + this + ); + }, + has: function (e) { + return e ? -1 < S.inArray(e, s) : 0 < s.length; + }, + empty: function () { + return s && (s = []), this; + }, + disable: function () { + return (a = u = []), (s = t = ''), this; + }, + disabled: function () { + return !s; + }, + lock: function () { + return (a = u = []), t || i || (s = t = ''), this; + }, + locked: function () { + return !!a; + }, + fireWith: function (e, t) { + return a || ((t = [e, (t = t || []).slice ? t.slice() : t]), u.push(t), i || c()), this; + }, + fire: function () { + return f.fireWith(this, arguments), this; + }, + fired: function () { + return !!o; + }, + }; + return f; + }), + S.extend({ + Deferred: function (e) { + var o = [ + ['notify', 'progress', S.Callbacks('memory'), S.Callbacks('memory'), 2], + ['resolve', 'done', S.Callbacks('once memory'), S.Callbacks('once memory'), 0, 'resolved'], + ['reject', 'fail', S.Callbacks('once memory'), S.Callbacks('once memory'), 1, 'rejected'], + ], + i = 'pending', + a = { + state: function () { + return i; + }, + always: function () { + return s.done(arguments).fail(arguments), this; + }, + catch: function (e) { + return a.then(null, e); + }, + pipe: function () { + var i = arguments; + return S.Deferred(function (r) { + S.each(o, function (e, t) { + var n = m(i[t[4]]) && i[t[4]]; + s[t[1]](function () { + var e = n && n.apply(this, arguments); + e && m(e.promise) + ? e.promise().progress(r.notify).done(r.resolve).fail(r.reject) + : r[t[0] + 'With'](this, n ? [e] : arguments); + }); + }), + (i = null); + }).promise(); + }, + then: function (t, n, r) { + var u = 0; + function l(i, o, a, s) { + return function () { + var n = this, + r = arguments, + e = function () { + var e, t; + if (!(i < u)) { + if ((e = a.apply(n, r)) === o.promise()) throw new TypeError('Thenable self-resolution'); + (t = e && ('object' == typeof e || 'function' == typeof e) && e.then), + m(t) + ? s + ? t.call(e, l(u, o, R, s), l(u, o, M, s)) + : (u++, t.call(e, l(u, o, R, s), l(u, o, M, s), l(u, o, R, o.notifyWith))) + : (a !== R && ((n = void 0), (r = [e])), (s || o.resolveWith)(n, r)); + } + }, + t = s + ? e + : function () { + try { + e(); + } catch (e) { + S.Deferred.exceptionHook && S.Deferred.exceptionHook(e, t.stackTrace), + u <= i + 1 && (a !== M && ((n = void 0), (r = [e])), o.rejectWith(n, r)); + } + }; + i ? t() : (S.Deferred.getStackHook && (t.stackTrace = S.Deferred.getStackHook()), C.setTimeout(t)); + }; + } + return S.Deferred(function (e) { + o[0][3].add(l(0, e, m(r) ? r : R, e.notifyWith)), o[1][3].add(l(0, e, m(t) ? t : R)), o[2][3].add(l(0, e, m(n) ? n : M)); + }).promise(); + }, + promise: function (e) { + return null != e ? S.extend(e, a) : a; + }, + }, + s = {}; + return ( + S.each(o, function (e, t) { + var n = t[2], + r = t[5]; + (a[t[1]] = n.add), + r && + n.add( + function () { + i = r; + }, + o[3 - e][2].disable, + o[3 - e][3].disable, + o[0][2].lock, + o[0][3].lock + ), + n.add(t[3].fire), + (s[t[0]] = function () { + return s[t[0] + 'With'](this === s ? void 0 : this, arguments), this; + }), + (s[t[0] + 'With'] = n.fireWith); + }), + a.promise(s), + e && e.call(s, s), + s + ); + }, + when: function (e) { + var n = arguments.length, + t = n, + r = Array(t), + i = s.call(arguments), + o = S.Deferred(), + a = function (t) { + return function (e) { + (r[t] = this), (i[t] = 1 < arguments.length ? s.call(arguments) : e), --n || o.resolveWith(r, i); + }; + }; + if (n <= 1 && (I(e, o.done(a(t)).resolve, o.reject, !n), 'pending' === o.state() || m(i[t] && i[t].then))) return o.then(); + while (t--) I(i[t], a(t), o.reject); + return o.promise(); + }, + }); + var W = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; + (S.Deferred.exceptionHook = function (e, t) { + C.console && C.console.warn && e && W.test(e.name) && C.console.warn('jQuery.Deferred exception: ' + e.message, e.stack, t); + }), + (S.readyException = function (e) { + C.setTimeout(function () { + throw e; + }); + }); + var F = S.Deferred(); + function B() { + E.removeEventListener('DOMContentLoaded', B), C.removeEventListener('load', B), S.ready(); + } + (S.fn.ready = function (e) { + return ( + F.then(e)['catch'](function (e) { + S.readyException(e); + }), + this + ); + }), + S.extend({ + isReady: !1, + readyWait: 1, + ready: function (e) { + (!0 === e ? --S.readyWait : S.isReady) || ((S.isReady = !0) !== e && 0 < --S.readyWait) || F.resolveWith(E, [S]); + }, + }), + (S.ready.then = F.then), + 'complete' === E.readyState || ('loading' !== E.readyState && !E.documentElement.doScroll) + ? C.setTimeout(S.ready) + : (E.addEventListener('DOMContentLoaded', B), C.addEventListener('load', B)); + var $ = function (e, t, n, r, i, o, a) { + var s = 0, + u = e.length, + l = null == n; + if ('object' === w(n)) for (s in ((i = !0), n)) $(e, t, s, n[s], !0, o, a); + else if ( + void 0 !== r && + ((i = !0), + m(r) || (a = !0), + l && + (a + ? (t.call(e, r), (t = null)) + : ((l = t), + (t = function (e, t, n) { + return l.call(S(e), n); + }))), + t) + ) + for (; s < u; s++) t(e[s], n, a ? r : r.call(e[s], s, t(e[s], n))); + return i ? e : l ? t.call(e) : u ? t(e[0], n) : o; + }, + _ = /^-ms-/, + z = /-([a-z])/g; + function U(e, t) { + return t.toUpperCase(); + } + function X(e) { + return e.replace(_, 'ms-').replace(z, U); + } + var V = function (e) { + return 1 === e.nodeType || 9 === e.nodeType || !+e.nodeType; + }; + function G() { + this.expando = S.expando + G.uid++; + } + (G.uid = 1), + (G.prototype = { + cache: function (e) { + var t = e[this.expando]; + return ( + t || + ((t = {}), + V(e) && (e.nodeType ? (e[this.expando] = t) : Object.defineProperty(e, this.expando, { value: t, configurable: !0 }))), + t + ); + }, + set: function (e, t, n) { + var r, + i = this.cache(e); + if ('string' == typeof t) i[X(t)] = n; + else for (r in t) i[X(r)] = t[r]; + return i; + }, + get: function (e, t) { + return void 0 === t ? this.cache(e) : e[this.expando] && e[this.expando][X(t)]; + }, + access: function (e, t, n) { + return void 0 === t || (t && 'string' == typeof t && void 0 === n) ? this.get(e, t) : (this.set(e, t, n), void 0 !== n ? n : t); + }, + remove: function (e, t) { + var n, + r = e[this.expando]; + if (void 0 !== r) { + if (void 0 !== t) { + n = (t = Array.isArray(t) ? t.map(X) : (t = X(t)) in r ? [t] : t.match(P) || []).length; + while (n--) delete r[t[n]]; + } + (void 0 === t || S.isEmptyObject(r)) && (e.nodeType ? (e[this.expando] = void 0) : delete e[this.expando]); + } + }, + hasData: function (e) { + var t = e[this.expando]; + return void 0 !== t && !S.isEmptyObject(t); + }, + }); + var Y = new G(), + Q = new G(), + J = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + K = /[A-Z]/g; + function Z(e, t, n) { + var r, i; + if (void 0 === n && 1 === e.nodeType) + if (((r = 'data-' + t.replace(K, '-$&').toLowerCase()), 'string' == typeof (n = e.getAttribute(r)))) { + try { + n = 'true' === (i = n) || ('false' !== i && ('null' === i ? null : i === +i + '' ? +i : J.test(i) ? JSON.parse(i) : i)); + } catch (e) {} + Q.set(e, t, n); + } else n = void 0; + return n; + } + S.extend({ + hasData: function (e) { + return Q.hasData(e) || Y.hasData(e); + }, + data: function (e, t, n) { + return Q.access(e, t, n); + }, + removeData: function (e, t) { + Q.remove(e, t); + }, + _data: function (e, t, n) { + return Y.access(e, t, n); + }, + _removeData: function (e, t) { + Y.remove(e, t); + }, + }), + S.fn.extend({ + data: function (n, e) { + var t, + r, + i, + o = this[0], + a = o && o.attributes; + if (void 0 === n) { + if (this.length && ((i = Q.get(o)), 1 === o.nodeType && !Y.get(o, 'hasDataAttrs'))) { + t = a.length; + while (t--) a[t] && 0 === (r = a[t].name).indexOf('data-') && ((r = X(r.slice(5))), Z(o, r, i[r])); + Y.set(o, 'hasDataAttrs', !0); + } + return i; + } + return 'object' == typeof n + ? this.each(function () { + Q.set(this, n); + }) + : $( + this, + function (e) { + var t; + if (o && void 0 === e) return void 0 !== (t = Q.get(o, n)) ? t : void 0 !== (t = Z(o, n)) ? t : void 0; + this.each(function () { + Q.set(this, n, e); + }); + }, + null, + e, + 1 < arguments.length, + null, + !0 + ); + }, + removeData: function (e) { + return this.each(function () { + Q.remove(this, e); + }); + }, + }), + S.extend({ + queue: function (e, t, n) { + var r; + if (e) + return ( + (t = (t || 'fx') + 'queue'), + (r = Y.get(e, t)), + n && (!r || Array.isArray(n) ? (r = Y.access(e, t, S.makeArray(n))) : r.push(n)), + r || [] + ); + }, + dequeue: function (e, t) { + t = t || 'fx'; + var n = S.queue(e, t), + r = n.length, + i = n.shift(), + o = S._queueHooks(e, t); + 'inprogress' === i && ((i = n.shift()), r--), + i && + ('fx' === t && n.unshift('inprogress'), + delete o.stop, + i.call( + e, + function () { + S.dequeue(e, t); + }, + o + )), + !r && o && o.empty.fire(); + }, + _queueHooks: function (e, t) { + var n = t + 'queueHooks'; + return ( + Y.get(e, n) || + Y.access(e, n, { + empty: S.Callbacks('once memory').add(function () { + Y.remove(e, [t + 'queue', n]); + }), + }) + ); + }, + }), + S.fn.extend({ + queue: function (t, n) { + var e = 2; + return ( + 'string' != typeof t && ((n = t), (t = 'fx'), e--), + arguments.length < e + ? S.queue(this[0], t) + : void 0 === n + ? this + : this.each(function () { + var e = S.queue(this, t, n); + S._queueHooks(this, t), 'fx' === t && 'inprogress' !== e[0] && S.dequeue(this, t); + }) + ); + }, + dequeue: function (e) { + return this.each(function () { + S.dequeue(this, e); + }); + }, + clearQueue: function (e) { + return this.queue(e || 'fx', []); + }, + promise: function (e, t) { + var n, + r = 1, + i = S.Deferred(), + o = this, + a = this.length, + s = function () { + --r || i.resolveWith(o, [o]); + }; + 'string' != typeof e && ((t = e), (e = void 0)), (e = e || 'fx'); + while (a--) (n = Y.get(o[a], e + 'queueHooks')) && n.empty && (r++, n.empty.add(s)); + return s(), i.promise(t); + }, + }); + var ee = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, + te = new RegExp('^(?:([+-])=|)(' + ee + ')([a-z%]*)$', 'i'), + ne = ['Top', 'Right', 'Bottom', 'Left'], + re = E.documentElement, + ie = function (e) { + return S.contains(e.ownerDocument, e); + }, + oe = { composed: !0 }; + re.getRootNode && + (ie = function (e) { + return S.contains(e.ownerDocument, e) || e.getRootNode(oe) === e.ownerDocument; + }); + var ae = function (e, t) { + return 'none' === (e = t || e).style.display || ('' === e.style.display && ie(e) && 'none' === S.css(e, 'display')); + }; + function se(e, t, n, r) { + var i, + o, + a = 20, + s = r + ? function () { + return r.cur(); + } + : function () { + return S.css(e, t, ''); + }, + u = s(), + l = (n && n[3]) || (S.cssNumber[t] ? '' : 'px'), + c = e.nodeType && (S.cssNumber[t] || ('px' !== l && +u)) && te.exec(S.css(e, t)); + if (c && c[3] !== l) { + (u /= 2), (l = l || c[3]), (c = +u || 1); + while (a--) S.style(e, t, c + l), (1 - o) * (1 - (o = s() / u || 0.5)) <= 0 && (a = 0), (c /= o); + (c *= 2), S.style(e, t, c + l), (n = n || []); + } + return n && ((c = +c || +u || 0), (i = n[1] ? c + (n[1] + 1) * n[2] : +n[2]), r && ((r.unit = l), (r.start = c), (r.end = i))), i; + } + var ue = {}; + function le(e, t) { + for (var n, r, i, o, a, s, u, l = [], c = 0, f = e.length; c < f; c++) + (r = e[c]).style && + ((n = r.style.display), + t + ? ('none' === n && ((l[c] = Y.get(r, 'display') || null), l[c] || (r.style.display = '')), + '' === r.style.display && + ae(r) && + (l[c] = + ((u = a = o = void 0), + (a = (i = r).ownerDocument), + (s = i.nodeName), + (u = ue[s]) || + ((o = a.body.appendChild(a.createElement(s))), + (u = S.css(o, 'display')), + o.parentNode.removeChild(o), + 'none' === u && (u = 'block'), + (ue[s] = u))))) + : 'none' !== n && ((l[c] = 'none'), Y.set(r, 'display', n))); + for (c = 0; c < f; c++) null != l[c] && (e[c].style.display = l[c]); + return e; + } + S.fn.extend({ + show: function () { + return le(this, !0); + }, + hide: function () { + return le(this); + }, + toggle: function (e) { + return 'boolean' == typeof e + ? e + ? this.show() + : this.hide() + : this.each(function () { + ae(this) ? S(this).show() : S(this).hide(); + }); + }, + }); + var ce, + fe, + pe = /^(?:checkbox|radio)$/i, + de = /<([a-z][^\/\0>\x20\t\r\n\f]*)/i, + he = /^$|^module$|\/(?:java|ecma)script/i; + (ce = E.createDocumentFragment().appendChild(E.createElement('div'))), + (fe = E.createElement('input')).setAttribute('type', 'radio'), + fe.setAttribute('checked', 'checked'), + fe.setAttribute('name', 't'), + ce.appendChild(fe), + (y.checkClone = ce.cloneNode(!0).cloneNode(!0).lastChild.checked), + (ce.innerHTML = '<textarea>x</textarea>'), + (y.noCloneChecked = !!ce.cloneNode(!0).lastChild.defaultValue), + (ce.innerHTML = '<option></option>'), + (y.option = !!ce.lastChild); + var ge = { + thead: [1, '<table>', '</table>'], + col: [2, '<table><colgroup>', '</colgroup></table>'], + tr: [2, '<table><tbody>', '</tbody></table>'], + td: [3, '<table><tbody><tr>', '</tr></tbody></table>'], + _default: [0, '', ''], + }; + function ve(e, t) { + var n; + return ( + (n = + 'undefined' != typeof e.getElementsByTagName + ? e.getElementsByTagName(t || '*') + : 'undefined' != typeof e.querySelectorAll + ? e.querySelectorAll(t || '*') + : []), + void 0 === t || (t && A(e, t)) ? S.merge([e], n) : n + ); + } + function ye(e, t) { + for (var n = 0, r = e.length; n < r; n++) Y.set(e[n], 'globalEval', !t || Y.get(t[n], 'globalEval')); + } + (ge.tbody = ge.tfoot = ge.colgroup = ge.caption = ge.thead), + (ge.th = ge.td), + y.option || (ge.optgroup = ge.option = [1, "<select multiple='multiple'>", '</select>']); + var me = /<|&#?\w+;/; + function xe(e, t, n, r, i) { + for (var o, a, s, u, l, c, f = t.createDocumentFragment(), p = [], d = 0, h = e.length; d < h; d++) + if ((o = e[d]) || 0 === o) + if ('object' === w(o)) S.merge(p, o.nodeType ? [o] : o); + else if (me.test(o)) { + (a = a || f.appendChild(t.createElement('div'))), + (s = (de.exec(o) || ['', ''])[1].toLowerCase()), + (u = ge[s] || ge._default), + (a.innerHTML = u[1] + S.htmlPrefilter(o) + u[2]), + (c = u[0]); + while (c--) a = a.lastChild; + S.merge(p, a.childNodes), ((a = f.firstChild).textContent = ''); + } else p.push(t.createTextNode(o)); + (f.textContent = ''), (d = 0); + while ((o = p[d++])) + if (r && -1 < S.inArray(o, r)) i && i.push(o); + else if (((l = ie(o)), (a = ve(f.appendChild(o), 'script')), l && ye(a), n)) { + c = 0; + while ((o = a[c++])) he.test(o.type || '') && n.push(o); + } + return f; + } + var be = /^key/, + we = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, + Te = /^([^.]*)(?:\.(.+)|)/; + function Ce() { + return !0; + } + function Ee() { + return !1; + } + function Se(e, t) { + return ( + (e === + (function () { + try { + return E.activeElement; + } catch (e) {} + })()) == + ('focus' === t) + ); + } + function ke(e, t, n, r, i, o) { + var a, s; + if ('object' == typeof t) { + for (s in ('string' != typeof n && ((r = r || n), (n = void 0)), t)) ke(e, s, n, r, t[s], o); + return e; + } + if ( + (null == r && null == i + ? ((i = n), (r = n = void 0)) + : null == i && ('string' == typeof n ? ((i = r), (r = void 0)) : ((i = r), (r = n), (n = void 0))), + !1 === i) + ) + i = Ee; + else if (!i) return e; + return ( + 1 === o && + ((a = i), + ((i = function (e) { + return S().off(e), a.apply(this, arguments); + }).guid = a.guid || (a.guid = S.guid++))), + e.each(function () { + S.event.add(this, t, i, r, n); + }) + ); + } + function Ae(e, i, o) { + o + ? (Y.set(e, i, !1), + S.event.add(e, i, { + namespace: !1, + handler: function (e) { + var t, + n, + r = Y.get(this, i); + if (1 & e.isTrigger && this[i]) { + if (r.length) (S.event.special[i] || {}).delegateType && e.stopPropagation(); + else if ( + ((r = s.call(arguments)), + Y.set(this, i, r), + (t = o(this, i)), + this[i](), + r !== (n = Y.get(this, i)) || t ? Y.set(this, i, !1) : (n = {}), + r !== n) + ) + return e.stopImmediatePropagation(), e.preventDefault(), n.value; + } else + r.length && + (Y.set(this, i, { value: S.event.trigger(S.extend(r[0], S.Event.prototype), r.slice(1), this) }), + e.stopImmediatePropagation()); + }, + })) + : void 0 === Y.get(e, i) && S.event.add(e, i, Ce); + } + (S.event = { + global: {}, + add: function (t, e, n, r, i) { + var o, + a, + s, + u, + l, + c, + f, + p, + d, + h, + g, + v = Y.get(t); + if (V(t)) { + n.handler && ((n = (o = n).handler), (i = o.selector)), + i && S.find.matchesSelector(re, i), + n.guid || (n.guid = S.guid++), + (u = v.events) || (u = v.events = Object.create(null)), + (a = v.handle) || + (a = v.handle = + function (e) { + return 'undefined' != typeof S && S.event.triggered !== e.type ? S.event.dispatch.apply(t, arguments) : void 0; + }), + (l = (e = (e || '').match(P) || ['']).length); + while (l--) + (d = g = (s = Te.exec(e[l]) || [])[1]), + (h = (s[2] || '').split('.').sort()), + d && + ((f = S.event.special[d] || {}), + (d = (i ? f.delegateType : f.bindType) || d), + (f = S.event.special[d] || {}), + (c = S.extend( + { + type: d, + origType: g, + data: r, + handler: n, + guid: n.guid, + selector: i, + needsContext: i && S.expr.match.needsContext.test(i), + namespace: h.join('.'), + }, + o + )), + (p = u[d]) || + (((p = u[d] = []).delegateCount = 0), + (f.setup && !1 !== f.setup.call(t, r, h, a)) || (t.addEventListener && t.addEventListener(d, a))), + f.add && (f.add.call(t, c), c.handler.guid || (c.handler.guid = n.guid)), + i ? p.splice(p.delegateCount++, 0, c) : p.push(c), + (S.event.global[d] = !0)); + } + }, + remove: function (e, t, n, r, i) { + var o, + a, + s, + u, + l, + c, + f, + p, + d, + h, + g, + v = Y.hasData(e) && Y.get(e); + if (v && (u = v.events)) { + l = (t = (t || '').match(P) || ['']).length; + while (l--) + if (((d = g = (s = Te.exec(t[l]) || [])[1]), (h = (s[2] || '').split('.').sort()), d)) { + (f = S.event.special[d] || {}), + (p = u[(d = (r ? f.delegateType : f.bindType) || d)] || []), + (s = s[2] && new RegExp('(^|\\.)' + h.join('\\.(?:.*\\.|)') + '(\\.|$)')), + (a = o = p.length); + while (o--) + (c = p[o]), + (!i && g !== c.origType) || + (n && n.guid !== c.guid) || + (s && !s.test(c.namespace)) || + (r && r !== c.selector && ('**' !== r || !c.selector)) || + (p.splice(o, 1), c.selector && p.delegateCount--, f.remove && f.remove.call(e, c)); + a && !p.length && ((f.teardown && !1 !== f.teardown.call(e, h, v.handle)) || S.removeEvent(e, d, v.handle), delete u[d]); + } else for (d in u) S.event.remove(e, d + t[l], n, r, !0); + S.isEmptyObject(u) && Y.remove(e, 'handle events'); + } + }, + dispatch: function (e) { + var t, + n, + r, + i, + o, + a, + s = new Array(arguments.length), + u = S.event.fix(e), + l = (Y.get(this, 'events') || Object.create(null))[u.type] || [], + c = S.event.special[u.type] || {}; + for (s[0] = u, t = 1; t < arguments.length; t++) s[t] = arguments[t]; + if (((u.delegateTarget = this), !c.preDispatch || !1 !== c.preDispatch.call(this, u))) { + (a = S.event.handlers.call(this, u, l)), (t = 0); + while ((i = a[t++]) && !u.isPropagationStopped()) { + (u.currentTarget = i.elem), (n = 0); + while ((o = i.handlers[n++]) && !u.isImmediatePropagationStopped()) + (u.rnamespace && !1 !== o.namespace && !u.rnamespace.test(o.namespace)) || + ((u.handleObj = o), + (u.data = o.data), + void 0 !== (r = ((S.event.special[o.origType] || {}).handle || o.handler).apply(i.elem, s)) && + !1 === (u.result = r) && + (u.preventDefault(), u.stopPropagation())); + } + return c.postDispatch && c.postDispatch.call(this, u), u.result; + } + }, + handlers: function (e, t) { + var n, + r, + i, + o, + a, + s = [], + u = t.delegateCount, + l = e.target; + if (u && l.nodeType && !('click' === e.type && 1 <= e.button)) + for (; l !== this; l = l.parentNode || this) + if (1 === l.nodeType && ('click' !== e.type || !0 !== l.disabled)) { + for (o = [], a = {}, n = 0; n < u; n++) + void 0 === a[(i = (r = t[n]).selector + ' ')] && + (a[i] = r.needsContext ? -1 < S(i, this).index(l) : S.find(i, this, null, [l]).length), + a[i] && o.push(r); + o.length && s.push({ elem: l, handlers: o }); + } + return (l = this), u < t.length && s.push({ elem: l, handlers: t.slice(u) }), s; + }, + addProp: function (t, e) { + Object.defineProperty(S.Event.prototype, t, { + enumerable: !0, + configurable: !0, + get: m(e) + ? function () { + if (this.originalEvent) return e(this.originalEvent); + } + : function () { + if (this.originalEvent) return this.originalEvent[t]; + }, + set: function (e) { + Object.defineProperty(this, t, { enumerable: !0, configurable: !0, writable: !0, value: e }); + }, + }); + }, + fix: function (e) { + return e[S.expando] ? e : new S.Event(e); + }, + special: { + load: { noBubble: !0 }, + click: { + setup: function (e) { + var t = this || e; + return pe.test(t.type) && t.click && A(t, 'input') && Ae(t, 'click', Ce), !1; + }, + trigger: function (e) { + var t = this || e; + return pe.test(t.type) && t.click && A(t, 'input') && Ae(t, 'click'), !0; + }, + _default: function (e) { + var t = e.target; + return (pe.test(t.type) && t.click && A(t, 'input') && Y.get(t, 'click')) || A(t, 'a'); + }, + }, + beforeunload: { + postDispatch: function (e) { + void 0 !== e.result && e.originalEvent && (e.originalEvent.returnValue = e.result); + }, + }, + }, + }), + (S.removeEvent = function (e, t, n) { + e.removeEventListener && e.removeEventListener(t, n); + }), + (S.Event = function (e, t) { + if (!(this instanceof S.Event)) return new S.Event(e, t); + e && e.type + ? ((this.originalEvent = e), + (this.type = e.type), + (this.isDefaultPrevented = e.defaultPrevented || (void 0 === e.defaultPrevented && !1 === e.returnValue) ? Ce : Ee), + (this.target = e.target && 3 === e.target.nodeType ? e.target.parentNode : e.target), + (this.currentTarget = e.currentTarget), + (this.relatedTarget = e.relatedTarget)) + : (this.type = e), + t && S.extend(this, t), + (this.timeStamp = (e && e.timeStamp) || Date.now()), + (this[S.expando] = !0); + }), + (S.Event.prototype = { + constructor: S.Event, + isDefaultPrevented: Ee, + isPropagationStopped: Ee, + isImmediatePropagationStopped: Ee, + isSimulated: !1, + preventDefault: function () { + var e = this.originalEvent; + (this.isDefaultPrevented = Ce), e && !this.isSimulated && e.preventDefault(); + }, + stopPropagation: function () { + var e = this.originalEvent; + (this.isPropagationStopped = Ce), e && !this.isSimulated && e.stopPropagation(); + }, + stopImmediatePropagation: function () { + var e = this.originalEvent; + (this.isImmediatePropagationStopped = Ce), e && !this.isSimulated && e.stopImmediatePropagation(), this.stopPropagation(); + }, + }), + S.each( + { + altKey: !0, + bubbles: !0, + cancelable: !0, + changedTouches: !0, + ctrlKey: !0, + detail: !0, + eventPhase: !0, + metaKey: !0, + pageX: !0, + pageY: !0, + shiftKey: !0, + view: !0, + char: !0, + code: !0, + charCode: !0, + key: !0, + keyCode: !0, + button: !0, + buttons: !0, + clientX: !0, + clientY: !0, + offsetX: !0, + offsetY: !0, + pointerId: !0, + pointerType: !0, + screenX: !0, + screenY: !0, + targetTouches: !0, + toElement: !0, + touches: !0, + which: function (e) { + var t = e.button; + return null == e.which && be.test(e.type) + ? null != e.charCode + ? e.charCode + : e.keyCode + : !e.which && void 0 !== t && we.test(e.type) + ? 1 & t + ? 1 + : 2 & t + ? 3 + : 4 & t + ? 2 + : 0 + : e.which; + }, + }, + S.event.addProp + ), + S.each({ focus: 'focusin', blur: 'focusout' }, function (e, t) { + S.event.special[e] = { + setup: function () { + return Ae(this, e, Se), !1; + }, + trigger: function () { + return Ae(this, e), !0; + }, + delegateType: t, + }; + }), + S.each({ mouseenter: 'mouseover', mouseleave: 'mouseout', pointerenter: 'pointerover', pointerleave: 'pointerout' }, function (e, i) { + S.event.special[e] = { + delegateType: i, + bindType: i, + handle: function (e) { + var t, + n = e.relatedTarget, + r = e.handleObj; + return ( + (n && (n === this || S.contains(this, n))) || ((e.type = r.origType), (t = r.handler.apply(this, arguments)), (e.type = i)), t + ); + }, + }; + }), + S.fn.extend({ + on: function (e, t, n, r) { + return ke(this, e, t, n, r); + }, + one: function (e, t, n, r) { + return ke(this, e, t, n, r, 1); + }, + off: function (e, t, n) { + var r, i; + if (e && e.preventDefault && e.handleObj) + return ( + (r = e.handleObj), + S(e.delegateTarget).off(r.namespace ? r.origType + '.' + r.namespace : r.origType, r.selector, r.handler), + this + ); + if ('object' == typeof e) { + for (i in e) this.off(i, t, e[i]); + return this; + } + return ( + (!1 !== t && 'function' != typeof t) || ((n = t), (t = void 0)), + !1 === n && (n = Ee), + this.each(function () { + S.event.remove(this, e, n, t); + }) + ); + }, + }); + var Ne = /<script|<style|<link/i, + De = /checked\s*(?:[^=]|=\s*.checked.)/i, + je = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; + function qe(e, t) { + return (A(e, 'table') && A(11 !== t.nodeType ? t : t.firstChild, 'tr') && S(e).children('tbody')[0]) || e; + } + function Le(e) { + return (e.type = (null !== e.getAttribute('type')) + '/' + e.type), e; + } + function He(e) { + return 'true/' === (e.type || '').slice(0, 5) ? (e.type = e.type.slice(5)) : e.removeAttribute('type'), e; + } + function Oe(e, t) { + var n, r, i, o, a, s; + if (1 === t.nodeType) { + if (Y.hasData(e) && (s = Y.get(e).events)) + for (i in (Y.remove(t, 'handle events'), s)) for (n = 0, r = s[i].length; n < r; n++) S.event.add(t, i, s[i][n]); + Q.hasData(e) && ((o = Q.access(e)), (a = S.extend({}, o)), Q.set(t, a)); + } + } + function Pe(n, r, i, o) { + r = g(r); + var e, + t, + a, + s, + u, + l, + c = 0, + f = n.length, + p = f - 1, + d = r[0], + h = m(d); + if (h || (1 < f && 'string' == typeof d && !y.checkClone && De.test(d))) + return n.each(function (e) { + var t = n.eq(e); + h && (r[0] = d.call(this, e, t.html())), Pe(t, r, i, o); + }); + if (f && ((t = (e = xe(r, n[0].ownerDocument, !1, n, o)).firstChild), 1 === e.childNodes.length && (e = t), t || o)) { + for (s = (a = S.map(ve(e, 'script'), Le)).length; c < f; c++) + (u = e), c !== p && ((u = S.clone(u, !0, !0)), s && S.merge(a, ve(u, 'script'))), i.call(n[c], u, c); + if (s) + for (l = a[a.length - 1].ownerDocument, S.map(a, He), c = 0; c < s; c++) + (u = a[c]), + he.test(u.type || '') && + !Y.access(u, 'globalEval') && + S.contains(l, u) && + (u.src && 'module' !== (u.type || '').toLowerCase() + ? S._evalUrl && !u.noModule && S._evalUrl(u.src, { nonce: u.nonce || u.getAttribute('nonce') }, l) + : b(u.textContent.replace(je, ''), u, l)); + } + return n; + } + function Re(e, t, n) { + for (var r, i = t ? S.filter(t, e) : e, o = 0; null != (r = i[o]); o++) + n || 1 !== r.nodeType || S.cleanData(ve(r)), r.parentNode && (n && ie(r) && ye(ve(r, 'script')), r.parentNode.removeChild(r)); + return e; + } + S.extend({ + htmlPrefilter: function (e) { + return e; + }, + clone: function (e, t, n) { + var r, + i, + o, + a, + s, + u, + l, + c = e.cloneNode(!0), + f = ie(e); + if (!(y.noCloneChecked || (1 !== e.nodeType && 11 !== e.nodeType) || S.isXMLDoc(e))) + for (a = ve(c), r = 0, i = (o = ve(e)).length; r < i; r++) + (s = o[r]), + (u = a[r]), + void 0, + 'input' === (l = u.nodeName.toLowerCase()) && pe.test(s.type) + ? (u.checked = s.checked) + : ('input' !== l && 'textarea' !== l) || (u.defaultValue = s.defaultValue); + if (t) + if (n) for (o = o || ve(e), a = a || ve(c), r = 0, i = o.length; r < i; r++) Oe(o[r], a[r]); + else Oe(e, c); + return 0 < (a = ve(c, 'script')).length && ye(a, !f && ve(e, 'script')), c; + }, + cleanData: function (e) { + for (var t, n, r, i = S.event.special, o = 0; void 0 !== (n = e[o]); o++) + if (V(n)) { + if ((t = n[Y.expando])) { + if (t.events) for (r in t.events) i[r] ? S.event.remove(n, r) : S.removeEvent(n, r, t.handle); + n[Y.expando] = void 0; + } + n[Q.expando] && (n[Q.expando] = void 0); + } + }, + }), + S.fn.extend({ + detach: function (e) { + return Re(this, e, !0); + }, + remove: function (e) { + return Re(this, e); + }, + text: function (e) { + return $( + this, + function (e) { + return void 0 === e + ? S.text(this) + : this.empty().each(function () { + (1 !== this.nodeType && 11 !== this.nodeType && 9 !== this.nodeType) || (this.textContent = e); + }); + }, + null, + e, + arguments.length + ); + }, + append: function () { + return Pe(this, arguments, function (e) { + (1 !== this.nodeType && 11 !== this.nodeType && 9 !== this.nodeType) || qe(this, e).appendChild(e); + }); + }, + prepend: function () { + return Pe(this, arguments, function (e) { + if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { + var t = qe(this, e); + t.insertBefore(e, t.firstChild); + } + }); + }, + before: function () { + return Pe(this, arguments, function (e) { + this.parentNode && this.parentNode.insertBefore(e, this); + }); + }, + after: function () { + return Pe(this, arguments, function (e) { + this.parentNode && this.parentNode.insertBefore(e, this.nextSibling); + }); + }, + empty: function () { + for (var e, t = 0; null != (e = this[t]); t++) 1 === e.nodeType && (S.cleanData(ve(e, !1)), (e.textContent = '')); + return this; + }, + clone: function (e, t) { + return ( + (e = null != e && e), + (t = null == t ? e : t), + this.map(function () { + return S.clone(this, e, t); + }) + ); + }, + html: function (e) { + return $( + this, + function (e) { + var t = this[0] || {}, + n = 0, + r = this.length; + if (void 0 === e && 1 === t.nodeType) return t.innerHTML; + if ('string' == typeof e && !Ne.test(e) && !ge[(de.exec(e) || ['', ''])[1].toLowerCase()]) { + e = S.htmlPrefilter(e); + try { + for (; n < r; n++) 1 === (t = this[n] || {}).nodeType && (S.cleanData(ve(t, !1)), (t.innerHTML = e)); + t = 0; + } catch (e) {} + } + t && this.empty().append(e); + }, + null, + e, + arguments.length + ); + }, + replaceWith: function () { + var n = []; + return Pe( + this, + arguments, + function (e) { + var t = this.parentNode; + S.inArray(this, n) < 0 && (S.cleanData(ve(this)), t && t.replaceChild(e, this)); + }, + n + ); + }, + }), + S.each( + { appendTo: 'append', prependTo: 'prepend', insertBefore: 'before', insertAfter: 'after', replaceAll: 'replaceWith' }, + function (e, a) { + S.fn[e] = function (e) { + for (var t, n = [], r = S(e), i = r.length - 1, o = 0; o <= i; o++) + (t = o === i ? this : this.clone(!0)), S(r[o])[a](t), u.apply(n, t.get()); + return this.pushStack(n); + }; + } + ); + var Me = new RegExp('^(' + ee + ')(?!px)[a-z%]+$', 'i'), + Ie = function (e) { + var t = e.ownerDocument.defaultView; + return (t && t.opener) || (t = C), t.getComputedStyle(e); + }, + We = function (e, t, n) { + var r, + i, + o = {}; + for (i in t) (o[i] = e.style[i]), (e.style[i] = t[i]); + for (i in ((r = n.call(e)), t)) e.style[i] = o[i]; + return r; + }, + Fe = new RegExp(ne.join('|'), 'i'); + function Be(e, t, n) { + var r, + i, + o, + a, + s = e.style; + return ( + (n = n || Ie(e)) && + ('' !== (a = n.getPropertyValue(t) || n[t]) || ie(e) || (a = S.style(e, t)), + !y.pixelBoxStyles() && + Me.test(a) && + Fe.test(t) && + ((r = s.width), + (i = s.minWidth), + (o = s.maxWidth), + (s.minWidth = s.maxWidth = s.width = a), + (a = n.width), + (s.width = r), + (s.minWidth = i), + (s.maxWidth = o))), + void 0 !== a ? a + '' : a + ); + } + function $e(e, t) { + return { + get: function () { + if (!e()) return (this.get = t).apply(this, arguments); + delete this.get; + }, + }; + } + !(function () { + function e() { + if (l) { + (u.style.cssText = 'position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0'), + (l.style.cssText = + 'position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%'), + re.appendChild(u).appendChild(l); + var e = C.getComputedStyle(l); + (n = '1%' !== e.top), + (s = 12 === t(e.marginLeft)), + (l.style.right = '60%'), + (o = 36 === t(e.right)), + (r = 36 === t(e.width)), + (l.style.position = 'absolute'), + (i = 12 === t(l.offsetWidth / 3)), + re.removeChild(u), + (l = null); + } + } + function t(e) { + return Math.round(parseFloat(e)); + } + var n, + r, + i, + o, + a, + s, + u = E.createElement('div'), + l = E.createElement('div'); + l.style && + ((l.style.backgroundClip = 'content-box'), + (l.cloneNode(!0).style.backgroundClip = ''), + (y.clearCloneStyle = 'content-box' === l.style.backgroundClip), + S.extend(y, { + boxSizingReliable: function () { + return e(), r; + }, + pixelBoxStyles: function () { + return e(), o; + }, + pixelPosition: function () { + return e(), n; + }, + reliableMarginLeft: function () { + return e(), s; + }, + scrollboxSize: function () { + return e(), i; + }, + reliableTrDimensions: function () { + var e, t, n, r; + return ( + null == a && + ((e = E.createElement('table')), + (t = E.createElement('tr')), + (n = E.createElement('div')), + (e.style.cssText = 'position:absolute;left:-11111px'), + (t.style.height = '1px'), + (n.style.height = '9px'), + re.appendChild(e).appendChild(t).appendChild(n), + (r = C.getComputedStyle(t)), + (a = 3 < parseInt(r.height)), + re.removeChild(e)), + a + ); + }, + })); + })(); + var _e = ['Webkit', 'Moz', 'ms'], + ze = E.createElement('div').style, + Ue = {}; + function Xe(e) { + var t = S.cssProps[e] || Ue[e]; + return ( + t || + (e in ze + ? e + : (Ue[e] = + (function (e) { + var t = e[0].toUpperCase() + e.slice(1), + n = _e.length; + while (n--) if ((e = _e[n] + t) in ze) return e; + })(e) || e)) + ); + } + var Ve = /^(none|table(?!-c[ea]).+)/, + Ge = /^--/, + Ye = { position: 'absolute', visibility: 'hidden', display: 'block' }, + Qe = { letterSpacing: '0', fontWeight: '400' }; + function Je(e, t, n) { + var r = te.exec(t); + return r ? Math.max(0, r[2] - (n || 0)) + (r[3] || 'px') : t; + } + function Ke(e, t, n, r, i, o) { + var a = 'width' === t ? 1 : 0, + s = 0, + u = 0; + if (n === (r ? 'border' : 'content')) return 0; + for (; a < 4; a += 2) + 'margin' === n && (u += S.css(e, n + ne[a], !0, i)), + r + ? ('content' === n && (u -= S.css(e, 'padding' + ne[a], !0, i)), + 'margin' !== n && (u -= S.css(e, 'border' + ne[a] + 'Width', !0, i))) + : ((u += S.css(e, 'padding' + ne[a], !0, i)), + 'padding' !== n ? (u += S.css(e, 'border' + ne[a] + 'Width', !0, i)) : (s += S.css(e, 'border' + ne[a] + 'Width', !0, i))); + return !r && 0 <= o && (u += Math.max(0, Math.ceil(e['offset' + t[0].toUpperCase() + t.slice(1)] - o - u - s - 0.5)) || 0), u; + } + function Ze(e, t, n) { + var r = Ie(e), + i = (!y.boxSizingReliable() || n) && 'border-box' === S.css(e, 'boxSizing', !1, r), + o = i, + a = Be(e, t, r), + s = 'offset' + t[0].toUpperCase() + t.slice(1); + if (Me.test(a)) { + if (!n) return a; + a = 'auto'; + } + return ( + ((!y.boxSizingReliable() && i) || + (!y.reliableTrDimensions() && A(e, 'tr')) || + 'auto' === a || + (!parseFloat(a) && 'inline' === S.css(e, 'display', !1, r))) && + e.getClientRects().length && + ((i = 'border-box' === S.css(e, 'boxSizing', !1, r)), (o = s in e) && (a = e[s])), + (a = parseFloat(a) || 0) + Ke(e, t, n || (i ? 'border' : 'content'), o, r, a) + 'px' + ); + } + function et(e, t, n, r, i) { + return new et.prototype.init(e, t, n, r, i); + } + S.extend({ + cssHooks: { + opacity: { + get: function (e, t) { + if (t) { + var n = Be(e, 'opacity'); + return '' === n ? '1' : n; + } + }, + }, + }, + cssNumber: { + animationIterationCount: !0, + columnCount: !0, + fillOpacity: !0, + flexGrow: !0, + flexShrink: !0, + fontWeight: !0, + gridArea: !0, + gridColumn: !0, + gridColumnEnd: !0, + gridColumnStart: !0, + gridRow: !0, + gridRowEnd: !0, + gridRowStart: !0, + lineHeight: !0, + opacity: !0, + order: !0, + orphans: !0, + widows: !0, + zIndex: !0, + zoom: !0, + }, + cssProps: {}, + style: function (e, t, n, r) { + if (e && 3 !== e.nodeType && 8 !== e.nodeType && e.style) { + var i, + o, + a, + s = X(t), + u = Ge.test(t), + l = e.style; + if ((u || (t = Xe(s)), (a = S.cssHooks[t] || S.cssHooks[s]), void 0 === n)) + return a && 'get' in a && void 0 !== (i = a.get(e, !1, r)) ? i : l[t]; + 'string' === (o = typeof n) && (i = te.exec(n)) && i[1] && ((n = se(e, t, i)), (o = 'number')), + null != n && + n == n && + ('number' !== o || u || (n += (i && i[3]) || (S.cssNumber[s] ? '' : 'px')), + y.clearCloneStyle || '' !== n || 0 !== t.indexOf('background') || (l[t] = 'inherit'), + (a && 'set' in a && void 0 === (n = a.set(e, n, r))) || (u ? l.setProperty(t, n) : (l[t] = n))); + } + }, + css: function (e, t, n, r) { + var i, + o, + a, + s = X(t); + return ( + Ge.test(t) || (t = Xe(s)), + (a = S.cssHooks[t] || S.cssHooks[s]) && 'get' in a && (i = a.get(e, !0, n)), + void 0 === i && (i = Be(e, t, r)), + 'normal' === i && t in Qe && (i = Qe[t]), + '' === n || n ? ((o = parseFloat(i)), !0 === n || isFinite(o) ? o || 0 : i) : i + ); + }, + }), + S.each(['height', 'width'], function (e, u) { + S.cssHooks[u] = { + get: function (e, t, n) { + if (t) + return !Ve.test(S.css(e, 'display')) || (e.getClientRects().length && e.getBoundingClientRect().width) + ? Ze(e, u, n) + : We(e, Ye, function () { + return Ze(e, u, n); + }); + }, + set: function (e, t, n) { + var r, + i = Ie(e), + o = !y.scrollboxSize() && 'absolute' === i.position, + a = (o || n) && 'border-box' === S.css(e, 'boxSizing', !1, i), + s = n ? Ke(e, u, n, a, i) : 0; + return ( + a && o && (s -= Math.ceil(e['offset' + u[0].toUpperCase() + u.slice(1)] - parseFloat(i[u]) - Ke(e, u, 'border', !1, i) - 0.5)), + s && (r = te.exec(t)) && 'px' !== (r[3] || 'px') && ((e.style[u] = t), (t = S.css(e, u))), + Je(0, t, s) + ); + }, + }; + }), + (S.cssHooks.marginLeft = $e(y.reliableMarginLeft, function (e, t) { + if (t) + return ( + (parseFloat(Be(e, 'marginLeft')) || + e.getBoundingClientRect().left - + We(e, { marginLeft: 0 }, function () { + return e.getBoundingClientRect().left; + })) + 'px' + ); + })), + S.each({ margin: '', padding: '', border: 'Width' }, function (i, o) { + (S.cssHooks[i + o] = { + expand: function (e) { + for (var t = 0, n = {}, r = 'string' == typeof e ? e.split(' ') : [e]; t < 4; t++) n[i + ne[t] + o] = r[t] || r[t - 2] || r[0]; + return n; + }, + }), + 'margin' !== i && (S.cssHooks[i + o].set = Je); + }), + S.fn.extend({ + css: function (e, t) { + return $( + this, + function (e, t, n) { + var r, + i, + o = {}, + a = 0; + if (Array.isArray(t)) { + for (r = Ie(e), i = t.length; a < i; a++) o[t[a]] = S.css(e, t[a], !1, r); + return o; + } + return void 0 !== n ? S.style(e, t, n) : S.css(e, t); + }, + e, + t, + 1 < arguments.length + ); + }, + }), + (((S.Tween = et).prototype = { + constructor: et, + init: function (e, t, n, r, i, o) { + (this.elem = e), + (this.prop = n), + (this.easing = i || S.easing._default), + (this.options = t), + (this.start = this.now = this.cur()), + (this.end = r), + (this.unit = o || (S.cssNumber[n] ? '' : 'px')); + }, + cur: function () { + var e = et.propHooks[this.prop]; + return e && e.get ? e.get(this) : et.propHooks._default.get(this); + }, + run: function (e) { + var t, + n = et.propHooks[this.prop]; + return ( + this.options.duration + ? (this.pos = t = S.easing[this.easing](e, this.options.duration * e, 0, 1, this.options.duration)) + : (this.pos = t = e), + (this.now = (this.end - this.start) * t + this.start), + this.options.step && this.options.step.call(this.elem, this.now, this), + n && n.set ? n.set(this) : et.propHooks._default.set(this), + this + ); + }, + }).init.prototype = et.prototype), + ((et.propHooks = { + _default: { + get: function (e) { + var t; + return 1 !== e.elem.nodeType || (null != e.elem[e.prop] && null == e.elem.style[e.prop]) + ? e.elem[e.prop] + : (t = S.css(e.elem, e.prop, '')) && 'auto' !== t + ? t + : 0; + }, + set: function (e) { + S.fx.step[e.prop] + ? S.fx.step[e.prop](e) + : 1 !== e.elem.nodeType || (!S.cssHooks[e.prop] && null == e.elem.style[Xe(e.prop)]) + ? (e.elem[e.prop] = e.now) + : S.style(e.elem, e.prop, e.now + e.unit); + }, + }, + }).scrollTop = et.propHooks.scrollLeft = + { + set: function (e) { + e.elem.nodeType && e.elem.parentNode && (e.elem[e.prop] = e.now); + }, + }), + (S.easing = { + linear: function (e) { + return e; + }, + swing: function (e) { + return 0.5 - Math.cos(e * Math.PI) / 2; + }, + _default: 'swing', + }), + (S.fx = et.prototype.init), + (S.fx.step = {}); + var tt, + nt, + rt, + it, + ot = /^(?:toggle|show|hide)$/, + at = /queueHooks$/; + function st() { + nt && (!1 === E.hidden && C.requestAnimationFrame ? C.requestAnimationFrame(st) : C.setTimeout(st, S.fx.interval), S.fx.tick()); + } + function ut() { + return ( + C.setTimeout(function () { + tt = void 0; + }), + (tt = Date.now()) + ); + } + function lt(e, t) { + var n, + r = 0, + i = { height: e }; + for (t = t ? 1 : 0; r < 4; r += 2 - t) i['margin' + (n = ne[r])] = i['padding' + n] = e; + return t && (i.opacity = i.width = e), i; + } + function ct(e, t, n) { + for (var r, i = (ft.tweeners[t] || []).concat(ft.tweeners['*']), o = 0, a = i.length; o < a; o++) + if ((r = i[o].call(n, t, e))) return r; + } + function ft(o, e, t) { + var n, + a, + r = 0, + i = ft.prefilters.length, + s = S.Deferred().always(function () { + delete u.elem; + }), + u = function () { + if (a) return !1; + for ( + var e = tt || ut(), t = Math.max(0, l.startTime + l.duration - e), n = 1 - (t / l.duration || 0), r = 0, i = l.tweens.length; + r < i; + r++ + ) + l.tweens[r].run(n); + return s.notifyWith(o, [l, n, t]), n < 1 && i ? t : (i || s.notifyWith(o, [l, 1, 0]), s.resolveWith(o, [l]), !1); + }, + l = s.promise({ + elem: o, + props: S.extend({}, e), + opts: S.extend(!0, { specialEasing: {}, easing: S.easing._default }, t), + originalProperties: e, + originalOptions: t, + startTime: tt || ut(), + duration: t.duration, + tweens: [], + createTween: function (e, t) { + var n = S.Tween(o, l.opts, e, t, l.opts.specialEasing[e] || l.opts.easing); + return l.tweens.push(n), n; + }, + stop: function (e) { + var t = 0, + n = e ? l.tweens.length : 0; + if (a) return this; + for (a = !0; t < n; t++) l.tweens[t].run(1); + return e ? (s.notifyWith(o, [l, 1, 0]), s.resolveWith(o, [l, e])) : s.rejectWith(o, [l, e]), this; + }, + }), + c = l.props; + for ( + !(function (e, t) { + var n, r, i, o, a; + for (n in e) + if ( + ((i = t[(r = X(n))]), + (o = e[n]), + Array.isArray(o) && ((i = o[1]), (o = e[n] = o[0])), + n !== r && ((e[r] = o), delete e[n]), + (a = S.cssHooks[r]) && ('expand' in a)) + ) + for (n in ((o = a.expand(o)), delete e[r], o)) (n in e) || ((e[n] = o[n]), (t[n] = i)); + else t[r] = i; + })(c, l.opts.specialEasing); + r < i; + r++ + ) + if ((n = ft.prefilters[r].call(l, o, c, l.opts))) return m(n.stop) && (S._queueHooks(l.elem, l.opts.queue).stop = n.stop.bind(n)), n; + return ( + S.map(c, ct, l), + m(l.opts.start) && l.opts.start.call(o, l), + l.progress(l.opts.progress).done(l.opts.done, l.opts.complete).fail(l.opts.fail).always(l.opts.always), + S.fx.timer(S.extend(u, { elem: o, anim: l, queue: l.opts.queue })), + l + ); + } + (S.Animation = S.extend(ft, { + tweeners: { + '*': [ + function (e, t) { + var n = this.createTween(e, t); + return se(n.elem, e, te.exec(t), n), n; + }, + ], + }, + tweener: function (e, t) { + m(e) ? ((t = e), (e = ['*'])) : (e = e.match(P)); + for (var n, r = 0, i = e.length; r < i; r++) (n = e[r]), (ft.tweeners[n] = ft.tweeners[n] || []), ft.tweeners[n].unshift(t); + }, + prefilters: [ + function (e, t, n) { + var r, + i, + o, + a, + s, + u, + l, + c, + f = 'width' in t || 'height' in t, + p = this, + d = {}, + h = e.style, + g = e.nodeType && ae(e), + v = Y.get(e, 'fxshow'); + for (r in (n.queue || + (null == (a = S._queueHooks(e, 'fx')).unqueued && + ((a.unqueued = 0), + (s = a.empty.fire), + (a.empty.fire = function () { + a.unqueued || s(); + })), + a.unqueued++, + p.always(function () { + p.always(function () { + a.unqueued--, S.queue(e, 'fx').length || a.empty.fire(); + }); + })), + t)) + if (((i = t[r]), ot.test(i))) { + if ((delete t[r], (o = o || 'toggle' === i), i === (g ? 'hide' : 'show'))) { + if ('show' !== i || !v || void 0 === v[r]) continue; + g = !0; + } + d[r] = (v && v[r]) || S.style(e, r); + } + if ((u = !S.isEmptyObject(t)) || !S.isEmptyObject(d)) + for (r in (f && + 1 === e.nodeType && + ((n.overflow = [h.overflow, h.overflowX, h.overflowY]), + null == (l = v && v.display) && (l = Y.get(e, 'display')), + 'none' === (c = S.css(e, 'display')) && + (l ? (c = l) : (le([e], !0), (l = e.style.display || l), (c = S.css(e, 'display')), le([e]))), + ('inline' === c || ('inline-block' === c && null != l)) && + 'none' === S.css(e, 'float') && + (u || + (p.done(function () { + h.display = l; + }), + null == l && ((c = h.display), (l = 'none' === c ? '' : c))), + (h.display = 'inline-block'))), + n.overflow && + ((h.overflow = 'hidden'), + p.always(function () { + (h.overflow = n.overflow[0]), (h.overflowX = n.overflow[1]), (h.overflowY = n.overflow[2]); + })), + (u = !1), + d)) + u || + (v ? 'hidden' in v && (g = v.hidden) : (v = Y.access(e, 'fxshow', { display: l })), + o && (v.hidden = !g), + g && le([e], !0), + p.done(function () { + for (r in (g || le([e]), Y.remove(e, 'fxshow'), d)) S.style(e, r, d[r]); + })), + (u = ct(g ? v[r] : 0, r, p)), + r in v || ((v[r] = u.start), g && ((u.end = u.start), (u.start = 0))); + }, + ], + prefilter: function (e, t) { + t ? ft.prefilters.unshift(e) : ft.prefilters.push(e); + }, + })), + (S.speed = function (e, t, n) { + var r = + e && 'object' == typeof e + ? S.extend({}, e) + : { complete: n || (!n && t) || (m(e) && e), duration: e, easing: (n && t) || (t && !m(t) && t) }; + return ( + S.fx.off + ? (r.duration = 0) + : 'number' != typeof r.duration && + (r.duration in S.fx.speeds ? (r.duration = S.fx.speeds[r.duration]) : (r.duration = S.fx.speeds._default)), + (null != r.queue && !0 !== r.queue) || (r.queue = 'fx'), + (r.old = r.complete), + (r.complete = function () { + m(r.old) && r.old.call(this), r.queue && S.dequeue(this, r.queue); + }), + r + ); + }), + S.fn.extend({ + fadeTo: function (e, t, n, r) { + return this.filter(ae).css('opacity', 0).show().end().animate({ opacity: t }, e, n, r); + }, + animate: function (t, e, n, r) { + var i = S.isEmptyObject(t), + o = S.speed(e, n, r), + a = function () { + var e = ft(this, S.extend({}, t), o); + (i || Y.get(this, 'finish')) && e.stop(!0); + }; + return (a.finish = a), i || !1 === o.queue ? this.each(a) : this.queue(o.queue, a); + }, + stop: function (i, e, o) { + var a = function (e) { + var t = e.stop; + delete e.stop, t(o); + }; + return ( + 'string' != typeof i && ((o = e), (e = i), (i = void 0)), + e && this.queue(i || 'fx', []), + this.each(function () { + var e = !0, + t = null != i && i + 'queueHooks', + n = S.timers, + r = Y.get(this); + if (t) r[t] && r[t].stop && a(r[t]); + else for (t in r) r[t] && r[t].stop && at.test(t) && a(r[t]); + for (t = n.length; t--; ) + n[t].elem !== this || (null != i && n[t].queue !== i) || (n[t].anim.stop(o), (e = !1), n.splice(t, 1)); + (!e && o) || S.dequeue(this, i); + }) + ); + }, + finish: function (a) { + return ( + !1 !== a && (a = a || 'fx'), + this.each(function () { + var e, + t = Y.get(this), + n = t[a + 'queue'], + r = t[a + 'queueHooks'], + i = S.timers, + o = n ? n.length : 0; + for (t.finish = !0, S.queue(this, a, []), r && r.stop && r.stop.call(this, !0), e = i.length; e--; ) + i[e].elem === this && i[e].queue === a && (i[e].anim.stop(!0), i.splice(e, 1)); + for (e = 0; e < o; e++) n[e] && n[e].finish && n[e].finish.call(this); + delete t.finish; + }) + ); + }, + }), + S.each(['toggle', 'show', 'hide'], function (e, r) { + var i = S.fn[r]; + S.fn[r] = function (e, t, n) { + return null == e || 'boolean' == typeof e ? i.apply(this, arguments) : this.animate(lt(r, !0), e, t, n); + }; + }), + S.each( + { + slideDown: lt('show'), + slideUp: lt('hide'), + slideToggle: lt('toggle'), + fadeIn: { opacity: 'show' }, + fadeOut: { opacity: 'hide' }, + fadeToggle: { opacity: 'toggle' }, + }, + function (e, r) { + S.fn[e] = function (e, t, n) { + return this.animate(r, e, t, n); + }; + } + ), + (S.timers = []), + (S.fx.tick = function () { + var e, + t = 0, + n = S.timers; + for (tt = Date.now(); t < n.length; t++) (e = n[t])() || n[t] !== e || n.splice(t--, 1); + n.length || S.fx.stop(), (tt = void 0); + }), + (S.fx.timer = function (e) { + S.timers.push(e), S.fx.start(); + }), + (S.fx.interval = 13), + (S.fx.start = function () { + nt || ((nt = !0), st()); + }), + (S.fx.stop = function () { + nt = null; + }), + (S.fx.speeds = { slow: 600, fast: 200, _default: 400 }), + (S.fn.delay = function (r, e) { + return ( + (r = (S.fx && S.fx.speeds[r]) || r), + (e = e || 'fx'), + this.queue(e, function (e, t) { + var n = C.setTimeout(e, r); + t.stop = function () { + C.clearTimeout(n); + }; + }) + ); + }), + (rt = E.createElement('input')), + (it = E.createElement('select').appendChild(E.createElement('option'))), + (rt.type = 'checkbox'), + (y.checkOn = '' !== rt.value), + (y.optSelected = it.selected), + ((rt = E.createElement('input')).value = 't'), + (rt.type = 'radio'), + (y.radioValue = 't' === rt.value); + var pt, + dt = S.expr.attrHandle; + S.fn.extend({ + attr: function (e, t) { + return $(this, S.attr, e, t, 1 < arguments.length); + }, + removeAttr: function (e) { + return this.each(function () { + S.removeAttr(this, e); + }); + }, + }), + S.extend({ + attr: function (e, t, n) { + var r, + i, + o = e.nodeType; + if (3 !== o && 8 !== o && 2 !== o) + return 'undefined' == typeof e.getAttribute + ? S.prop(e, t, n) + : ((1 === o && S.isXMLDoc(e)) || (i = S.attrHooks[t.toLowerCase()] || (S.expr.match.bool.test(t) ? pt : void 0)), + void 0 !== n + ? null === n + ? void S.removeAttr(e, t) + : i && 'set' in i && void 0 !== (r = i.set(e, n, t)) + ? r + : (e.setAttribute(t, n + ''), n) + : i && 'get' in i && null !== (r = i.get(e, t)) + ? r + : null == (r = S.find.attr(e, t)) + ? void 0 + : r); + }, + attrHooks: { + type: { + set: function (e, t) { + if (!y.radioValue && 'radio' === t && A(e, 'input')) { + var n = e.value; + return e.setAttribute('type', t), n && (e.value = n), t; + } + }, + }, + }, + removeAttr: function (e, t) { + var n, + r = 0, + i = t && t.match(P); + if (i && 1 === e.nodeType) while ((n = i[r++])) e.removeAttribute(n); + }, + }), + (pt = { + set: function (e, t, n) { + return !1 === t ? S.removeAttr(e, n) : e.setAttribute(n, n), n; + }, + }), + S.each(S.expr.match.bool.source.match(/\w+/g), function (e, t) { + var a = dt[t] || S.find.attr; + dt[t] = function (e, t, n) { + var r, + i, + o = t.toLowerCase(); + return n || ((i = dt[o]), (dt[o] = r), (r = null != a(e, t, n) ? o : null), (dt[o] = i)), r; + }; + }); + var ht = /^(?:input|select|textarea|button)$/i, + gt = /^(?:a|area)$/i; + function vt(e) { + return (e.match(P) || []).join(' '); + } + function yt(e) { + return (e.getAttribute && e.getAttribute('class')) || ''; + } + function mt(e) { + return Array.isArray(e) ? e : ('string' == typeof e && e.match(P)) || []; + } + S.fn.extend({ + prop: function (e, t) { + return $(this, S.prop, e, t, 1 < arguments.length); + }, + removeProp: function (e) { + return this.each(function () { + delete this[S.propFix[e] || e]; + }); + }, + }), + S.extend({ + prop: function (e, t, n) { + var r, + i, + o = e.nodeType; + if (3 !== o && 8 !== o && 2 !== o) + return ( + (1 === o && S.isXMLDoc(e)) || ((t = S.propFix[t] || t), (i = S.propHooks[t])), + void 0 !== n + ? i && 'set' in i && void 0 !== (r = i.set(e, n, t)) + ? r + : (e[t] = n) + : i && 'get' in i && null !== (r = i.get(e, t)) + ? r + : e[t] + ); + }, + propHooks: { + tabIndex: { + get: function (e) { + var t = S.find.attr(e, 'tabindex'); + return t ? parseInt(t, 10) : ht.test(e.nodeName) || (gt.test(e.nodeName) && e.href) ? 0 : -1; + }, + }, + }, + propFix: { for: 'htmlFor', class: 'className' }, + }), + y.optSelected || + (S.propHooks.selected = { + get: function (e) { + var t = e.parentNode; + return t && t.parentNode && t.parentNode.selectedIndex, null; + }, + set: function (e) { + var t = e.parentNode; + t && (t.selectedIndex, t.parentNode && t.parentNode.selectedIndex); + }, + }), + S.each( + ['tabIndex', 'readOnly', 'maxLength', 'cellSpacing', 'cellPadding', 'rowSpan', 'colSpan', 'useMap', 'frameBorder', 'contentEditable'], + function () { + S.propFix[this.toLowerCase()] = this; + } + ), + S.fn.extend({ + addClass: function (t) { + var e, + n, + r, + i, + o, + a, + s, + u = 0; + if (m(t)) + return this.each(function (e) { + S(this).addClass(t.call(this, e, yt(this))); + }); + if ((e = mt(t)).length) + while ((n = this[u++])) + if (((i = yt(n)), (r = 1 === n.nodeType && ' ' + vt(i) + ' '))) { + a = 0; + while ((o = e[a++])) r.indexOf(' ' + o + ' ') < 0 && (r += o + ' '); + i !== (s = vt(r)) && n.setAttribute('class', s); + } + return this; + }, + removeClass: function (t) { + var e, + n, + r, + i, + o, + a, + s, + u = 0; + if (m(t)) + return this.each(function (e) { + S(this).removeClass(t.call(this, e, yt(this))); + }); + if (!arguments.length) return this.attr('class', ''); + if ((e = mt(t)).length) + while ((n = this[u++])) + if (((i = yt(n)), (r = 1 === n.nodeType && ' ' + vt(i) + ' '))) { + a = 0; + while ((o = e[a++])) while (-1 < r.indexOf(' ' + o + ' ')) r = r.replace(' ' + o + ' ', ' '); + i !== (s = vt(r)) && n.setAttribute('class', s); + } + return this; + }, + toggleClass: function (i, t) { + var o = typeof i, + a = 'string' === o || Array.isArray(i); + return 'boolean' == typeof t && a + ? t + ? this.addClass(i) + : this.removeClass(i) + : m(i) + ? this.each(function (e) { + S(this).toggleClass(i.call(this, e, yt(this), t), t); + }) + : this.each(function () { + var e, t, n, r; + if (a) { + (t = 0), (n = S(this)), (r = mt(i)); + while ((e = r[t++])) n.hasClass(e) ? n.removeClass(e) : n.addClass(e); + } else (void 0 !== i && 'boolean' !== o) || ((e = yt(this)) && Y.set(this, '__className__', e), this.setAttribute && this.setAttribute('class', e || !1 === i ? '' : Y.get(this, '__className__') || '')); + }); + }, + hasClass: function (e) { + var t, + n, + r = 0; + t = ' ' + e + ' '; + while ((n = this[r++])) if (1 === n.nodeType && -1 < (' ' + vt(yt(n)) + ' ').indexOf(t)) return !0; + return !1; + }, + }); + var xt = /\r/g; + S.fn.extend({ + val: function (n) { + var r, + e, + i, + t = this[0]; + return arguments.length + ? ((i = m(n)), + this.each(function (e) { + var t; + 1 === this.nodeType && + (null == (t = i ? n.call(this, e, S(this).val()) : n) + ? (t = '') + : 'number' == typeof t + ? (t += '') + : Array.isArray(t) && + (t = S.map(t, function (e) { + return null == e ? '' : e + ''; + })), + ((r = S.valHooks[this.type] || S.valHooks[this.nodeName.toLowerCase()]) && + 'set' in r && + void 0 !== r.set(this, t, 'value')) || + (this.value = t)); + })) + : t + ? (r = S.valHooks[t.type] || S.valHooks[t.nodeName.toLowerCase()]) && 'get' in r && void 0 !== (e = r.get(t, 'value')) + ? e + : 'string' == typeof (e = t.value) + ? e.replace(xt, '') + : null == e + ? '' + : e + : void 0; + }, + }), + S.extend({ + valHooks: { + option: { + get: function (e) { + var t = S.find.attr(e, 'value'); + return null != t ? t : vt(S.text(e)); + }, + }, + select: { + get: function (e) { + var t, + n, + r, + i = e.options, + o = e.selectedIndex, + a = 'select-one' === e.type, + s = a ? null : [], + u = a ? o + 1 : i.length; + for (r = o < 0 ? u : a ? o : 0; r < u; r++) + if (((n = i[r]).selected || r === o) && !n.disabled && (!n.parentNode.disabled || !A(n.parentNode, 'optgroup'))) { + if (((t = S(n).val()), a)) return t; + s.push(t); + } + return s; + }, + set: function (e, t) { + var n, + r, + i = e.options, + o = S.makeArray(t), + a = i.length; + while (a--) ((r = i[a]).selected = -1 < S.inArray(S.valHooks.option.get(r), o)) && (n = !0); + return n || (e.selectedIndex = -1), o; + }, + }, + }, + }), + S.each(['radio', 'checkbox'], function () { + (S.valHooks[this] = { + set: function (e, t) { + if (Array.isArray(t)) return (e.checked = -1 < S.inArray(S(e).val(), t)); + }, + }), + y.checkOn || + (S.valHooks[this].get = function (e) { + return null === e.getAttribute('value') ? 'on' : e.value; + }); + }), + (y.focusin = 'onfocusin' in C); + var bt = /^(?:focusinfocus|focusoutblur)$/, + wt = function (e) { + e.stopPropagation(); + }; + S.extend(S.event, { + trigger: function (e, t, n, r) { + var i, + o, + a, + s, + u, + l, + c, + f, + p = [n || E], + d = v.call(e, 'type') ? e.type : e, + h = v.call(e, 'namespace') ? e.namespace.split('.') : []; + if ( + ((o = f = a = n = n || E), + 3 !== n.nodeType && + 8 !== n.nodeType && + !bt.test(d + S.event.triggered) && + (-1 < d.indexOf('.') && ((d = (h = d.split('.')).shift()), h.sort()), + (u = d.indexOf(':') < 0 && 'on' + d), + ((e = e[S.expando] ? e : new S.Event(d, 'object' == typeof e && e)).isTrigger = r ? 2 : 3), + (e.namespace = h.join('.')), + (e.rnamespace = e.namespace ? new RegExp('(^|\\.)' + h.join('\\.(?:.*\\.|)') + '(\\.|$)') : null), + (e.result = void 0), + e.target || (e.target = n), + (t = null == t ? [e] : S.makeArray(t, [e])), + (c = S.event.special[d] || {}), + r || !c.trigger || !1 !== c.trigger.apply(n, t))) + ) { + if (!r && !c.noBubble && !x(n)) { + for (s = c.delegateType || d, bt.test(s + d) || (o = o.parentNode); o; o = o.parentNode) p.push(o), (a = o); + a === (n.ownerDocument || E) && p.push(a.defaultView || a.parentWindow || C); + } + i = 0; + while ((o = p[i++]) && !e.isPropagationStopped()) + (f = o), + (e.type = 1 < i ? s : c.bindType || d), + (l = (Y.get(o, 'events') || Object.create(null))[e.type] && Y.get(o, 'handle')) && l.apply(o, t), + (l = u && o[u]) && l.apply && V(o) && ((e.result = l.apply(o, t)), !1 === e.result && e.preventDefault()); + return ( + (e.type = d), + r || + e.isDefaultPrevented() || + (c._default && !1 !== c._default.apply(p.pop(), t)) || + !V(n) || + (u && + m(n[d]) && + !x(n) && + ((a = n[u]) && (n[u] = null), + (S.event.triggered = d), + e.isPropagationStopped() && f.addEventListener(d, wt), + n[d](), + e.isPropagationStopped() && f.removeEventListener(d, wt), + (S.event.triggered = void 0), + a && (n[u] = a))), + e.result + ); + } + }, + simulate: function (e, t, n) { + var r = S.extend(new S.Event(), n, { type: e, isSimulated: !0 }); + S.event.trigger(r, null, t); + }, + }), + S.fn.extend({ + trigger: function (e, t) { + return this.each(function () { + S.event.trigger(e, t, this); + }); + }, + triggerHandler: function (e, t) { + var n = this[0]; + if (n) return S.event.trigger(e, t, n, !0); + }, + }), + y.focusin || + S.each({ focus: 'focusin', blur: 'focusout' }, function (n, r) { + var i = function (e) { + S.event.simulate(r, e.target, S.event.fix(e)); + }; + S.event.special[r] = { + setup: function () { + var e = this.ownerDocument || this.document || this, + t = Y.access(e, r); + t || e.addEventListener(n, i, !0), Y.access(e, r, (t || 0) + 1); + }, + teardown: function () { + var e = this.ownerDocument || this.document || this, + t = Y.access(e, r) - 1; + t ? Y.access(e, r, t) : (e.removeEventListener(n, i, !0), Y.remove(e, r)); + }, + }; + }); + var Tt = C.location, + Ct = { guid: Date.now() }, + Et = /\?/; + S.parseXML = function (e) { + var t; + if (!e || 'string' != typeof e) return null; + try { + t = new C.DOMParser().parseFromString(e, 'text/xml'); + } catch (e) { + t = void 0; + } + return (t && !t.getElementsByTagName('parsererror').length) || S.error('Invalid XML: ' + e), t; + }; + var St = /\[\]$/, + kt = /\r?\n/g, + At = /^(?:submit|button|image|reset|file)$/i, + Nt = /^(?:input|select|textarea|keygen)/i; + function Dt(n, e, r, i) { + var t; + if (Array.isArray(e)) + S.each(e, function (e, t) { + r || St.test(n) ? i(n, t) : Dt(n + '[' + ('object' == typeof t && null != t ? e : '') + ']', t, r, i); + }); + else if (r || 'object' !== w(e)) i(n, e); + else for (t in e) Dt(n + '[' + t + ']', e[t], r, i); + } + (S.param = function (e, t) { + var n, + r = [], + i = function (e, t) { + var n = m(t) ? t() : t; + r[r.length] = encodeURIComponent(e) + '=' + encodeURIComponent(null == n ? '' : n); + }; + if (null == e) return ''; + if (Array.isArray(e) || (e.jquery && !S.isPlainObject(e))) + S.each(e, function () { + i(this.name, this.value); + }); + else for (n in e) Dt(n, e[n], t, i); + return r.join('&'); + }), + S.fn.extend({ + serialize: function () { + return S.param(this.serializeArray()); + }, + serializeArray: function () { + return this.map(function () { + var e = S.prop(this, 'elements'); + return e ? S.makeArray(e) : this; + }) + .filter(function () { + var e = this.type; + return this.name && !S(this).is(':disabled') && Nt.test(this.nodeName) && !At.test(e) && (this.checked || !pe.test(e)); + }) + .map(function (e, t) { + var n = S(this).val(); + return null == n + ? null + : Array.isArray(n) + ? S.map(n, function (e) { + return { name: t.name, value: e.replace(kt, '\r\n') }; + }) + : { name: t.name, value: n.replace(kt, '\r\n') }; + }) + .get(); + }, + }); + var jt = /%20/g, + qt = /#.*$/, + Lt = /([?&])_=[^&]*/, + Ht = /^(.*?):[ \t]*([^\r\n]*)$/gm, + Ot = /^(?:GET|HEAD)$/, + Pt = /^\/\//, + Rt = {}, + Mt = {}, + It = '*/'.concat('*'), + Wt = E.createElement('a'); + function Ft(o) { + return function (e, t) { + 'string' != typeof e && ((t = e), (e = '*')); + var n, + r = 0, + i = e.toLowerCase().match(P) || []; + if (m(t)) while ((n = i[r++])) '+' === n[0] ? ((n = n.slice(1) || '*'), (o[n] = o[n] || []).unshift(t)) : (o[n] = o[n] || []).push(t); + }; + } + function Bt(t, i, o, a) { + var s = {}, + u = t === Mt; + function l(e) { + var r; + return ( + (s[e] = !0), + S.each(t[e] || [], function (e, t) { + var n = t(i, o, a); + return 'string' != typeof n || u || s[n] ? (u ? !(r = n) : void 0) : (i.dataTypes.unshift(n), l(n), !1); + }), + r + ); + } + return l(i.dataTypes[0]) || (!s['*'] && l('*')); + } + function $t(e, t) { + var n, + r, + i = S.ajaxSettings.flatOptions || {}; + for (n in t) void 0 !== t[n] && ((i[n] ? e : r || (r = {}))[n] = t[n]); + return r && S.extend(!0, e, r), e; + } + (Wt.href = Tt.href), + S.extend({ + active: 0, + lastModified: {}, + etag: {}, + ajaxSettings: { + url: Tt.href, + type: 'GET', + isLocal: /^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(Tt.protocol), + global: !0, + processData: !0, + async: !0, + contentType: 'application/x-www-form-urlencoded; charset=UTF-8', + accepts: { + '*': It, + text: 'text/plain', + html: 'text/html', + xml: 'application/xml, text/xml', + json: 'application/json, text/javascript', + }, + contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, + responseFields: { xml: 'responseXML', text: 'responseText', json: 'responseJSON' }, + converters: { '* text': String, 'text html': !0, 'text json': JSON.parse, 'text xml': S.parseXML }, + flatOptions: { url: !0, context: !0 }, + }, + ajaxSetup: function (e, t) { + return t ? $t($t(e, S.ajaxSettings), t) : $t(S.ajaxSettings, e); + }, + ajaxPrefilter: Ft(Rt), + ajaxTransport: Ft(Mt), + ajax: function (e, t) { + 'object' == typeof e && ((t = e), (e = void 0)), (t = t || {}); + var c, + f, + p, + n, + d, + r, + h, + g, + i, + o, + v = S.ajaxSetup({}, t), + y = v.context || v, + m = v.context && (y.nodeType || y.jquery) ? S(y) : S.event, + x = S.Deferred(), + b = S.Callbacks('once memory'), + w = v.statusCode || {}, + a = {}, + s = {}, + u = 'canceled', + T = { + readyState: 0, + getResponseHeader: function (e) { + var t; + if (h) { + if (!n) { + n = {}; + while ((t = Ht.exec(p))) n[t[1].toLowerCase() + ' '] = (n[t[1].toLowerCase() + ' '] || []).concat(t[2]); + } + t = n[e.toLowerCase() + ' ']; + } + return null == t ? null : t.join(', '); + }, + getAllResponseHeaders: function () { + return h ? p : null; + }, + setRequestHeader: function (e, t) { + return null == h && ((e = s[e.toLowerCase()] = s[e.toLowerCase()] || e), (a[e] = t)), this; + }, + overrideMimeType: function (e) { + return null == h && (v.mimeType = e), this; + }, + statusCode: function (e) { + var t; + if (e) + if (h) T.always(e[T.status]); + else for (t in e) w[t] = [w[t], e[t]]; + return this; + }, + abort: function (e) { + var t = e || u; + return c && c.abort(t), l(0, t), this; + }, + }; + if ( + (x.promise(T), + (v.url = ((e || v.url || Tt.href) + '').replace(Pt, Tt.protocol + '//')), + (v.type = t.method || t.type || v.method || v.type), + (v.dataTypes = (v.dataType || '*').toLowerCase().match(P) || ['']), + null == v.crossDomain) + ) { + r = E.createElement('a'); + try { + (r.href = v.url), (r.href = r.href), (v.crossDomain = Wt.protocol + '//' + Wt.host != r.protocol + '//' + r.host); + } catch (e) { + v.crossDomain = !0; + } + } + if ((v.data && v.processData && 'string' != typeof v.data && (v.data = S.param(v.data, v.traditional)), Bt(Rt, v, t, T), h)) + return T; + for (i in ((g = S.event && v.global) && 0 == S.active++ && S.event.trigger('ajaxStart'), + (v.type = v.type.toUpperCase()), + (v.hasContent = !Ot.test(v.type)), + (f = v.url.replace(qt, '')), + v.hasContent + ? v.data && + v.processData && + 0 === (v.contentType || '').indexOf('application/x-www-form-urlencoded') && + (v.data = v.data.replace(jt, '+')) + : ((o = v.url.slice(f.length)), + v.data && (v.processData || 'string' == typeof v.data) && ((f += (Et.test(f) ? '&' : '?') + v.data), delete v.data), + !1 === v.cache && ((f = f.replace(Lt, '$1')), (o = (Et.test(f) ? '&' : '?') + '_=' + Ct.guid++ + o)), + (v.url = f + o)), + v.ifModified && + (S.lastModified[f] && T.setRequestHeader('If-Modified-Since', S.lastModified[f]), + S.etag[f] && T.setRequestHeader('If-None-Match', S.etag[f])), + ((v.data && v.hasContent && !1 !== v.contentType) || t.contentType) && T.setRequestHeader('Content-Type', v.contentType), + T.setRequestHeader( + 'Accept', + v.dataTypes[0] && v.accepts[v.dataTypes[0]] + ? v.accepts[v.dataTypes[0]] + ('*' !== v.dataTypes[0] ? ', ' + It + '; q=0.01' : '') + : v.accepts['*'] + ), + v.headers)) + T.setRequestHeader(i, v.headers[i]); + if (v.beforeSend && (!1 === v.beforeSend.call(y, T, v) || h)) return T.abort(); + if (((u = 'abort'), b.add(v.complete), T.done(v.success), T.fail(v.error), (c = Bt(Mt, v, t, T)))) { + if (((T.readyState = 1), g && m.trigger('ajaxSend', [T, v]), h)) return T; + v.async && + 0 < v.timeout && + (d = C.setTimeout(function () { + T.abort('timeout'); + }, v.timeout)); + try { + (h = !1), c.send(a, l); + } catch (e) { + if (h) throw e; + l(-1, e); + } + } else l(-1, 'No Transport'); + function l(e, t, n, r) { + var i, + o, + a, + s, + u, + l = t; + h || + ((h = !0), + d && C.clearTimeout(d), + (c = void 0), + (p = r || ''), + (T.readyState = 0 < e ? 4 : 0), + (i = (200 <= e && e < 300) || 304 === e), + n && + (s = (function (e, t, n) { + var r, + i, + o, + a, + s = e.contents, + u = e.dataTypes; + while ('*' === u[0]) u.shift(), void 0 === r && (r = e.mimeType || t.getResponseHeader('Content-Type')); + if (r) + for (i in s) + if (s[i] && s[i].test(r)) { + u.unshift(i); + break; + } + if (u[0] in n) o = u[0]; + else { + for (i in n) { + if (!u[0] || e.converters[i + ' ' + u[0]]) { + o = i; + break; + } + a || (a = i); + } + o = o || a; + } + if (o) return o !== u[0] && u.unshift(o), n[o]; + })(v, T, n)), + !i && -1 < S.inArray('script', v.dataTypes) && (v.converters['text script'] = function () {}), + (s = (function (e, t, n, r) { + var i, + o, + a, + s, + u, + l = {}, + c = e.dataTypes.slice(); + if (c[1]) for (a in e.converters) l[a.toLowerCase()] = e.converters[a]; + o = c.shift(); + while (o) + if ( + (e.responseFields[o] && (n[e.responseFields[o]] = t), + !u && r && e.dataFilter && (t = e.dataFilter(t, e.dataType)), + (u = o), + (o = c.shift())) + ) + if ('*' === o) o = u; + else if ('*' !== u && u !== o) { + if (!(a = l[u + ' ' + o] || l['* ' + o])) + for (i in l) + if ((s = i.split(' '))[1] === o && (a = l[u + ' ' + s[0]] || l['* ' + s[0]])) { + !0 === a ? (a = l[i]) : !0 !== l[i] && ((o = s[0]), c.unshift(s[1])); + break; + } + if (!0 !== a) + if (a && e['throws']) t = a(t); + else + try { + t = a(t); + } catch (e) { + return { state: 'parsererror', error: a ? e : 'No conversion from ' + u + ' to ' + o }; + } + } + return { state: 'success', data: t }; + })(v, s, T, i)), + i + ? (v.ifModified && + ((u = T.getResponseHeader('Last-Modified')) && (S.lastModified[f] = u), + (u = T.getResponseHeader('etag')) && (S.etag[f] = u)), + 204 === e || 'HEAD' === v.type + ? (l = 'nocontent') + : 304 === e + ? (l = 'notmodified') + : ((l = s.state), (o = s.data), (i = !(a = s.error)))) + : ((a = l), (!e && l) || ((l = 'error'), e < 0 && (e = 0))), + (T.status = e), + (T.statusText = (t || l) + ''), + i ? x.resolveWith(y, [o, l, T]) : x.rejectWith(y, [T, l, a]), + T.statusCode(w), + (w = void 0), + g && m.trigger(i ? 'ajaxSuccess' : 'ajaxError', [T, v, i ? o : a]), + b.fireWith(y, [T, l]), + g && (m.trigger('ajaxComplete', [T, v]), --S.active || S.event.trigger('ajaxStop'))); + } + return T; + }, + getJSON: function (e, t, n) { + return S.get(e, t, n, 'json'); + }, + getScript: function (e, t) { + return S.get(e, void 0, t, 'script'); + }, + }), + S.each(['get', 'post'], function (e, i) { + S[i] = function (e, t, n, r) { + return ( + m(t) && ((r = r || n), (n = t), (t = void 0)), + S.ajax(S.extend({ url: e, type: i, dataType: r, data: t, success: n }, S.isPlainObject(e) && e)) + ); + }; + }), + S.ajaxPrefilter(function (e) { + var t; + for (t in e.headers) 'content-type' === t.toLowerCase() && (e.contentType = e.headers[t] || ''); + }), + (S._evalUrl = function (e, t, n) { + return S.ajax({ + url: e, + type: 'GET', + dataType: 'script', + cache: !0, + async: !1, + global: !1, + converters: { 'text script': function () {} }, + dataFilter: function (e) { + S.globalEval(e, t, n); + }, + }); + }), + S.fn.extend({ + wrapAll: function (e) { + var t; + return ( + this[0] && + (m(e) && (e = e.call(this[0])), + (t = S(e, this[0].ownerDocument).eq(0).clone(!0)), + this[0].parentNode && t.insertBefore(this[0]), + t + .map(function () { + var e = this; + while (e.firstElementChild) e = e.firstElementChild; + return e; + }) + .append(this)), + this + ); + }, + wrapInner: function (n) { + return m(n) + ? this.each(function (e) { + S(this).wrapInner(n.call(this, e)); + }) + : this.each(function () { + var e = S(this), + t = e.contents(); + t.length ? t.wrapAll(n) : e.append(n); + }); + }, + wrap: function (t) { + var n = m(t); + return this.each(function (e) { + S(this).wrapAll(n ? t.call(this, e) : t); + }); + }, + unwrap: function (e) { + return ( + this.parent(e) + .not('body') + .each(function () { + S(this).replaceWith(this.childNodes); + }), + this + ); + }, + }), + (S.expr.pseudos.hidden = function (e) { + return !S.expr.pseudos.visible(e); + }), + (S.expr.pseudos.visible = function (e) { + return !!(e.offsetWidth || e.offsetHeight || e.getClientRects().length); + }), + (S.ajaxSettings.xhr = function () { + try { + return new C.XMLHttpRequest(); + } catch (e) {} + }); + var _t = { 0: 200, 1223: 204 }, + zt = S.ajaxSettings.xhr(); + (y.cors = !!zt && 'withCredentials' in zt), + (y.ajax = zt = !!zt), + S.ajaxTransport(function (i) { + var o, a; + if (y.cors || (zt && !i.crossDomain)) + return { + send: function (e, t) { + var n, + r = i.xhr(); + if ((r.open(i.type, i.url, i.async, i.username, i.password), i.xhrFields)) for (n in i.xhrFields) r[n] = i.xhrFields[n]; + for (n in (i.mimeType && r.overrideMimeType && r.overrideMimeType(i.mimeType), + i.crossDomain || e['X-Requested-With'] || (e['X-Requested-With'] = 'XMLHttpRequest'), + e)) + r.setRequestHeader(n, e[n]); + (o = function (e) { + return function () { + o && + ((o = a = r.onload = r.onerror = r.onabort = r.ontimeout = r.onreadystatechange = null), + 'abort' === e + ? r.abort() + : 'error' === e + ? 'number' != typeof r.status + ? t(0, 'error') + : t(r.status, r.statusText) + : t( + _t[r.status] || r.status, + r.statusText, + 'text' !== (r.responseType || 'text') || 'string' != typeof r.responseText + ? { binary: r.response } + : { text: r.responseText }, + r.getAllResponseHeaders() + )); + }; + }), + (r.onload = o()), + (a = r.onerror = r.ontimeout = o('error')), + void 0 !== r.onabort + ? (r.onabort = a) + : (r.onreadystatechange = function () { + 4 === r.readyState && + C.setTimeout(function () { + o && a(); + }); + }), + (o = o('abort')); + try { + r.send((i.hasContent && i.data) || null); + } catch (e) { + if (o) throw e; + } + }, + abort: function () { + o && o(); + }, + }; + }), + S.ajaxPrefilter(function (e) { + e.crossDomain && (e.contents.script = !1); + }), + S.ajaxSetup({ + accepts: { script: 'text/javascript, application/javascript, application/ecmascript, application/x-ecmascript' }, + contents: { script: /\b(?:java|ecma)script\b/ }, + converters: { + 'text script': function (e) { + return S.globalEval(e), e; + }, + }, + }), + S.ajaxPrefilter('script', function (e) { + void 0 === e.cache && (e.cache = !1), e.crossDomain && (e.type = 'GET'); + }), + S.ajaxTransport('script', function (n) { + var r, i; + if (n.crossDomain || n.scriptAttrs) + return { + send: function (e, t) { + (r = S('<script>') + .attr(n.scriptAttrs || {}) + .prop({ charset: n.scriptCharset, src: n.url }) + .on( + 'load error', + (i = function (e) { + r.remove(), (i = null), e && t('error' === e.type ? 404 : 200, e.type); + }) + )), + E.head.appendChild(r[0]); + }, + abort: function () { + i && i(); + }, + }; + }); + var Ut, + Xt = [], + Vt = /(=)\?(?=&|$)|\?\?/; + S.ajaxSetup({ + jsonp: 'callback', + jsonpCallback: function () { + var e = Xt.pop() || S.expando + '_' + Ct.guid++; + return (this[e] = !0), e; + }, + }), + S.ajaxPrefilter('json jsonp', function (e, t, n) { + var r, + i, + o, + a = + !1 !== e.jsonp && + (Vt.test(e.url) + ? 'url' + : 'string' == typeof e.data && + 0 === (e.contentType || '').indexOf('application/x-www-form-urlencoded') && + Vt.test(e.data) && + 'data'); + if (a || 'jsonp' === e.dataTypes[0]) + return ( + (r = e.jsonpCallback = m(e.jsonpCallback) ? e.jsonpCallback() : e.jsonpCallback), + a ? (e[a] = e[a].replace(Vt, '$1' + r)) : !1 !== e.jsonp && (e.url += (Et.test(e.url) ? '&' : '?') + e.jsonp + '=' + r), + (e.converters['script json'] = function () { + return o || S.error(r + ' was not called'), o[0]; + }), + (e.dataTypes[0] = 'json'), + (i = C[r]), + (C[r] = function () { + o = arguments; + }), + n.always(function () { + void 0 === i ? S(C).removeProp(r) : (C[r] = i), + e[r] && ((e.jsonpCallback = t.jsonpCallback), Xt.push(r)), + o && m(i) && i(o[0]), + (o = i = void 0); + }), + 'script' + ); + }), + (y.createHTMLDocument = + (((Ut = E.implementation.createHTMLDocument('').body).innerHTML = '<form></form><form></form>'), 2 === Ut.childNodes.length)), + (S.parseHTML = function (e, t, n) { + return 'string' != typeof e + ? [] + : ('boolean' == typeof t && ((n = t), (t = !1)), + t || + (y.createHTMLDocument + ? (((r = (t = E.implementation.createHTMLDocument('')).createElement('base')).href = E.location.href), t.head.appendChild(r)) + : (t = E)), + (o = !n && []), + (i = N.exec(e)) ? [t.createElement(i[1])] : ((i = xe([e], t, o)), o && o.length && S(o).remove(), S.merge([], i.childNodes))); + var r, i, o; + }), + (S.fn.load = function (e, t, n) { + var r, + i, + o, + a = this, + s = e.indexOf(' '); + return ( + -1 < s && ((r = vt(e.slice(s))), (e = e.slice(0, s))), + m(t) ? ((n = t), (t = void 0)) : t && 'object' == typeof t && (i = 'POST'), + 0 < a.length && + S.ajax({ url: e, type: i || 'GET', dataType: 'html', data: t }) + .done(function (e) { + (o = arguments), a.html(r ? S('<div>').append(S.parseHTML(e)).find(r) : e); + }) + .always( + n && + function (e, t) { + a.each(function () { + n.apply(this, o || [e.responseText, t, e]); + }); + } + ), + this + ); + }), + (S.expr.pseudos.animated = function (t) { + return S.grep(S.timers, function (e) { + return t === e.elem; + }).length; + }), + (S.offset = { + setOffset: function (e, t, n) { + var r, + i, + o, + a, + s, + u, + l = S.css(e, 'position'), + c = S(e), + f = {}; + 'static' === l && (e.style.position = 'relative'), + (s = c.offset()), + (o = S.css(e, 'top')), + (u = S.css(e, 'left')), + ('absolute' === l || 'fixed' === l) && -1 < (o + u).indexOf('auto') + ? ((a = (r = c.position()).top), (i = r.left)) + : ((a = parseFloat(o) || 0), (i = parseFloat(u) || 0)), + m(t) && (t = t.call(e, n, S.extend({}, s))), + null != t.top && (f.top = t.top - s.top + a), + null != t.left && (f.left = t.left - s.left + i), + 'using' in t + ? t.using.call(e, f) + : ('number' == typeof f.top && (f.top += 'px'), 'number' == typeof f.left && (f.left += 'px'), c.css(f)); + }, + }), + S.fn.extend({ + offset: function (t) { + if (arguments.length) + return void 0 === t + ? this + : this.each(function (e) { + S.offset.setOffset(this, t, e); + }); + var e, + n, + r = this[0]; + return r + ? r.getClientRects().length + ? ((e = r.getBoundingClientRect()), + (n = r.ownerDocument.defaultView), + { top: e.top + n.pageYOffset, left: e.left + n.pageXOffset }) + : { top: 0, left: 0 } + : void 0; + }, + position: function () { + if (this[0]) { + var e, + t, + n, + r = this[0], + i = { top: 0, left: 0 }; + if ('fixed' === S.css(r, 'position')) t = r.getBoundingClientRect(); + else { + (t = this.offset()), (n = r.ownerDocument), (e = r.offsetParent || n.documentElement); + while (e && (e === n.body || e === n.documentElement) && 'static' === S.css(e, 'position')) e = e.parentNode; + e && + e !== r && + 1 === e.nodeType && + (((i = S(e).offset()).top += S.css(e, 'borderTopWidth', !0)), (i.left += S.css(e, 'borderLeftWidth', !0))); + } + return { top: t.top - i.top - S.css(r, 'marginTop', !0), left: t.left - i.left - S.css(r, 'marginLeft', !0) }; + } + }, + offsetParent: function () { + return this.map(function () { + var e = this.offsetParent; + while (e && 'static' === S.css(e, 'position')) e = e.offsetParent; + return e || re; + }); + }, + }), + S.each({ scrollLeft: 'pageXOffset', scrollTop: 'pageYOffset' }, function (t, i) { + var o = 'pageYOffset' === i; + S.fn[t] = function (e) { + return $( + this, + function (e, t, n) { + var r; + if ((x(e) ? (r = e) : 9 === e.nodeType && (r = e.defaultView), void 0 === n)) return r ? r[i] : e[t]; + r ? r.scrollTo(o ? r.pageXOffset : n, o ? n : r.pageYOffset) : (e[t] = n); + }, + t, + e, + arguments.length + ); + }; + }), + S.each(['top', 'left'], function (e, n) { + S.cssHooks[n] = $e(y.pixelPosition, function (e, t) { + if (t) return (t = Be(e, n)), Me.test(t) ? S(e).position()[n] + 'px' : t; + }); + }), + S.each({ Height: 'height', Width: 'width' }, function (a, s) { + S.each({ padding: 'inner' + a, content: s, '': 'outer' + a }, function (r, o) { + S.fn[o] = function (e, t) { + var n = arguments.length && (r || 'boolean' != typeof e), + i = r || (!0 === e || !0 === t ? 'margin' : 'border'); + return $( + this, + function (e, t, n) { + var r; + return x(e) + ? 0 === o.indexOf('outer') + ? e['inner' + a] + : e.document.documentElement['client' + a] + : 9 === e.nodeType + ? ((r = e.documentElement), + Math.max(e.body['scroll' + a], r['scroll' + a], e.body['offset' + a], r['offset' + a], r['client' + a])) + : void 0 === n + ? S.css(e, t, i) + : S.style(e, t, n, i); + }, + s, + n ? e : void 0, + n + ); + }; + }); + }), + S.each(['ajaxStart', 'ajaxStop', 'ajaxComplete', 'ajaxError', 'ajaxSuccess', 'ajaxSend'], function (e, t) { + S.fn[t] = function (e) { + return this.on(t, e); + }; + }), + S.fn.extend({ + bind: function (e, t, n) { + return this.on(e, null, t, n); + }, + unbind: function (e, t) { + return this.off(e, null, t); + }, + delegate: function (e, t, n, r) { + return this.on(t, e, n, r); + }, + undelegate: function (e, t, n) { + return 1 === arguments.length ? this.off(e, '**') : this.off(t, e || '**', n); + }, + hover: function (e, t) { + return this.mouseenter(e).mouseleave(t || e); + }, + }), + S.each( + 'blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu'.split( + ' ' + ), + function (e, n) { + S.fn[n] = function (e, t) { + return 0 < arguments.length ? this.on(n, null, e, t) : this.trigger(n); + }; + } + ); + var Gt = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; + (S.proxy = function (e, t) { + var n, r, i; + if (('string' == typeof t && ((n = e[t]), (t = e), (e = n)), m(e))) + return ( + (r = s.call(arguments, 2)), + ((i = function () { + return e.apply(t || this, r.concat(s.call(arguments))); + }).guid = e.guid = + e.guid || S.guid++), + i + ); + }), + (S.holdReady = function (e) { + e ? S.readyWait++ : S.ready(!0); + }), + (S.isArray = Array.isArray), + (S.parseJSON = JSON.parse), + (S.nodeName = A), + (S.isFunction = m), + (S.isWindow = x), + (S.camelCase = X), + (S.type = w), + (S.now = Date.now), + (S.isNumeric = function (e) { + var t = S.type(e); + return ('number' === t || 'string' === t) && !isNaN(e - parseFloat(e)); + }), + (S.trim = function (e) { + return null == e ? '' : (e + '').replace(Gt, ''); + }), + 'function' == typeof define && + define.amd && + define('jquery', [], function () { + return S; + }); + var Yt = C.jQuery, + Qt = C.$; + return ( + (S.noConflict = function (e) { + return C.$ === S && (C.$ = Qt), e && C.jQuery === S && (C.jQuery = Yt), S; + }), + 'undefined' == typeof e && (C.jQuery = C.$ = S), + S + ); +}); diff --git a/src/main/webapp/content/js/popper1.16.0.min.js b/src/main/webapp/content/js/popper1.16.0.min.js index 8a17212f7dba4ce8b961eff7efe8ef5ba8c60844..239553c03426893f509be57ff1a4fb0aeb9db0cd 100644 --- a/src/main/webapp/content/js/popper1.16.0.min.js +++ b/src/main/webapp/content/js/popper1.16.0.min.js @@ -1,5 +1,964 @@ /* Copyright (C) Federico Zivolo 2019 Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). - */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function i(e){return e&&e.referenceNode?e.referenceNode:e}function r(e){return 11===e?re:10===e?pe:re||pe}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1<arguments.length&&void 0!==arguments[1]?arguments[1]:'top',o='top'===t?'scrollTop':'scrollLeft',n=e.nodeName;if('BODY'===n||'HTML'===n){var i=e.ownerDocument.documentElement,r=e.ownerDocument.scrollingElement||i;return r[o]}return e[o]}function f(e,t){var o=2<arguments.length&&void 0!==arguments[2]&&arguments[2],n=l(t,'top'),i=l(t,'left'),r=o?-1:1;return e.top+=n*r,e.bottom+=n*r,e.left+=i*r,e.right+=i*r,e}function m(e,t){var o='x'===t?'Left':'Top',n='Left'==o?'Right':'Bottom';return parseFloat(e['border'+o+'Width'],10)+parseFloat(e['border'+n+'Width'],10)}function h(e,t,o,n){return ee(t['offset'+e],t['scroll'+e],o['client'+e],o['offset'+e],o['scroll'+e],r(10)?parseInt(o['offset'+e])+parseInt(n['margin'+('Height'===e?'Top':'Left')])+parseInt(n['margin'+('Height'===e?'Bottom':'Right')]):0)}function c(e){var t=e.body,o=e.documentElement,n=r(10)&&getComputedStyle(o);return{height:h('Height',t,o,n),width:h('Width',t,o,n)}}function g(e){return le({},e,{right:e.left+e.width,bottom:e.top+e.height})}function u(e){var o={};try{if(r(10)){o=e.getBoundingClientRect();var n=l(e,'top'),i=l(e,'left');o.top+=n,o.left+=i,o.bottom+=n,o.right+=i}else o=e.getBoundingClientRect()}catch(t){}var p={left:o.left,top:o.top,width:o.right-o.left,height:o.bottom-o.top},s='HTML'===e.nodeName?c(e.ownerDocument):{},d=s.width||e.clientWidth||p.width,a=s.height||e.clientHeight||p.height,f=e.offsetWidth-d,h=e.offsetHeight-a;if(f||h){var u=t(e);f-=m(u,'x'),h-=m(u,'y'),p.width-=f,p.height-=h}return g(p)}function b(e,o){var i=2<arguments.length&&void 0!==arguments[2]&&arguments[2],p=r(10),s='HTML'===o.nodeName,d=u(e),a=u(o),l=n(e),m=t(o),h=parseFloat(m.borderTopWidth,10),c=parseFloat(m.borderLeftWidth,10);i&&s&&(a.top=ee(a.top,0),a.left=ee(a.left,0));var b=g({top:d.top-a.top-h,left:d.left-a.left-c,width:d.width,height:d.height});if(b.marginTop=0,b.marginLeft=0,!p&&s){var w=parseFloat(m.marginTop,10),y=parseFloat(m.marginLeft,10);b.top-=h-w,b.bottom-=h-w,b.left-=c-y,b.right-=c-y,b.marginTop=w,b.marginLeft=y}return(p&&!i?o.contains(l):o===l&&'BODY'!==l.nodeName)&&(b=f(b,o)),b}function w(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=e.ownerDocument.documentElement,n=b(e,o),i=ee(o.clientWidth,window.innerWidth||0),r=ee(o.clientHeight,window.innerHeight||0),p=t?0:l(o),s=t?0:l(o,'left'),d={top:p-n.top+n.marginTop,left:s-n.left+n.marginLeft,width:i,height:r};return g(d)}function y(e){var n=e.nodeName;if('BODY'===n||'HTML'===n)return!1;if('fixed'===t(e,'position'))return!0;var i=o(e);return!!i&&y(i)}function E(e){if(!e||!e.parentElement||r())return document.documentElement;for(var o=e.parentElement;o&&'none'===t(o,'transform');)o=o.parentElement;return o||document.documentElement}function v(e,t,r,p){var s=4<arguments.length&&void 0!==arguments[4]&&arguments[4],d={top:0,left:0},l=s?E(e):a(e,i(t));if('viewport'===p)d=w(l,s);else{var f;'scrollParent'===p?(f=n(o(t)),'BODY'===f.nodeName&&(f=e.ownerDocument.documentElement)):'window'===p?f=e.ownerDocument.documentElement:f=p;var m=b(f,l,s);if('HTML'===f.nodeName&&!y(l)){var h=c(e.ownerDocument),g=h.height,u=h.width;d.top+=m.top-m.marginTop,d.bottom=g+m.top,d.left+=m.left-m.marginLeft,d.right=u+m.left}else d=m}r=r||0;var v='number'==typeof r;return d.left+=v?r:r.left||0,d.top+=v?r:r.top||0,d.right-=v?r:r.right||0,d.bottom-=v?r:r.bottom||0,d}function x(e){var t=e.width,o=e.height;return t*o}function O(e,t,o,n,i){var r=5<arguments.length&&void 0!==arguments[5]?arguments[5]:0;if(-1===e.indexOf('auto'))return e;var p=v(o,n,r,i),s={top:{width:p.width,height:t.top-p.top},right:{width:p.right-t.right,height:p.height},bottom:{width:p.width,height:p.bottom-t.bottom},left:{width:t.left-p.left,height:p.height}},d=Object.keys(s).map(function(e){return le({key:e},s[e],{area:x(s[e])})}).sort(function(e,t){return t.area-e.area}),a=d.filter(function(e){var t=e.width,n=e.height;return t>=o.clientWidth&&n>=o.clientHeight}),l=0<a.length?a[0].key:d[0].key,f=e.split('-')[1];return l+(f?'-'+f:'')}function L(e,t,o){var n=3<arguments.length&&void 0!==arguments[3]?arguments[3]:null,r=n?E(t):a(t,i(o));return b(o,r,n)}function S(e){var t=e.ownerDocument.defaultView,o=t.getComputedStyle(e),n=parseFloat(o.marginTop||0)+parseFloat(o.marginBottom||0),i=parseFloat(o.marginLeft||0)+parseFloat(o.marginRight||0),r={width:e.offsetWidth+i,height:e.offsetHeight+n};return r}function T(e){var t={left:'right',right:'left',bottom:'top',top:'bottom'};return e.replace(/left|right|bottom|top/g,function(e){return t[e]})}function C(e,t,o){o=o.split('-')[0];var n=S(e),i={width:n.width,height:n.height},r=-1!==['right','left'].indexOf(o),p=r?'top':'left',s=r?'left':'top',d=r?'height':'width',a=r?'width':'height';return i[p]=t[p]+t[d]/2-n[d]/2,i[s]=o===s?t[s]-n[a]:t[T(s)],i}function D(e,t){return Array.prototype.find?e.find(t):e.filter(t)[0]}function N(e,t,o){if(Array.prototype.findIndex)return e.findIndex(function(e){return e[t]===o});var n=D(e,function(e){return e[t]===o});return e.indexOf(n)}function P(t,o,n){var i=void 0===n?t:t.slice(0,N(t,'name',n));return i.forEach(function(t){t['function']&&console.warn('`modifier.function` is deprecated, use `modifier.fn`!');var n=t['function']||t.fn;t.enabled&&e(n)&&(o.offsets.popper=g(o.offsets.popper),o.offsets.reference=g(o.offsets.reference),o=n(o,t))}),o}function k(){if(!this.state.isDestroyed){var e={instance:this,styles:{},arrowStyles:{},attributes:{},flipped:!1,offsets:{}};e.offsets.reference=L(this.state,this.popper,this.reference,this.options.positionFixed),e.placement=O(this.options.placement,e.offsets.reference,this.popper,this.reference,this.options.modifiers.flip.boundariesElement,this.options.modifiers.flip.padding),e.originalPlacement=e.placement,e.positionFixed=this.options.positionFixed,e.offsets.popper=C(this.popper,e.offsets.reference,e.placement),e.offsets.popper.position=this.options.positionFixed?'fixed':'absolute',e=P(this.modifiers,e),this.state.isCreated?this.options.onUpdate(e):(this.state.isCreated=!0,this.options.onCreate(e))}}function W(e,t){return e.some(function(e){var o=e.name,n=e.enabled;return n&&o===t})}function B(e){for(var t=[!1,'ms','Webkit','Moz','O'],o=e.charAt(0).toUpperCase()+e.slice(1),n=0;n<t.length;n++){var i=t[n],r=i?''+i+o:e;if('undefined'!=typeof document.body.style[r])return r}return null}function H(){return this.state.isDestroyed=!0,W(this.modifiers,'applyStyle')&&(this.popper.removeAttribute('x-placement'),this.popper.style.position='',this.popper.style.top='',this.popper.style.left='',this.popper.style.right='',this.popper.style.bottom='',this.popper.style.willChange='',this.popper.style[B('transform')]=''),this.disableEventListeners(),this.options.removeOnDestroy&&this.popper.parentNode.removeChild(this.popper),this}function A(e){var t=e.ownerDocument;return t?t.defaultView:window}function M(e,t,o,i){var r='BODY'===e.nodeName,p=r?e.ownerDocument.defaultView:e;p.addEventListener(t,o,{passive:!0}),r||M(n(p.parentNode),t,o,i),i.push(p)}function F(e,t,o,i){o.updateBound=i,A(e).addEventListener('resize',o.updateBound,{passive:!0});var r=n(e);return M(r,'scroll',o.updateBound,o.scrollParents),o.scrollElement=r,o.eventsEnabled=!0,o}function I(){this.state.eventsEnabled||(this.state=F(this.reference,this.options,this.state,this.scheduleUpdate))}function R(e,t){return A(e).removeEventListener('resize',t.updateBound),t.scrollParents.forEach(function(e){e.removeEventListener('scroll',t.updateBound)}),t.updateBound=null,t.scrollParents=[],t.scrollElement=null,t.eventsEnabled=!1,t}function U(){this.state.eventsEnabled&&(cancelAnimationFrame(this.scheduleUpdate),this.state=R(this.reference,this.state))}function Y(e){return''!==e&&!isNaN(parseFloat(e))&&isFinite(e)}function V(e,t){Object.keys(t).forEach(function(o){var n='';-1!==['width','height','top','right','bottom','left'].indexOf(o)&&Y(t[o])&&(n='px'),e.style[o]=t[o]+n})}function j(e,t){Object.keys(t).forEach(function(o){var n=t[o];!1===n?e.removeAttribute(o):e.setAttribute(o,t[o])})}function q(e,t){var o=e.offsets,n=o.popper,i=o.reference,r=$,p=function(e){return e},s=r(i.width),d=r(n.width),a=-1!==['left','right'].indexOf(e.placement),l=-1!==e.placement.indexOf('-'),f=t?a||l||s%2==d%2?r:Z:p,m=t?r:p;return{left:f(1==s%2&&1==d%2&&!l&&t?n.left-1:n.left),top:m(n.top),bottom:m(n.bottom),right:f(n.right)}}function K(e,t,o){var n=D(e,function(e){var o=e.name;return o===t}),i=!!n&&e.some(function(e){return e.name===o&&e.enabled&&e.order<n.order});if(!i){var r='`'+t+'`';console.warn('`'+o+'`'+' modifier is required by '+r+' modifier in order to work, be sure to include it before '+r+'!')}return i}function z(e){return'end'===e?'start':'start'===e?'end':e}function G(e){var t=1<arguments.length&&void 0!==arguments[1]&&arguments[1],o=he.indexOf(e),n=he.slice(o+1).concat(he.slice(0,o));return t?n.reverse():n}function _(e,t,o,n){var i=e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/),r=+i[1],p=i[2];if(!r)return e;if(0===p.indexOf('%')){var s;switch(p){case'%p':s=o;break;case'%':case'%r':default:s=n;}var d=g(s);return d[t]/100*r}if('vh'===p||'vw'===p){var a;return a='vh'===p?ee(document.documentElement.clientHeight,window.innerHeight||0):ee(document.documentElement.clientWidth,window.innerWidth||0),a/100*r}return r}function X(e,t,o,n){var i=[0,0],r=-1!==['right','left'].indexOf(n),p=e.split(/(\+|\-)/).map(function(e){return e.trim()}),s=p.indexOf(D(p,function(e){return-1!==e.search(/,|\s/)}));p[s]&&-1===p[s].indexOf(',')&&console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');var d=/\s*,\s*|\s+/,a=-1===s?[p]:[p.slice(0,s).concat([p[s].split(d)[0]]),[p[s].split(d)[1]].concat(p.slice(s+1))];return a=a.map(function(e,n){var i=(1===n?!r:r)?'height':'width',p=!1;return e.reduce(function(e,t){return''===e[e.length-1]&&-1!==['+','-'].indexOf(t)?(e[e.length-1]=t,p=!0,e):p?(e[e.length-1]+=t,p=!1,e):e.concat(t)},[]).map(function(e){return _(e,i,t,o)})}),a.forEach(function(e,t){e.forEach(function(o,n){Y(o)&&(i[t]+=o*('-'===e[n-1]?-1:1))})}),i}function J(e,t){var o,n=t.offset,i=e.placement,r=e.offsets,p=r.popper,s=r.reference,d=i.split('-')[0];return o=Y(+n)?[+n,0]:X(n,p,s,d),'left'===d?(p.top+=o[0],p.left-=o[1]):'right'===d?(p.top+=o[0],p.left+=o[1]):'top'===d?(p.left+=o[0],p.top-=o[1]):'bottom'===d&&(p.left+=o[0],p.top+=o[1]),e.popper=p,e}var Q=Math.min,Z=Math.floor,$=Math.round,ee=Math.max,te='undefined'!=typeof window&&'undefined'!=typeof document&&'undefined'!=typeof navigator,oe=function(){for(var e=['Edge','Trident','Firefox'],t=0;t<e.length;t+=1)if(te&&0<=navigator.userAgent.indexOf(e[t]))return 1;return 0}(),ne=te&&window.Promise,ie=ne?function(e){var t=!1;return function(){t||(t=!0,window.Promise.resolve().then(function(){t=!1,e()}))}}:function(e){var t=!1;return function(){t||(t=!0,setTimeout(function(){t=!1,e()},oe))}},re=te&&!!(window.MSInputMethodContext&&document.documentMode),pe=te&&/MSIE 10/.test(navigator.userAgent),se=function(e,t){if(!(e instanceof t))throw new TypeError('Cannot call a class as a function')},de=function(){function e(e,t){for(var o,n=0;n<t.length;n++)o=t[n],o.enumerable=o.enumerable||!1,o.configurable=!0,'value'in o&&(o.writable=!0),Object.defineProperty(e,o.key,o)}return function(t,o,n){return o&&e(t.prototype,o),n&&e(t,n),t}}(),ae=function(e,t,o){return t in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e},le=Object.assign||function(e){for(var t,o=1;o<arguments.length;o++)for(var n in t=arguments[o],t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n]);return e},fe=te&&/Firefox/i.test(navigator.userAgent),me=['auto-start','auto','auto-end','top-start','top','top-end','right-start','right','right-end','bottom-end','bottom','bottom-start','left-end','left','left-start'],he=me.slice(3),ce={FLIP:'flip',CLOCKWISE:'clockwise',COUNTERCLOCKWISE:'counterclockwise'},ge=function(){function t(o,n){var i=this,r=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{};se(this,t),this.scheduleUpdate=function(){return requestAnimationFrame(i.update)},this.update=ie(this.update.bind(this)),this.options=le({},t.Defaults,r),this.state={isDestroyed:!1,isCreated:!1,scrollParents:[]},this.reference=o&&o.jquery?o[0]:o,this.popper=n&&n.jquery?n[0]:n,this.options.modifiers={},Object.keys(le({},t.Defaults.modifiers,r.modifiers)).forEach(function(e){i.options.modifiers[e]=le({},t.Defaults.modifiers[e]||{},r.modifiers?r.modifiers[e]:{})}),this.modifiers=Object.keys(this.options.modifiers).map(function(e){return le({name:e},i.options.modifiers[e])}).sort(function(e,t){return e.order-t.order}),this.modifiers.forEach(function(t){t.enabled&&e(t.onLoad)&&t.onLoad(i.reference,i.popper,i.options,t,i.state)}),this.update();var p=this.options.eventsEnabled;p&&this.enableEventListeners(),this.state.eventsEnabled=p}return de(t,[{key:'update',value:function(){return k.call(this)}},{key:'destroy',value:function(){return H.call(this)}},{key:'enableEventListeners',value:function(){return I.call(this)}},{key:'disableEventListeners',value:function(){return U.call(this)}}]),t}();return ge.Utils=('undefined'==typeof window?global:window).PopperUtils,ge.placements=me,ge.Defaults={placement:'bottom',positionFixed:!1,eventsEnabled:!0,removeOnDestroy:!1,onCreate:function(){},onUpdate:function(){},modifiers:{shift:{order:100,enabled:!0,fn:function(e){var t=e.placement,o=t.split('-')[0],n=t.split('-')[1];if(n){var i=e.offsets,r=i.reference,p=i.popper,s=-1!==['bottom','top'].indexOf(o),d=s?'left':'top',a=s?'width':'height',l={start:ae({},d,r[d]),end:ae({},d,r[d]+r[a]-p[a])};e.offsets.popper=le({},p,l[n])}return e}},offset:{order:200,enabled:!0,fn:J,offset:0},preventOverflow:{order:300,enabled:!0,fn:function(e,t){var o=t.boundariesElement||p(e.instance.popper);e.instance.reference===o&&(o=p(o));var n=B('transform'),i=e.instance.popper.style,r=i.top,s=i.left,d=i[n];i.top='',i.left='',i[n]='';var a=v(e.instance.popper,e.instance.reference,t.padding,o,e.positionFixed);i.top=r,i.left=s,i[n]=d,t.boundaries=a;var l=t.priority,f=e.offsets.popper,m={primary:function(e){var o=f[e];return f[e]<a[e]&&!t.escapeWithReference&&(o=ee(f[e],a[e])),ae({},e,o)},secondary:function(e){var o='right'===e?'left':'top',n=f[o];return f[e]>a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),ae({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=le({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]<r(n[d])&&(e.offsets.popper[d]=r(n[d])-o[a]),o[d]>r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-u<s[m]&&(e.offsets.popper[m]-=s[m]-(d[c]-u)),d[m]+u>s[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},ae(n,m,$(v)),ae(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ce.FLIP:p=[n,i];break;case ce.CLOCKWISE:p=G(n);break;case ce.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)<f(l.right)||'top'===n&&f(a.bottom)>f(l.top)||'bottom'===n&&f(a.top)<f(l.bottom),h=f(a.left)<f(o.left),c=f(a.right)>f(o.right),g=f(a.top)<f(o.top),u=f(a.bottom)>f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=le({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottom<o.top||t.left>o.right||t.top>o.bottom||t.right<o.left){if(!0===e.hide)return e;e.hide=!0,e.attributes['x-out-of-boundaries']=''}else{if(!1===e.hide)return e;e.hide=!1,e.attributes['x-out-of-boundaries']=!1}return e}},computeStyle:{order:850,enabled:!0,fn:function(e,t){var o=t.x,n=t.y,i=e.offsets.popper,r=D(e.instance.modifiers,function(e){return'applyStyle'===e.name}).gpuAcceleration;void 0!==r&&console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!');var s,d,a=void 0===r?t.gpuAcceleration:r,l=p(e.instance.popper),f=u(l),m={position:i.position},h=q(e,2>window.devicePixelRatio||!fe),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=le({},E,e.attributes),e.styles=le({},m,e.styles),e.arrowStyles=le({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ge}); + */ (function (e, t) { + 'object' == typeof exports && 'undefined' != typeof module + ? (module.exports = t()) + : 'function' == typeof define && define.amd + ? define(t) + : (e.Popper = t()); +})(this, function () { + 'use strict'; + function e(e) { + return e && '[object Function]' === {}.toString.call(e); + } + function t(e, t) { + if (1 !== e.nodeType) return []; + var o = e.ownerDocument.defaultView, + n = o.getComputedStyle(e, null); + return t ? n[t] : n; + } + function o(e) { + return 'HTML' === e.nodeName ? e : e.parentNode || e.host; + } + function n(e) { + if (!e) return document.body; + switch (e.nodeName) { + case 'HTML': + case 'BODY': + return e.ownerDocument.body; + case '#document': + return e.body; + } + var i = t(e), + r = i.overflow, + p = i.overflowX, + s = i.overflowY; + return /(auto|scroll|overlay)/.test(r + s + p) ? e : n(o(e)); + } + function i(e) { + return e && e.referenceNode ? e.referenceNode : e; + } + function r(e) { + return 11 === e ? re : 10 === e ? pe : re || pe; + } + function p(e) { + if (!e) return document.documentElement; + for (var o = r(10) ? document.body : null, n = e.offsetParent || null; n === o && e.nextElementSibling; ) + n = (e = e.nextElementSibling).offsetParent; + var i = n && n.nodeName; + return i && 'BODY' !== i && 'HTML' !== i + ? -1 !== ['TH', 'TD', 'TABLE'].indexOf(n.nodeName) && 'static' === t(n, 'position') + ? p(n) + : n + : e + ? e.ownerDocument.documentElement + : document.documentElement; + } + function s(e) { + var t = e.nodeName; + return 'BODY' !== t && ('HTML' === t || p(e.firstElementChild) === e); + } + function d(e) { + return null === e.parentNode ? e : d(e.parentNode); + } + function a(e, t) { + if (!e || !e.nodeType || !t || !t.nodeType) return document.documentElement; + var o = e.compareDocumentPosition(t) & Node.DOCUMENT_POSITION_FOLLOWING, + n = o ? e : t, + i = o ? t : e, + r = document.createRange(); + r.setStart(n, 0), r.setEnd(i, 0); + var l = r.commonAncestorContainer; + if ((e !== l && t !== l) || n.contains(i)) return s(l) ? l : p(l); + var f = d(e); + return f.host ? a(f.host, t) : a(e, d(t).host); + } + function l(e) { + var t = 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : 'top', + o = 'top' === t ? 'scrollTop' : 'scrollLeft', + n = e.nodeName; + if ('BODY' === n || 'HTML' === n) { + var i = e.ownerDocument.documentElement, + r = e.ownerDocument.scrollingElement || i; + return r[o]; + } + return e[o]; + } + function f(e, t) { + var o = 2 < arguments.length && void 0 !== arguments[2] && arguments[2], + n = l(t, 'top'), + i = l(t, 'left'), + r = o ? -1 : 1; + return (e.top += n * r), (e.bottom += n * r), (e.left += i * r), (e.right += i * r), e; + } + function m(e, t) { + var o = 'x' === t ? 'Left' : 'Top', + n = 'Left' == o ? 'Right' : 'Bottom'; + return parseFloat(e['border' + o + 'Width'], 10) + parseFloat(e['border' + n + 'Width'], 10); + } + function h(e, t, o, n) { + return ee( + t['offset' + e], + t['scroll' + e], + o['client' + e], + o['offset' + e], + o['scroll' + e], + r(10) + ? parseInt(o['offset' + e]) + + parseInt(n['margin' + ('Height' === e ? 'Top' : 'Left')]) + + parseInt(n['margin' + ('Height' === e ? 'Bottom' : 'Right')]) + : 0 + ); + } + function c(e) { + var t = e.body, + o = e.documentElement, + n = r(10) && getComputedStyle(o); + return { height: h('Height', t, o, n), width: h('Width', t, o, n) }; + } + function g(e) { + return le({}, e, { right: e.left + e.width, bottom: e.top + e.height }); + } + function u(e) { + var o = {}; + try { + if (r(10)) { + o = e.getBoundingClientRect(); + var n = l(e, 'top'), + i = l(e, 'left'); + (o.top += n), (o.left += i), (o.bottom += n), (o.right += i); + } else o = e.getBoundingClientRect(); + } catch (t) {} + var p = { left: o.left, top: o.top, width: o.right - o.left, height: o.bottom - o.top }, + s = 'HTML' === e.nodeName ? c(e.ownerDocument) : {}, + d = s.width || e.clientWidth || p.width, + a = s.height || e.clientHeight || p.height, + f = e.offsetWidth - d, + h = e.offsetHeight - a; + if (f || h) { + var u = t(e); + (f -= m(u, 'x')), (h -= m(u, 'y')), (p.width -= f), (p.height -= h); + } + return g(p); + } + function b(e, o) { + var i = 2 < arguments.length && void 0 !== arguments[2] && arguments[2], + p = r(10), + s = 'HTML' === o.nodeName, + d = u(e), + a = u(o), + l = n(e), + m = t(o), + h = parseFloat(m.borderTopWidth, 10), + c = parseFloat(m.borderLeftWidth, 10); + i && s && ((a.top = ee(a.top, 0)), (a.left = ee(a.left, 0))); + var b = g({ top: d.top - a.top - h, left: d.left - a.left - c, width: d.width, height: d.height }); + if (((b.marginTop = 0), (b.marginLeft = 0), !p && s)) { + var w = parseFloat(m.marginTop, 10), + y = parseFloat(m.marginLeft, 10); + (b.top -= h - w), (b.bottom -= h - w), (b.left -= c - y), (b.right -= c - y), (b.marginTop = w), (b.marginLeft = y); + } + return (p && !i ? o.contains(l) : o === l && 'BODY' !== l.nodeName) && (b = f(b, o)), b; + } + function w(e) { + var t = 1 < arguments.length && void 0 !== arguments[1] && arguments[1], + o = e.ownerDocument.documentElement, + n = b(e, o), + i = ee(o.clientWidth, window.innerWidth || 0), + r = ee(o.clientHeight, window.innerHeight || 0), + p = t ? 0 : l(o), + s = t ? 0 : l(o, 'left'), + d = { top: p - n.top + n.marginTop, left: s - n.left + n.marginLeft, width: i, height: r }; + return g(d); + } + function y(e) { + var n = e.nodeName; + if ('BODY' === n || 'HTML' === n) return !1; + if ('fixed' === t(e, 'position')) return !0; + var i = o(e); + return !!i && y(i); + } + function E(e) { + if (!e || !e.parentElement || r()) return document.documentElement; + for (var o = e.parentElement; o && 'none' === t(o, 'transform'); ) o = o.parentElement; + return o || document.documentElement; + } + function v(e, t, r, p) { + var s = 4 < arguments.length && void 0 !== arguments[4] && arguments[4], + d = { top: 0, left: 0 }, + l = s ? E(e) : a(e, i(t)); + if ('viewport' === p) d = w(l, s); + else { + var f; + 'scrollParent' === p + ? ((f = n(o(t))), 'BODY' === f.nodeName && (f = e.ownerDocument.documentElement)) + : 'window' === p + ? (f = e.ownerDocument.documentElement) + : (f = p); + var m = b(f, l, s); + if ('HTML' === f.nodeName && !y(l)) { + var h = c(e.ownerDocument), + g = h.height, + u = h.width; + (d.top += m.top - m.marginTop), (d.bottom = g + m.top), (d.left += m.left - m.marginLeft), (d.right = u + m.left); + } else d = m; + } + r = r || 0; + var v = 'number' == typeof r; + return ( + (d.left += v ? r : r.left || 0), + (d.top += v ? r : r.top || 0), + (d.right -= v ? r : r.right || 0), + (d.bottom -= v ? r : r.bottom || 0), + d + ); + } + function x(e) { + var t = e.width, + o = e.height; + return t * o; + } + function O(e, t, o, n, i) { + var r = 5 < arguments.length && void 0 !== arguments[5] ? arguments[5] : 0; + if (-1 === e.indexOf('auto')) return e; + var p = v(o, n, r, i), + s = { + top: { width: p.width, height: t.top - p.top }, + right: { width: p.right - t.right, height: p.height }, + bottom: { width: p.width, height: p.bottom - t.bottom }, + left: { width: t.left - p.left, height: p.height }, + }, + d = Object.keys(s) + .map(function (e) { + return le({ key: e }, s[e], { area: x(s[e]) }); + }) + .sort(function (e, t) { + return t.area - e.area; + }), + a = d.filter(function (e) { + var t = e.width, + n = e.height; + return t >= o.clientWidth && n >= o.clientHeight; + }), + l = 0 < a.length ? a[0].key : d[0].key, + f = e.split('-')[1]; + return l + (f ? '-' + f : ''); + } + function L(e, t, o) { + var n = 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null, + r = n ? E(t) : a(t, i(o)); + return b(o, r, n); + } + function S(e) { + var t = e.ownerDocument.defaultView, + o = t.getComputedStyle(e), + n = parseFloat(o.marginTop || 0) + parseFloat(o.marginBottom || 0), + i = parseFloat(o.marginLeft || 0) + parseFloat(o.marginRight || 0), + r = { width: e.offsetWidth + i, height: e.offsetHeight + n }; + return r; + } + function T(e) { + var t = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' }; + return e.replace(/left|right|bottom|top/g, function (e) { + return t[e]; + }); + } + function C(e, t, o) { + o = o.split('-')[0]; + var n = S(e), + i = { width: n.width, height: n.height }, + r = -1 !== ['right', 'left'].indexOf(o), + p = r ? 'top' : 'left', + s = r ? 'left' : 'top', + d = r ? 'height' : 'width', + a = r ? 'width' : 'height'; + return (i[p] = t[p] + t[d] / 2 - n[d] / 2), (i[s] = o === s ? t[s] - n[a] : t[T(s)]), i; + } + function D(e, t) { + return Array.prototype.find ? e.find(t) : e.filter(t)[0]; + } + function N(e, t, o) { + if (Array.prototype.findIndex) + return e.findIndex(function (e) { + return e[t] === o; + }); + var n = D(e, function (e) { + return e[t] === o; + }); + return e.indexOf(n); + } + function P(t, o, n) { + var i = void 0 === n ? t : t.slice(0, N(t, 'name', n)); + return ( + i.forEach(function (t) { + t['function'] && console.warn('`modifier.function` is deprecated, use `modifier.fn`!'); + var n = t['function'] || t.fn; + t.enabled && e(n) && ((o.offsets.popper = g(o.offsets.popper)), (o.offsets.reference = g(o.offsets.reference)), (o = n(o, t))); + }), + o + ); + } + function k() { + if (!this.state.isDestroyed) { + var e = { instance: this, styles: {}, arrowStyles: {}, attributes: {}, flipped: !1, offsets: {} }; + (e.offsets.reference = L(this.state, this.popper, this.reference, this.options.positionFixed)), + (e.placement = O( + this.options.placement, + e.offsets.reference, + this.popper, + this.reference, + this.options.modifiers.flip.boundariesElement, + this.options.modifiers.flip.padding + )), + (e.originalPlacement = e.placement), + (e.positionFixed = this.options.positionFixed), + (e.offsets.popper = C(this.popper, e.offsets.reference, e.placement)), + (e.offsets.popper.position = this.options.positionFixed ? 'fixed' : 'absolute'), + (e = P(this.modifiers, e)), + this.state.isCreated ? this.options.onUpdate(e) : ((this.state.isCreated = !0), this.options.onCreate(e)); + } + } + function W(e, t) { + return e.some(function (e) { + var o = e.name, + n = e.enabled; + return n && o === t; + }); + } + function B(e) { + for (var t = [!1, 'ms', 'Webkit', 'Moz', 'O'], o = e.charAt(0).toUpperCase() + e.slice(1), n = 0; n < t.length; n++) { + var i = t[n], + r = i ? '' + i + o : e; + if ('undefined' != typeof document.body.style[r]) return r; + } + return null; + } + function H() { + return ( + (this.state.isDestroyed = !0), + W(this.modifiers, 'applyStyle') && + (this.popper.removeAttribute('x-placement'), + (this.popper.style.position = ''), + (this.popper.style.top = ''), + (this.popper.style.left = ''), + (this.popper.style.right = ''), + (this.popper.style.bottom = ''), + (this.popper.style.willChange = ''), + (this.popper.style[B('transform')] = '')), + this.disableEventListeners(), + this.options.removeOnDestroy && this.popper.parentNode.removeChild(this.popper), + this + ); + } + function A(e) { + var t = e.ownerDocument; + return t ? t.defaultView : window; + } + function M(e, t, o, i) { + var r = 'BODY' === e.nodeName, + p = r ? e.ownerDocument.defaultView : e; + p.addEventListener(t, o, { passive: !0 }), r || M(n(p.parentNode), t, o, i), i.push(p); + } + function F(e, t, o, i) { + (o.updateBound = i), A(e).addEventListener('resize', o.updateBound, { passive: !0 }); + var r = n(e); + return M(r, 'scroll', o.updateBound, o.scrollParents), (o.scrollElement = r), (o.eventsEnabled = !0), o; + } + function I() { + this.state.eventsEnabled || (this.state = F(this.reference, this.options, this.state, this.scheduleUpdate)); + } + function R(e, t) { + return ( + A(e).removeEventListener('resize', t.updateBound), + t.scrollParents.forEach(function (e) { + e.removeEventListener('scroll', t.updateBound); + }), + (t.updateBound = null), + (t.scrollParents = []), + (t.scrollElement = null), + (t.eventsEnabled = !1), + t + ); + } + function U() { + this.state.eventsEnabled && (cancelAnimationFrame(this.scheduleUpdate), (this.state = R(this.reference, this.state))); + } + function Y(e) { + return '' !== e && !isNaN(parseFloat(e)) && isFinite(e); + } + function V(e, t) { + Object.keys(t).forEach(function (o) { + var n = ''; + -1 !== ['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(o) && Y(t[o]) && (n = 'px'), (e.style[o] = t[o] + n); + }); + } + function j(e, t) { + Object.keys(t).forEach(function (o) { + var n = t[o]; + !1 === n ? e.removeAttribute(o) : e.setAttribute(o, t[o]); + }); + } + function q(e, t) { + var o = e.offsets, + n = o.popper, + i = o.reference, + r = $, + p = function (e) { + return e; + }, + s = r(i.width), + d = r(n.width), + a = -1 !== ['left', 'right'].indexOf(e.placement), + l = -1 !== e.placement.indexOf('-'), + f = t ? (a || l || s % 2 == d % 2 ? r : Z) : p, + m = t ? r : p; + return { left: f(1 == s % 2 && 1 == d % 2 && !l && t ? n.left - 1 : n.left), top: m(n.top), bottom: m(n.bottom), right: f(n.right) }; + } + function K(e, t, o) { + var n = D(e, function (e) { + var o = e.name; + return o === t; + }), + i = + !!n && + e.some(function (e) { + return e.name === o && e.enabled && e.order < n.order; + }); + if (!i) { + var r = '`' + t + '`'; + console.warn('`' + o + '`' + ' modifier is required by ' + r + ' modifier in order to work, be sure to include it before ' + r + '!'); + } + return i; + } + function z(e) { + return 'end' === e ? 'start' : 'start' === e ? 'end' : e; + } + function G(e) { + var t = 1 < arguments.length && void 0 !== arguments[1] && arguments[1], + o = he.indexOf(e), + n = he.slice(o + 1).concat(he.slice(0, o)); + return t ? n.reverse() : n; + } + function _(e, t, o, n) { + var i = e.match(/((?:\-|\+)?\d*\.?\d*)(.*)/), + r = +i[1], + p = i[2]; + if (!r) return e; + if (0 === p.indexOf('%')) { + var s; + switch (p) { + case '%p': + s = o; + break; + case '%': + case '%r': + default: + s = n; + } + var d = g(s); + return (d[t] / 100) * r; + } + if ('vh' === p || 'vw' === p) { + var a; + return ( + (a = + 'vh' === p + ? ee(document.documentElement.clientHeight, window.innerHeight || 0) + : ee(document.documentElement.clientWidth, window.innerWidth || 0)), + (a / 100) * r + ); + } + return r; + } + function X(e, t, o, n) { + var i = [0, 0], + r = -1 !== ['right', 'left'].indexOf(n), + p = e.split(/(\+|\-)/).map(function (e) { + return e.trim(); + }), + s = p.indexOf( + D(p, function (e) { + return -1 !== e.search(/,|\s/); + }) + ); + p[s] && -1 === p[s].indexOf(',') && console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.'); + var d = /\s*,\s*|\s+/, + a = -1 === s ? [p] : [p.slice(0, s).concat([p[s].split(d)[0]]), [p[s].split(d)[1]].concat(p.slice(s + 1))]; + return ( + (a = a.map(function (e, n) { + var i = (1 === n ? !r : r) ? 'height' : 'width', + p = !1; + return e + .reduce(function (e, t) { + return '' === e[e.length - 1] && -1 !== ['+', '-'].indexOf(t) + ? ((e[e.length - 1] = t), (p = !0), e) + : p + ? ((e[e.length - 1] += t), (p = !1), e) + : e.concat(t); + }, []) + .map(function (e) { + return _(e, i, t, o); + }); + })), + a.forEach(function (e, t) { + e.forEach(function (o, n) { + Y(o) && (i[t] += o * ('-' === e[n - 1] ? -1 : 1)); + }); + }), + i + ); + } + function J(e, t) { + var o, + n = t.offset, + i = e.placement, + r = e.offsets, + p = r.popper, + s = r.reference, + d = i.split('-')[0]; + return ( + (o = Y(+n) ? [+n, 0] : X(n, p, s, d)), + 'left' === d + ? ((p.top += o[0]), (p.left -= o[1])) + : 'right' === d + ? ((p.top += o[0]), (p.left += o[1])) + : 'top' === d + ? ((p.left += o[0]), (p.top -= o[1])) + : 'bottom' === d && ((p.left += o[0]), (p.top += o[1])), + (e.popper = p), + e + ); + } + var Q = Math.min, + Z = Math.floor, + $ = Math.round, + ee = Math.max, + te = 'undefined' != typeof window && 'undefined' != typeof document && 'undefined' != typeof navigator, + oe = (function () { + for (var e = ['Edge', 'Trident', 'Firefox'], t = 0; t < e.length; t += 1) if (te && 0 <= navigator.userAgent.indexOf(e[t])) return 1; + return 0; + })(), + ne = te && window.Promise, + ie = ne + ? function (e) { + var t = !1; + return function () { + t || + ((t = !0), + window.Promise.resolve().then(function () { + (t = !1), e(); + })); + }; + } + : function (e) { + var t = !1; + return function () { + t || + ((t = !0), + setTimeout(function () { + (t = !1), e(); + }, oe)); + }; + }, + re = te && !!(window.MSInputMethodContext && document.documentMode), + pe = te && /MSIE 10/.test(navigator.userAgent), + se = function (e, t) { + if (!(e instanceof t)) throw new TypeError('Cannot call a class as a function'); + }, + de = (function () { + function e(e, t) { + for (var o, n = 0; n < t.length; n++) + (o = t[n]), + (o.enumerable = o.enumerable || !1), + (o.configurable = !0), + 'value' in o && (o.writable = !0), + Object.defineProperty(e, o.key, o); + } + return function (t, o, n) { + return o && e(t.prototype, o), n && e(t, n), t; + }; + })(), + ae = function (e, t, o) { + return t in e ? Object.defineProperty(e, t, { value: o, enumerable: !0, configurable: !0, writable: !0 }) : (e[t] = o), e; + }, + le = + Object.assign || + function (e) { + for (var t, o = 1; o < arguments.length; o++) + for (var n in ((t = arguments[o]), t)) Object.prototype.hasOwnProperty.call(t, n) && (e[n] = t[n]); + return e; + }, + fe = te && /Firefox/i.test(navigator.userAgent), + me = [ + 'auto-start', + 'auto', + 'auto-end', + 'top-start', + 'top', + 'top-end', + 'right-start', + 'right', + 'right-end', + 'bottom-end', + 'bottom', + 'bottom-start', + 'left-end', + 'left', + 'left-start', + ], + he = me.slice(3), + ce = { FLIP: 'flip', CLOCKWISE: 'clockwise', COUNTERCLOCKWISE: 'counterclockwise' }, + ge = (function () { + function t(o, n) { + var i = this, + r = 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : {}; + se(this, t), + (this.scheduleUpdate = function () { + return requestAnimationFrame(i.update); + }), + (this.update = ie(this.update.bind(this))), + (this.options = le({}, t.Defaults, r)), + (this.state = { isDestroyed: !1, isCreated: !1, scrollParents: [] }), + (this.reference = o && o.jquery ? o[0] : o), + (this.popper = n && n.jquery ? n[0] : n), + (this.options.modifiers = {}), + Object.keys(le({}, t.Defaults.modifiers, r.modifiers)).forEach(function (e) { + i.options.modifiers[e] = le({}, t.Defaults.modifiers[e] || {}, r.modifiers ? r.modifiers[e] : {}); + }), + (this.modifiers = Object.keys(this.options.modifiers) + .map(function (e) { + return le({ name: e }, i.options.modifiers[e]); + }) + .sort(function (e, t) { + return e.order - t.order; + })), + this.modifiers.forEach(function (t) { + t.enabled && e(t.onLoad) && t.onLoad(i.reference, i.popper, i.options, t, i.state); + }), + this.update(); + var p = this.options.eventsEnabled; + p && this.enableEventListeners(), (this.state.eventsEnabled = p); + } + return ( + de(t, [ + { + key: 'update', + value: function () { + return k.call(this); + }, + }, + { + key: 'destroy', + value: function () { + return H.call(this); + }, + }, + { + key: 'enableEventListeners', + value: function () { + return I.call(this); + }, + }, + { + key: 'disableEventListeners', + value: function () { + return U.call(this); + }, + }, + ]), + t + ); + })(); + return ( + (ge.Utils = ('undefined' == typeof window ? global : window).PopperUtils), + (ge.placements = me), + (ge.Defaults = { + placement: 'bottom', + positionFixed: !1, + eventsEnabled: !0, + removeOnDestroy: !1, + onCreate: function () {}, + onUpdate: function () {}, + modifiers: { + shift: { + order: 100, + enabled: !0, + fn: function (e) { + var t = e.placement, + o = t.split('-')[0], + n = t.split('-')[1]; + if (n) { + var i = e.offsets, + r = i.reference, + p = i.popper, + s = -1 !== ['bottom', 'top'].indexOf(o), + d = s ? 'left' : 'top', + a = s ? 'width' : 'height', + l = { start: ae({}, d, r[d]), end: ae({}, d, r[d] + r[a] - p[a]) }; + e.offsets.popper = le({}, p, l[n]); + } + return e; + }, + }, + offset: { order: 200, enabled: !0, fn: J, offset: 0 }, + preventOverflow: { + order: 300, + enabled: !0, + fn: function (e, t) { + var o = t.boundariesElement || p(e.instance.popper); + e.instance.reference === o && (o = p(o)); + var n = B('transform'), + i = e.instance.popper.style, + r = i.top, + s = i.left, + d = i[n]; + (i.top = ''), (i.left = ''), (i[n] = ''); + var a = v(e.instance.popper, e.instance.reference, t.padding, o, e.positionFixed); + (i.top = r), (i.left = s), (i[n] = d), (t.boundaries = a); + var l = t.priority, + f = e.offsets.popper, + m = { + primary: function (e) { + var o = f[e]; + return f[e] < a[e] && !t.escapeWithReference && (o = ee(f[e], a[e])), ae({}, e, o); + }, + secondary: function (e) { + var o = 'right' === e ? 'left' : 'top', + n = f[o]; + return f[e] > a[e] && !t.escapeWithReference && (n = Q(f[o], a[e] - ('right' === e ? f.width : f.height))), ae({}, o, n); + }, + }; + return ( + l.forEach(function (e) { + var t = -1 === ['left', 'top'].indexOf(e) ? 'secondary' : 'primary'; + f = le({}, f, m[t](e)); + }), + (e.offsets.popper = f), + e + ); + }, + priority: ['left', 'right', 'top', 'bottom'], + padding: 5, + boundariesElement: 'scrollParent', + }, + keepTogether: { + order: 400, + enabled: !0, + fn: function (e) { + var t = e.offsets, + o = t.popper, + n = t.reference, + i = e.placement.split('-')[0], + r = Z, + p = -1 !== ['top', 'bottom'].indexOf(i), + s = p ? 'right' : 'bottom', + d = p ? 'left' : 'top', + a = p ? 'width' : 'height'; + return o[s] < r(n[d]) && (e.offsets.popper[d] = r(n[d]) - o[a]), o[d] > r(n[s]) && (e.offsets.popper[d] = r(n[s])), e; + }, + }, + arrow: { + order: 500, + enabled: !0, + fn: function (e, o) { + var n; + if (!K(e.instance.modifiers, 'arrow', 'keepTogether')) return e; + var i = o.element; + if ('string' == typeof i) { + if (((i = e.instance.popper.querySelector(i)), !i)) return e; + } else if (!e.instance.popper.contains(i)) + return console.warn('WARNING: `arrow.element` must be child of its popper element!'), e; + var r = e.placement.split('-')[0], + p = e.offsets, + s = p.popper, + d = p.reference, + a = -1 !== ['left', 'right'].indexOf(r), + l = a ? 'height' : 'width', + f = a ? 'Top' : 'Left', + m = f.toLowerCase(), + h = a ? 'left' : 'top', + c = a ? 'bottom' : 'right', + u = S(i)[l]; + d[c] - u < s[m] && (e.offsets.popper[m] -= s[m] - (d[c] - u)), + d[m] + u > s[c] && (e.offsets.popper[m] += d[m] + u - s[c]), + (e.offsets.popper = g(e.offsets.popper)); + var b = d[m] + d[l] / 2 - u / 2, + w = t(e.instance.popper), + y = parseFloat(w['margin' + f], 10), + E = parseFloat(w['border' + f + 'Width'], 10), + v = b - e.offsets.popper[m] - y - E; + return (v = ee(Q(s[l] - u, v), 0)), (e.arrowElement = i), (e.offsets.arrow = ((n = {}), ae(n, m, $(v)), ae(n, h, ''), n)), e; + }, + element: '[x-arrow]', + }, + flip: { + order: 600, + enabled: !0, + fn: function (e, t) { + if (W(e.instance.modifiers, 'inner')) return e; + if (e.flipped && e.placement === e.originalPlacement) return e; + var o = v(e.instance.popper, e.instance.reference, t.padding, t.boundariesElement, e.positionFixed), + n = e.placement.split('-')[0], + i = T(n), + r = e.placement.split('-')[1] || '', + p = []; + switch (t.behavior) { + case ce.FLIP: + p = [n, i]; + break; + case ce.CLOCKWISE: + p = G(n); + break; + case ce.COUNTERCLOCKWISE: + p = G(n, !0); + break; + default: + p = t.behavior; + } + return ( + p.forEach(function (s, d) { + if (n !== s || p.length === d + 1) return e; + (n = e.placement.split('-')[0]), (i = T(n)); + var a = e.offsets.popper, + l = e.offsets.reference, + f = Z, + m = + ('left' === n && f(a.right) > f(l.left)) || + ('right' === n && f(a.left) < f(l.right)) || + ('top' === n && f(a.bottom) > f(l.top)) || + ('bottom' === n && f(a.top) < f(l.bottom)), + h = f(a.left) < f(o.left), + c = f(a.right) > f(o.right), + g = f(a.top) < f(o.top), + u = f(a.bottom) > f(o.bottom), + b = ('left' === n && h) || ('right' === n && c) || ('top' === n && g) || ('bottom' === n && u), + w = -1 !== ['top', 'bottom'].indexOf(n), + y = + !!t.flipVariations && + ((w && 'start' === r && h) || (w && 'end' === r && c) || (!w && 'start' === r && g) || (!w && 'end' === r && u)), + E = + !!t.flipVariationsByContent && + ((w && 'start' === r && c) || (w && 'end' === r && h) || (!w && 'start' === r && u) || (!w && 'end' === r && g)), + v = y || E; + (m || b || v) && + ((e.flipped = !0), + (m || b) && (n = p[d + 1]), + v && (r = z(r)), + (e.placement = n + (r ? '-' + r : '')), + (e.offsets.popper = le({}, e.offsets.popper, C(e.instance.popper, e.offsets.reference, e.placement))), + (e = P(e.instance.modifiers, e, 'flip'))); + }), + e + ); + }, + behavior: 'flip', + padding: 5, + boundariesElement: 'viewport', + flipVariations: !1, + flipVariationsByContent: !1, + }, + inner: { + order: 700, + enabled: !1, + fn: function (e) { + var t = e.placement, + o = t.split('-')[0], + n = e.offsets, + i = n.popper, + r = n.reference, + p = -1 !== ['left', 'right'].indexOf(o), + s = -1 === ['top', 'left'].indexOf(o); + return (i[p ? 'left' : 'top'] = r[o] - (s ? i[p ? 'width' : 'height'] : 0)), (e.placement = T(t)), (e.offsets.popper = g(i)), e; + }, + }, + hide: { + order: 800, + enabled: !0, + fn: function (e) { + if (!K(e.instance.modifiers, 'hide', 'preventOverflow')) return e; + var t = e.offsets.reference, + o = D(e.instance.modifiers, function (e) { + return 'preventOverflow' === e.name; + }).boundaries; + if (t.bottom < o.top || t.left > o.right || t.top > o.bottom || t.right < o.left) { + if (!0 === e.hide) return e; + (e.hide = !0), (e.attributes['x-out-of-boundaries'] = ''); + } else { + if (!1 === e.hide) return e; + (e.hide = !1), (e.attributes['x-out-of-boundaries'] = !1); + } + return e; + }, + }, + computeStyle: { + order: 850, + enabled: !0, + fn: function (e, t) { + var o = t.x, + n = t.y, + i = e.offsets.popper, + r = D(e.instance.modifiers, function (e) { + return 'applyStyle' === e.name; + }).gpuAcceleration; + void 0 !== r && + console.warn( + 'WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be supported in future versions of Popper.js!' + ); + var s, + d, + a = void 0 === r ? t.gpuAcceleration : r, + l = p(e.instance.popper), + f = u(l), + m = { position: i.position }, + h = q(e, 2 > window.devicePixelRatio || !fe), + c = 'bottom' === o ? 'top' : 'bottom', + g = 'right' === n ? 'left' : 'right', + b = B('transform'); + if ( + ((d = 'bottom' == c ? ('HTML' === l.nodeName ? -l.clientHeight + h.bottom : -f.height + h.bottom) : h.top), + (s = 'right' == g ? ('HTML' === l.nodeName ? -l.clientWidth + h.right : -f.width + h.right) : h.left), + a && b) + ) + (m[b] = 'translate3d(' + s + 'px, ' + d + 'px, 0)'), (m[c] = 0), (m[g] = 0), (m.willChange = 'transform'); + else { + var w = 'bottom' == c ? -1 : 1, + y = 'right' == g ? -1 : 1; + (m[c] = d * w), (m[g] = s * y), (m.willChange = c + ', ' + g); + } + var E = { 'x-placement': e.placement }; + return ( + (e.attributes = le({}, E, e.attributes)), + (e.styles = le({}, m, e.styles)), + (e.arrowStyles = le({}, e.offsets.arrow, e.arrowStyles)), + e + ); + }, + gpuAcceleration: !0, + x: 'bottom', + y: 'right', + }, + applyStyle: { + order: 900, + enabled: !0, + fn: function (e) { + return ( + V(e.instance.popper, e.styles), + j(e.instance.popper, e.attributes), + e.arrowElement && Object.keys(e.arrowStyles).length && V(e.arrowElement, e.arrowStyles), + e + ); + }, + onLoad: function (e, t, o, n, i) { + var r = L(i, t, e, o.positionFixed), + p = O(o.placement, r, t, e, o.modifiers.flip.boundariesElement, o.modifiers.flip.padding); + return t.setAttribute('x-placement', p), V(t, { position: o.positionFixed ? 'fixed' : 'absolute' }), o; + }, + gpuAcceleration: void 0, + }, + }, + }), + ge + ); +}); //# sourceMappingURL=popper.min.js.map diff --git a/src/main/webapp/content/scss/bootstrap4.5.2.min.scss b/src/main/webapp/content/scss/bootstrap4.5.2.min.scss index 21d10bad3e294f129ea09b9dc4e4d2f319fb8de5..175a98cefb7fb11657ace975b5f6a41cda6d228c 100644 --- a/src/main/webapp/content/scss/bootstrap4.5.2.min.scss +++ b/src/main/webapp/content/scss/bootstrap4.5.2.min.scss @@ -3,5 +3,9424 @@ * Copyright 2011-2020 The Bootstrap Authors * Copyright 2011-2020 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) - */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]){color:inherit;text-decoration:none}a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-sm-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-md-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-md-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-md-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-md-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-md-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-lg-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.row-cols-xl-1>*{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{-ms-flex:0 0 20%;flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}input[type=date].form-control,input[type=datetime-local].form-control,input[type=month].form-control,input[type=time].form-control{-webkit-appearance:none;-moz-appearance:none;appearance:none}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;left:0;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{color:#fff;background-color:#0069d9;border-color:#0062cc;box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{color:#fff;background-color:#5a6268;border-color:#545b62;box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{color:#fff;background-color:#218838;border-color:#1e7e34;box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{color:#fff;background-color:#138496;border-color:#117a8b;box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{color:#212529;background-color:#e0a800;border-color:#d39e00;box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{color:#fff;background-color:#c82333;border-color:#bd2130;box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{color:#212529;background-color:#e2e6ea;border-color:#dae0e5;box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{color:#fff;background-color:#23272b;border-color:#1d2124;box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;z-index:1;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before,.custom-control-input[disabled]~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1.4rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom,.card-img-top{-ms-flex-negative:0;flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img,.card-img-bottom{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{-ms-flex:1 0 0%;flex:1 0 0%;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item{display:-ms-flexbox;display:flex}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;line-height:0;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;overflow:hidden;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;border-radius:.25rem}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.list-group-item:last-child{border-bottom-right-radius:inherit;border-bottom-left-radius:inherit}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal>.list-group-item.active{margin-top:0}.list-group-horizontal>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm>.list-group-item.active{margin-top:0}.list-group-horizontal-sm>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md>.list-group-item.active{margin-top:0}.list-group-horizontal-md>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg>.list-group-item.active{margin-top:0}.list-group-horizontal-lg>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl>.list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl>.list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl>.list-group-item.active{margin-top:0}.list-group-horizontal-xl>.list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl>.list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush{border-radius:0}.list-group-flush>.list-group-item{border-width:0 0 1px}.list-group-flush>.list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0}a.close.disabled{pointer-events:none}.toast{-ms-flex-preferred-size:350px;flex-basis:350px;max-width:350px;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05);border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal.modal-static .modal-dialog{-webkit-transform:scale(1.02);transform:scale(1.02)}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1;-webkit-transform:none;transform:none}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file + */ +:root { + --blue: #007bff; + --indigo: #6610f2; + --purple: #6f42c1; + --pink: #e83e8c; + --red: #dc3545; + --orange: #fd7e14; + --yellow: #ffc107; + --green: #28a745; + --teal: #20c997; + --cyan: #17a2b8; + --white: #fff; + --gray: #6c757d; + --gray-dark: #343a40; + --primary: #007bff; + --secondary: #6c757d; + --success: #28a745; + --info: #17a2b8; + --warning: #ffc107; + --danger: #dc3545; + --light: #f8f9fa; + --dark: #343a40; + --breakpoint-xs: 0; + --breakpoint-sm: 576px; + --breakpoint-md: 768px; + --breakpoint-lg: 992px; + --breakpoint-xl: 1200px; + --font-family-sans-serif: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, + 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; +} +*, +::after, +::before { + box-sizing: border-box; +} +html { + font-family: sans-serif; + line-height: 1.15; + -webkit-text-size-adjust: 100%; + -webkit-tap-highlight-color: transparent; +} +article, +aside, +figcaption, +figure, +footer, +header, +hgroup, +main, +nav, +section { + display: block; +} +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', + 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #212529; + text-align: left; + background-color: #fff; +} +[tabindex='-1']:focus:not(:focus-visible) { + outline: 0 !important; +} +hr { + box-sizing: content-box; + height: 0; + overflow: visible; +} +h1, +h2, +h3, +h4, +h5, +h6 { + margin-top: 0; + margin-bottom: 0.5rem; +} +p { + margin-top: 0; + margin-bottom: 1rem; +} +abbr[data-original-title], +abbr[title] { + text-decoration: underline; + -webkit-text-decoration: underline dotted; + text-decoration: underline dotted; + cursor: help; + border-bottom: 0; + -webkit-text-decoration-skip-ink: none; + text-decoration-skip-ink: none; +} +address { + margin-bottom: 1rem; + font-style: normal; + line-height: inherit; +} +dl, +ol, +ul { + margin-top: 0; + margin-bottom: 1rem; +} +ol ol, +ol ul, +ul ol, +ul ul { + margin-bottom: 0; +} +dt { + font-weight: 700; +} +dd { + margin-bottom: 0.5rem; + margin-left: 0; +} +blockquote { + margin: 0 0 1rem; +} +b, +strong { + font-weight: bolder; +} +small { + font-size: 80%; +} +sub, +sup { + position: relative; + font-size: 75%; + line-height: 0; + vertical-align: baseline; +} +sub { + bottom: -0.25em; +} +sup { + top: -0.5em; +} +a { + color: #007bff; + text-decoration: none; + background-color: transparent; +} +a:hover { + color: #0056b3; + text-decoration: underline; +} +a:not([href]):not([class]) { + color: inherit; + text-decoration: none; +} +a:not([href]):not([class]):hover { + color: inherit; + text-decoration: none; +} +code, +kbd, +pre, +samp { + font-family: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace; + font-size: 1em; +} +pre { + margin-top: 0; + margin-bottom: 1rem; + overflow: auto; + -ms-overflow-style: scrollbar; +} +figure { + margin: 0 0 1rem; +} +img { + vertical-align: middle; + border-style: none; +} +svg { + overflow: hidden; + vertical-align: middle; +} +table { + border-collapse: collapse; +} +caption { + padding-top: 0.75rem; + padding-bottom: 0.75rem; + color: #6c757d; + text-align: left; + caption-side: bottom; +} +th { + text-align: inherit; +} +label { + display: inline-block; + margin-bottom: 0.5rem; +} +button { + border-radius: 0; +} +button:focus { + outline: 1px dotted; + outline: 5px auto -webkit-focus-ring-color; +} +button, +input, +optgroup, +select, +textarea { + margin: 0; + font-family: inherit; + font-size: inherit; + line-height: inherit; +} +button, +input { + overflow: visible; +} +button, +select { + text-transform: none; +} +[role='button'] { + cursor: pointer; +} +select { + word-wrap: normal; +} +[type='button'], +[type='reset'], +[type='submit'], +button { + -webkit-appearance: button; +} +[type='button']:not(:disabled), +[type='reset']:not(:disabled), +[type='submit']:not(:disabled), +button:not(:disabled) { + cursor: pointer; +} +[type='button']::-moz-focus-inner, +[type='reset']::-moz-focus-inner, +[type='submit']::-moz-focus-inner, +button::-moz-focus-inner { + padding: 0; + border-style: none; +} +input[type='checkbox'], +input[type='radio'] { + box-sizing: border-box; + padding: 0; +} +textarea { + overflow: auto; + resize: vertical; +} +fieldset { + min-width: 0; + padding: 0; + margin: 0; + border: 0; +} +legend { + display: block; + width: 100%; + max-width: 100%; + padding: 0; + margin-bottom: 0.5rem; + font-size: 1.5rem; + line-height: inherit; + color: inherit; + white-space: normal; +} +progress { + vertical-align: baseline; +} +[type='number']::-webkit-inner-spin-button, +[type='number']::-webkit-outer-spin-button { + height: auto; +} +[type='search'] { + outline-offset: -2px; + -webkit-appearance: none; +} +[type='search']::-webkit-search-decoration { + -webkit-appearance: none; +} +::-webkit-file-upload-button { + font: inherit; + -webkit-appearance: button; +} +output { + display: inline-block; +} +summary { + display: list-item; + cursor: pointer; +} +template { + display: none; +} +[hidden] { + display: none !important; +} +.h1, +.h2, +.h3, +.h4, +.h5, +.h6, +h1, +h2, +h3, +h4, +h5, +h6 { + margin-bottom: 0.5rem; + font-weight: 500; + line-height: 1.2; +} +.h1, +h1 { + font-size: 2.5rem; +} +.h2, +h2 { + font-size: 2rem; +} +.h3, +h3 { + font-size: 1.75rem; +} +.h4, +h4 { + font-size: 1.5rem; +} +.h5, +h5 { + font-size: 1.25rem; +} +.h6, +h6 { + font-size: 1rem; +} +.lead { + font-size: 1.25rem; + font-weight: 300; +} +.display-1 { + font-size: 6rem; + font-weight: 300; + line-height: 1.2; +} +.display-2 { + font-size: 5.5rem; + font-weight: 300; + line-height: 1.2; +} +.display-3 { + font-size: 4.5rem; + font-weight: 300; + line-height: 1.2; +} +.display-4 { + font-size: 3.5rem; + font-weight: 300; + line-height: 1.2; +} +hr { + margin-top: 1rem; + margin-bottom: 1rem; + border: 0; + border-top: 1px solid rgba(0, 0, 0, 0.1); +} +.small, +small { + font-size: 80%; + font-weight: 400; +} +.mark, +mark { + padding: 0.2em; + background-color: #fcf8e3; +} +.list-unstyled { + padding-left: 0; + list-style: none; +} +.list-inline { + padding-left: 0; + list-style: none; +} +.list-inline-item { + display: inline-block; +} +.list-inline-item:not(:last-child) { + margin-right: 0.5rem; +} +.initialism { + font-size: 90%; + text-transform: uppercase; +} +.blockquote { + margin-bottom: 1rem; + font-size: 1.25rem; +} +.blockquote-footer { + display: block; + font-size: 80%; + color: #6c757d; +} +.blockquote-footer::before { + content: '\2014\00A0'; +} +.img-fluid { + max-width: 100%; + height: auto; +} +.img-thumbnail { + padding: 0.25rem; + background-color: #fff; + border: 1px solid #dee2e6; + border-radius: 0.25rem; + max-width: 100%; + height: auto; +} +.figure { + display: inline-block; +} +.figure-img { + margin-bottom: 0.5rem; + line-height: 1; +} +.figure-caption { + font-size: 90%; + color: #6c757d; +} +code { + font-size: 87.5%; + color: #e83e8c; + word-wrap: break-word; +} +a > code { + color: inherit; +} +kbd { + padding: 0.2rem 0.4rem; + font-size: 87.5%; + color: #fff; + background-color: #212529; + border-radius: 0.2rem; +} +kbd kbd { + padding: 0; + font-size: 100%; + font-weight: 700; +} +pre { + display: block; + font-size: 87.5%; + color: #212529; +} +pre code { + font-size: inherit; + color: inherit; + word-break: normal; +} +.pre-scrollable { + max-height: 340px; + overflow-y: scroll; +} +.container, +.container-fluid, +.container-lg, +.container-md, +.container-sm, +.container-xl { + width: 100%; + padding-right: 15px; + padding-left: 15px; + margin-right: auto; + margin-left: auto; +} +@media (min-width: 576px) { + .container, + .container-sm { + max-width: 540px; + } +} +@media (min-width: 768px) { + .container, + .container-md, + .container-sm { + max-width: 720px; + } +} +@media (min-width: 992px) { + .container, + .container-lg, + .container-md, + .container-sm { + max-width: 960px; + } +} +@media (min-width: 1200px) { + .container, + .container-lg, + .container-md, + .container-sm, + .container-xl { + max-width: 1140px; + } +} +.row { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -15px; + margin-left: -15px; +} +.no-gutters { + margin-right: 0; + margin-left: 0; +} +.no-gutters > .col, +.no-gutters > [class*='col-'] { + padding-right: 0; + padding-left: 0; +} +.col, +.col-1, +.col-10, +.col-11, +.col-12, +.col-2, +.col-3, +.col-4, +.col-5, +.col-6, +.col-7, +.col-8, +.col-9, +.col-auto, +.col-lg, +.col-lg-1, +.col-lg-10, +.col-lg-11, +.col-lg-12, +.col-lg-2, +.col-lg-3, +.col-lg-4, +.col-lg-5, +.col-lg-6, +.col-lg-7, +.col-lg-8, +.col-lg-9, +.col-lg-auto, +.col-md, +.col-md-1, +.col-md-10, +.col-md-11, +.col-md-12, +.col-md-2, +.col-md-3, +.col-md-4, +.col-md-5, +.col-md-6, +.col-md-7, +.col-md-8, +.col-md-9, +.col-md-auto, +.col-sm, +.col-sm-1, +.col-sm-10, +.col-sm-11, +.col-sm-12, +.col-sm-2, +.col-sm-3, +.col-sm-4, +.col-sm-5, +.col-sm-6, +.col-sm-7, +.col-sm-8, +.col-sm-9, +.col-sm-auto, +.col-xl, +.col-xl-1, +.col-xl-10, +.col-xl-11, +.col-xl-12, +.col-xl-2, +.col-xl-3, +.col-xl-4, +.col-xl-5, +.col-xl-6, +.col-xl-7, +.col-xl-8, +.col-xl-9, +.col-xl-auto { + position: relative; + width: 100%; + padding-right: 15px; + padding-left: 15px; +} +.col { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; +} +.row-cols-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; +} +.row-cols-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; +} +.row-cols-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; +} +.row-cols-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; +} +.row-cols-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; +} +.row-cols-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; +} +.col-auto { + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: 100%; +} +.col-1 { + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; +} +.col-2 { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; +} +.col-3 { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; +} +.col-4 { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; +} +.col-5 { + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; +} +.col-6 { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; +} +.col-7 { + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; +} +.col-8 { + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; +} +.col-9 { + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; +} +.col-10 { + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; +} +.col-11 { + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; +} +.col-12 { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; +} +.order-first { + -ms-flex-order: -1; + order: -1; +} +.order-last { + -ms-flex-order: 13; + order: 13; +} +.order-0 { + -ms-flex-order: 0; + order: 0; +} +.order-1 { + -ms-flex-order: 1; + order: 1; +} +.order-2 { + -ms-flex-order: 2; + order: 2; +} +.order-3 { + -ms-flex-order: 3; + order: 3; +} +.order-4 { + -ms-flex-order: 4; + order: 4; +} +.order-5 { + -ms-flex-order: 5; + order: 5; +} +.order-6 { + -ms-flex-order: 6; + order: 6; +} +.order-7 { + -ms-flex-order: 7; + order: 7; +} +.order-8 { + -ms-flex-order: 8; + order: 8; +} +.order-9 { + -ms-flex-order: 9; + order: 9; +} +.order-10 { + -ms-flex-order: 10; + order: 10; +} +.order-11 { + -ms-flex-order: 11; + order: 11; +} +.order-12 { + -ms-flex-order: 12; + order: 12; +} +.offset-1 { + margin-left: 8.333333%; +} +.offset-2 { + margin-left: 16.666667%; +} +.offset-3 { + margin-left: 25%; +} +.offset-4 { + margin-left: 33.333333%; +} +.offset-5 { + margin-left: 41.666667%; +} +.offset-6 { + margin-left: 50%; +} +.offset-7 { + margin-left: 58.333333%; +} +.offset-8 { + margin-left: 66.666667%; +} +.offset-9 { + margin-left: 75%; +} +.offset-10 { + margin-left: 83.333333%; +} +.offset-11 { + margin-left: 91.666667%; +} +@media (min-width: 576px) { + .col-sm { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .row-cols-sm-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .row-cols-sm-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .row-cols-sm-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .row-cols-sm-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .row-cols-sm-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; + } + .row-cols-sm-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-sm-auto { + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: 100%; + } + .col-sm-1 { + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-sm-2 { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-sm-3 { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-sm-4 { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-sm-5 { + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-sm-6 { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-sm-7 { + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-sm-8 { + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-sm-9 { + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-sm-10 { + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-sm-11 { + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-sm-12 { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-sm-first { + -ms-flex-order: -1; + order: -1; + } + .order-sm-last { + -ms-flex-order: 13; + order: 13; + } + .order-sm-0 { + -ms-flex-order: 0; + order: 0; + } + .order-sm-1 { + -ms-flex-order: 1; + order: 1; + } + .order-sm-2 { + -ms-flex-order: 2; + order: 2; + } + .order-sm-3 { + -ms-flex-order: 3; + order: 3; + } + .order-sm-4 { + -ms-flex-order: 4; + order: 4; + } + .order-sm-5 { + -ms-flex-order: 5; + order: 5; + } + .order-sm-6 { + -ms-flex-order: 6; + order: 6; + } + .order-sm-7 { + -ms-flex-order: 7; + order: 7; + } + .order-sm-8 { + -ms-flex-order: 8; + order: 8; + } + .order-sm-9 { + -ms-flex-order: 9; + order: 9; + } + .order-sm-10 { + -ms-flex-order: 10; + order: 10; + } + .order-sm-11 { + -ms-flex-order: 11; + order: 11; + } + .order-sm-12 { + -ms-flex-order: 12; + order: 12; + } + .offset-sm-0 { + margin-left: 0; + } + .offset-sm-1 { + margin-left: 8.333333%; + } + .offset-sm-2 { + margin-left: 16.666667%; + } + .offset-sm-3 { + margin-left: 25%; + } + .offset-sm-4 { + margin-left: 33.333333%; + } + .offset-sm-5 { + margin-left: 41.666667%; + } + .offset-sm-6 { + margin-left: 50%; + } + .offset-sm-7 { + margin-left: 58.333333%; + } + .offset-sm-8 { + margin-left: 66.666667%; + } + .offset-sm-9 { + margin-left: 75%; + } + .offset-sm-10 { + margin-left: 83.333333%; + } + .offset-sm-11 { + margin-left: 91.666667%; + } +} +@media (min-width: 768px) { + .col-md { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .row-cols-md-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .row-cols-md-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .row-cols-md-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .row-cols-md-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .row-cols-md-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; + } + .row-cols-md-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-md-auto { + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: 100%; + } + .col-md-1 { + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-md-2 { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-md-3 { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-md-4 { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-md-5 { + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-md-6 { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-md-7 { + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-md-8 { + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-md-9 { + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-md-10 { + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-md-11 { + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-md-12 { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-md-first { + -ms-flex-order: -1; + order: -1; + } + .order-md-last { + -ms-flex-order: 13; + order: 13; + } + .order-md-0 { + -ms-flex-order: 0; + order: 0; + } + .order-md-1 { + -ms-flex-order: 1; + order: 1; + } + .order-md-2 { + -ms-flex-order: 2; + order: 2; + } + .order-md-3 { + -ms-flex-order: 3; + order: 3; + } + .order-md-4 { + -ms-flex-order: 4; + order: 4; + } + .order-md-5 { + -ms-flex-order: 5; + order: 5; + } + .order-md-6 { + -ms-flex-order: 6; + order: 6; + } + .order-md-7 { + -ms-flex-order: 7; + order: 7; + } + .order-md-8 { + -ms-flex-order: 8; + order: 8; + } + .order-md-9 { + -ms-flex-order: 9; + order: 9; + } + .order-md-10 { + -ms-flex-order: 10; + order: 10; + } + .order-md-11 { + -ms-flex-order: 11; + order: 11; + } + .order-md-12 { + -ms-flex-order: 12; + order: 12; + } + .offset-md-0 { + margin-left: 0; + } + .offset-md-1 { + margin-left: 8.333333%; + } + .offset-md-2 { + margin-left: 16.666667%; + } + .offset-md-3 { + margin-left: 25%; + } + .offset-md-4 { + margin-left: 33.333333%; + } + .offset-md-5 { + margin-left: 41.666667%; + } + .offset-md-6 { + margin-left: 50%; + } + .offset-md-7 { + margin-left: 58.333333%; + } + .offset-md-8 { + margin-left: 66.666667%; + } + .offset-md-9 { + margin-left: 75%; + } + .offset-md-10 { + margin-left: 83.333333%; + } + .offset-md-11 { + margin-left: 91.666667%; + } +} +@media (min-width: 992px) { + .col-lg { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .row-cols-lg-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .row-cols-lg-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .row-cols-lg-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .row-cols-lg-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .row-cols-lg-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; + } + .row-cols-lg-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-lg-auto { + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: 100%; + } + .col-lg-1 { + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-lg-2 { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-lg-3 { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-lg-4 { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-lg-5 { + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-lg-6 { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-lg-7 { + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-lg-8 { + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-lg-9 { + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-lg-10 { + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-lg-11 { + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-lg-12 { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-lg-first { + -ms-flex-order: -1; + order: -1; + } + .order-lg-last { + -ms-flex-order: 13; + order: 13; + } + .order-lg-0 { + -ms-flex-order: 0; + order: 0; + } + .order-lg-1 { + -ms-flex-order: 1; + order: 1; + } + .order-lg-2 { + -ms-flex-order: 2; + order: 2; + } + .order-lg-3 { + -ms-flex-order: 3; + order: 3; + } + .order-lg-4 { + -ms-flex-order: 4; + order: 4; + } + .order-lg-5 { + -ms-flex-order: 5; + order: 5; + } + .order-lg-6 { + -ms-flex-order: 6; + order: 6; + } + .order-lg-7 { + -ms-flex-order: 7; + order: 7; + } + .order-lg-8 { + -ms-flex-order: 8; + order: 8; + } + .order-lg-9 { + -ms-flex-order: 9; + order: 9; + } + .order-lg-10 { + -ms-flex-order: 10; + order: 10; + } + .order-lg-11 { + -ms-flex-order: 11; + order: 11; + } + .order-lg-12 { + -ms-flex-order: 12; + order: 12; + } + .offset-lg-0 { + margin-left: 0; + } + .offset-lg-1 { + margin-left: 8.333333%; + } + .offset-lg-2 { + margin-left: 16.666667%; + } + .offset-lg-3 { + margin-left: 25%; + } + .offset-lg-4 { + margin-left: 33.333333%; + } + .offset-lg-5 { + margin-left: 41.666667%; + } + .offset-lg-6 { + margin-left: 50%; + } + .offset-lg-7 { + margin-left: 58.333333%; + } + .offset-lg-8 { + margin-left: 66.666667%; + } + .offset-lg-9 { + margin-left: 75%; + } + .offset-lg-10 { + margin-left: 83.333333%; + } + .offset-lg-11 { + margin-left: 91.666667%; + } +} +@media (min-width: 1200px) { + .col-xl { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -ms-flex-positive: 1; + flex-grow: 1; + max-width: 100%; + } + .row-cols-xl-1 > * { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .row-cols-xl-2 > * { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .row-cols-xl-3 > * { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .row-cols-xl-4 > * { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .row-cols-xl-5 > * { + -ms-flex: 0 0 20%; + flex: 0 0 20%; + max-width: 20%; + } + .row-cols-xl-6 > * { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-xl-auto { + -ms-flex: 0 0 auto; + flex: 0 0 auto; + width: auto; + max-width: 100%; + } + .col-xl-1 { + -ms-flex: 0 0 8.333333%; + flex: 0 0 8.333333%; + max-width: 8.333333%; + } + .col-xl-2 { + -ms-flex: 0 0 16.666667%; + flex: 0 0 16.666667%; + max-width: 16.666667%; + } + .col-xl-3 { + -ms-flex: 0 0 25%; + flex: 0 0 25%; + max-width: 25%; + } + .col-xl-4 { + -ms-flex: 0 0 33.333333%; + flex: 0 0 33.333333%; + max-width: 33.333333%; + } + .col-xl-5 { + -ms-flex: 0 0 41.666667%; + flex: 0 0 41.666667%; + max-width: 41.666667%; + } + .col-xl-6 { + -ms-flex: 0 0 50%; + flex: 0 0 50%; + max-width: 50%; + } + .col-xl-7 { + -ms-flex: 0 0 58.333333%; + flex: 0 0 58.333333%; + max-width: 58.333333%; + } + .col-xl-8 { + -ms-flex: 0 0 66.666667%; + flex: 0 0 66.666667%; + max-width: 66.666667%; + } + .col-xl-9 { + -ms-flex: 0 0 75%; + flex: 0 0 75%; + max-width: 75%; + } + .col-xl-10 { + -ms-flex: 0 0 83.333333%; + flex: 0 0 83.333333%; + max-width: 83.333333%; + } + .col-xl-11 { + -ms-flex: 0 0 91.666667%; + flex: 0 0 91.666667%; + max-width: 91.666667%; + } + .col-xl-12 { + -ms-flex: 0 0 100%; + flex: 0 0 100%; + max-width: 100%; + } + .order-xl-first { + -ms-flex-order: -1; + order: -1; + } + .order-xl-last { + -ms-flex-order: 13; + order: 13; + } + .order-xl-0 { + -ms-flex-order: 0; + order: 0; + } + .order-xl-1 { + -ms-flex-order: 1; + order: 1; + } + .order-xl-2 { + -ms-flex-order: 2; + order: 2; + } + .order-xl-3 { + -ms-flex-order: 3; + order: 3; + } + .order-xl-4 { + -ms-flex-order: 4; + order: 4; + } + .order-xl-5 { + -ms-flex-order: 5; + order: 5; + } + .order-xl-6 { + -ms-flex-order: 6; + order: 6; + } + .order-xl-7 { + -ms-flex-order: 7; + order: 7; + } + .order-xl-8 { + -ms-flex-order: 8; + order: 8; + } + .order-xl-9 { + -ms-flex-order: 9; + order: 9; + } + .order-xl-10 { + -ms-flex-order: 10; + order: 10; + } + .order-xl-11 { + -ms-flex-order: 11; + order: 11; + } + .order-xl-12 { + -ms-flex-order: 12; + order: 12; + } + .offset-xl-0 { + margin-left: 0; + } + .offset-xl-1 { + margin-left: 8.333333%; + } + .offset-xl-2 { + margin-left: 16.666667%; + } + .offset-xl-3 { + margin-left: 25%; + } + .offset-xl-4 { + margin-left: 33.333333%; + } + .offset-xl-5 { + margin-left: 41.666667%; + } + .offset-xl-6 { + margin-left: 50%; + } + .offset-xl-7 { + margin-left: 58.333333%; + } + .offset-xl-8 { + margin-left: 66.666667%; + } + .offset-xl-9 { + margin-left: 75%; + } + .offset-xl-10 { + margin-left: 83.333333%; + } + .offset-xl-11 { + margin-left: 91.666667%; + } +} +.table { + width: 100%; + margin-bottom: 1rem; + color: #212529; +} +.table td, +.table th { + padding: 0.75rem; + vertical-align: top; + border-top: 1px solid #dee2e6; +} +.table thead th { + vertical-align: bottom; + border-bottom: 2px solid #dee2e6; +} +.table tbody + tbody { + border-top: 2px solid #dee2e6; +} +.table-sm td, +.table-sm th { + padding: 0.3rem; +} +.table-bordered { + border: 1px solid #dee2e6; +} +.table-bordered td, +.table-bordered th { + border: 1px solid #dee2e6; +} +.table-bordered thead td, +.table-bordered thead th { + border-bottom-width: 2px; +} +.table-borderless tbody + tbody, +.table-borderless td, +.table-borderless th, +.table-borderless thead th { + border: 0; +} +.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(0, 0, 0, 0.05); +} +.table-hover tbody tr:hover { + color: #212529; + background-color: rgba(0, 0, 0, 0.075); +} +.table-primary, +.table-primary > td, +.table-primary > th { + background-color: #b8daff; +} +.table-primary tbody + tbody, +.table-primary td, +.table-primary th, +.table-primary thead th { + border-color: #7abaff; +} +.table-hover .table-primary:hover { + background-color: #9fcdff; +} +.table-hover .table-primary:hover > td, +.table-hover .table-primary:hover > th { + background-color: #9fcdff; +} +.table-secondary, +.table-secondary > td, +.table-secondary > th { + background-color: #d6d8db; +} +.table-secondary tbody + tbody, +.table-secondary td, +.table-secondary th, +.table-secondary thead th { + border-color: #b3b7bb; +} +.table-hover .table-secondary:hover { + background-color: #c8cbcf; +} +.table-hover .table-secondary:hover > td, +.table-hover .table-secondary:hover > th { + background-color: #c8cbcf; +} +.table-success, +.table-success > td, +.table-success > th { + background-color: #c3e6cb; +} +.table-success tbody + tbody, +.table-success td, +.table-success th, +.table-success thead th { + border-color: #8fd19e; +} +.table-hover .table-success:hover { + background-color: #b1dfbb; +} +.table-hover .table-success:hover > td, +.table-hover .table-success:hover > th { + background-color: #b1dfbb; +} +.table-info, +.table-info > td, +.table-info > th { + background-color: #bee5eb; +} +.table-info tbody + tbody, +.table-info td, +.table-info th, +.table-info thead th { + border-color: #86cfda; +} +.table-hover .table-info:hover { + background-color: #abdde5; +} +.table-hover .table-info:hover > td, +.table-hover .table-info:hover > th { + background-color: #abdde5; +} +.table-warning, +.table-warning > td, +.table-warning > th { + background-color: #ffeeba; +} +.table-warning tbody + tbody, +.table-warning td, +.table-warning th, +.table-warning thead th { + border-color: #ffdf7e; +} +.table-hover .table-warning:hover { + background-color: #ffe8a1; +} +.table-hover .table-warning:hover > td, +.table-hover .table-warning:hover > th { + background-color: #ffe8a1; +} +.table-danger, +.table-danger > td, +.table-danger > th { + background-color: #f5c6cb; +} +.table-danger tbody + tbody, +.table-danger td, +.table-danger th, +.table-danger thead th { + border-color: #ed969e; +} +.table-hover .table-danger:hover { + background-color: #f1b0b7; +} +.table-hover .table-danger:hover > td, +.table-hover .table-danger:hover > th { + background-color: #f1b0b7; +} +.table-light, +.table-light > td, +.table-light > th { + background-color: #fdfdfe; +} +.table-light tbody + tbody, +.table-light td, +.table-light th, +.table-light thead th { + border-color: #fbfcfc; +} +.table-hover .table-light:hover { + background-color: #ececf6; +} +.table-hover .table-light:hover > td, +.table-hover .table-light:hover > th { + background-color: #ececf6; +} +.table-dark, +.table-dark > td, +.table-dark > th { + background-color: #c6c8ca; +} +.table-dark tbody + tbody, +.table-dark td, +.table-dark th, +.table-dark thead th { + border-color: #95999c; +} +.table-hover .table-dark:hover { + background-color: #b9bbbe; +} +.table-hover .table-dark:hover > td, +.table-hover .table-dark:hover > th { + background-color: #b9bbbe; +} +.table-active, +.table-active > td, +.table-active > th { + background-color: rgba(0, 0, 0, 0.075); +} +.table-hover .table-active:hover { + background-color: rgba(0, 0, 0, 0.075); +} +.table-hover .table-active:hover > td, +.table-hover .table-active:hover > th { + background-color: rgba(0, 0, 0, 0.075); +} +.table .thead-dark th { + color: #fff; + background-color: #343a40; + border-color: #454d55; +} +.table .thead-light th { + color: #495057; + background-color: #e9ecef; + border-color: #dee2e6; +} +.table-dark { + color: #fff; + background-color: #343a40; +} +.table-dark td, +.table-dark th, +.table-dark thead th { + border-color: #454d55; +} +.table-dark.table-bordered { + border: 0; +} +.table-dark.table-striped tbody tr:nth-of-type(odd) { + background-color: rgba(255, 255, 255, 0.05); +} +.table-dark.table-hover tbody tr:hover { + color: #fff; + background-color: rgba(255, 255, 255, 0.075); +} +@media (max-width: 575.98px) { + .table-responsive-sm { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + .table-responsive-sm > .table-bordered { + border: 0; + } +} +@media (max-width: 767.98px) { + .table-responsive-md { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + .table-responsive-md > .table-bordered { + border: 0; + } +} +@media (max-width: 991.98px) { + .table-responsive-lg { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + .table-responsive-lg > .table-bordered { + border: 0; + } +} +@media (max-width: 1199.98px) { + .table-responsive-xl { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + } + .table-responsive-xl > .table-bordered { + border: 0; + } +} +.table-responsive { + display: block; + width: 100%; + overflow-x: auto; + -webkit-overflow-scrolling: touch; +} +.table-responsive > .table-bordered { + border: 0; +} +.form-control { + display: block; + width: 100%; + height: calc(1.5em + 0.75rem + 2px); + padding: 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + background-color: #fff; + background-clip: padding-box; + border: 1px solid #ced4da; + border-radius: 0.25rem; + transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .form-control { + transition: none; + } +} +.form-control::-ms-expand { + background-color: transparent; + border: 0; +} +.form-control:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #495057; +} +.form-control:focus { + color: #495057; + background-color: #fff; + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.form-control::-webkit-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::-moz-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::-ms-input-placeholder { + color: #6c757d; + opacity: 1; +} +.form-control::placeholder { + color: #6c757d; + opacity: 1; +} +.form-control:disabled, +.form-control[readonly] { + background-color: #e9ecef; + opacity: 1; +} +input[type='date'].form-control, +input[type='datetime-local'].form-control, +input[type='month'].form-control, +input[type='time'].form-control { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +select.form-control:focus::-ms-value { + color: #495057; + background-color: #fff; +} +.form-control-file, +.form-control-range { + display: block; + width: 100%; +} +.col-form-label { + padding-top: calc(0.375rem + 1px); + padding-bottom: calc(0.375rem + 1px); + margin-bottom: 0; + font-size: inherit; + line-height: 1.5; +} +.col-form-label-lg { + padding-top: calc(0.5rem + 1px); + padding-bottom: calc(0.5rem + 1px); + font-size: 1.25rem; + line-height: 1.5; +} +.col-form-label-sm { + padding-top: calc(0.25rem + 1px); + padding-bottom: calc(0.25rem + 1px); + font-size: 0.875rem; + line-height: 1.5; +} +.form-control-plaintext { + display: block; + width: 100%; + padding: 0.375rem 0; + margin-bottom: 0; + font-size: 1rem; + line-height: 1.5; + color: #212529; + background-color: transparent; + border: solid transparent; + border-width: 1px 0; +} +.form-control-plaintext.form-control-lg, +.form-control-plaintext.form-control-sm { + padding-right: 0; + padding-left: 0; +} +.form-control-sm { + height: calc(1.5em + 0.5rem + 2px); + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} +.form-control-lg { + height: calc(1.5em + 1rem + 2px); + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} +select.form-control[multiple], +select.form-control[size] { + height: auto; +} +textarea.form-control { + height: auto; +} +.form-group { + margin-bottom: 1rem; +} +.form-text { + display: block; + margin-top: 0.25rem; +} +.form-row { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + margin-right: -5px; + margin-left: -5px; +} +.form-row > .col, +.form-row > [class*='col-'] { + padding-right: 5px; + padding-left: 5px; +} +.form-check { + position: relative; + display: block; + padding-left: 1.25rem; +} +.form-check-input { + position: absolute; + margin-top: 0.3rem; + margin-left: -1.25rem; +} +.form-check-input:disabled ~ .form-check-label, +.form-check-input[disabled] ~ .form-check-label { + color: #6c757d; +} +.form-check-label { + margin-bottom: 0; +} +.form-check-inline { + display: -ms-inline-flexbox; + display: inline-flex; + -ms-flex-align: center; + align-items: center; + padding-left: 0; + margin-right: 0.75rem; +} +.form-check-inline .form-check-input { + position: static; + margin-top: 0; + margin-right: 0.3125rem; + margin-left: 0; +} +.valid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #28a745; +} +.valid-tooltip { + position: absolute; + top: 100%; + left: 0; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + line-height: 1.5; + color: #fff; + background-color: rgba(40, 167, 69, 0.9); + border-radius: 0.25rem; +} +.is-valid ~ .valid-feedback, +.is-valid ~ .valid-tooltip, +.was-validated :valid ~ .valid-feedback, +.was-validated :valid ~ .valid-tooltip { + display: block; +} +.form-control.is-valid, +.was-validated .form-control:valid { + border-color: #28a745; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-control.is-valid:focus, +.was-validated .form-control:valid:focus { + border-color: #28a745; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} +.was-validated textarea.form-control:valid, +textarea.form-control.is-valid { + padding-right: calc(1.5em + 0.75rem); + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} +.custom-select.is-valid, +.was-validated .custom-select:valid { + border-color: #28a745; + padding-right: calc(0.75em + 2.3125rem); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") + no-repeat right 0.75rem center/8px 10px, + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") + #fff no-repeat center right 1.75rem / calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.custom-select.is-valid:focus, +.was-validated .custom-select:valid:focus { + border-color: #28a745; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} +.form-check-input.is-valid ~ .form-check-label, +.was-validated .form-check-input:valid ~ .form-check-label { + color: #28a745; +} +.form-check-input.is-valid ~ .valid-feedback, +.form-check-input.is-valid ~ .valid-tooltip, +.was-validated .form-check-input:valid ~ .valid-feedback, +.was-validated .form-check-input:valid ~ .valid-tooltip { + display: block; +} +.custom-control-input.is-valid ~ .custom-control-label, +.was-validated .custom-control-input:valid ~ .custom-control-label { + color: #28a745; +} +.custom-control-input.is-valid ~ .custom-control-label::before, +.was-validated .custom-control-input:valid ~ .custom-control-label::before { + border-color: #28a745; +} +.custom-control-input.is-valid:checked ~ .custom-control-label::before, +.was-validated .custom-control-input:valid:checked ~ .custom-control-label::before { + border-color: #34ce57; + background-color: #34ce57; +} +.custom-control-input.is-valid:focus ~ .custom-control-label::before, +.was-validated .custom-control-input:valid:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} +.custom-control-input.is-valid:focus:not(:checked) ~ .custom-control-label::before, +.was-validated .custom-control-input:valid:focus:not(:checked) ~ .custom-control-label::before { + border-color: #28a745; +} +.custom-file-input.is-valid ~ .custom-file-label, +.was-validated .custom-file-input:valid ~ .custom-file-label { + border-color: #28a745; +} +.custom-file-input.is-valid:focus ~ .custom-file-label, +.was-validated .custom-file-input:valid:focus ~ .custom-file-label { + border-color: #28a745; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25); +} +.invalid-feedback { + display: none; + width: 100%; + margin-top: 0.25rem; + font-size: 80%; + color: #dc3545; +} +.invalid-tooltip { + position: absolute; + top: 100%; + left: 0; + z-index: 5; + display: none; + max-width: 100%; + padding: 0.25rem 0.5rem; + margin-top: 0.1rem; + font-size: 0.875rem; + line-height: 1.5; + color: #fff; + background-color: rgba(220, 53, 69, 0.9); + border-radius: 0.25rem; +} +.is-invalid ~ .invalid-feedback, +.is-invalid ~ .invalid-tooltip, +.was-validated :invalid ~ .invalid-feedback, +.was-validated :invalid ~ .invalid-tooltip { + display: block; +} +.form-control.is-invalid, +.was-validated .form-control:invalid { + border-color: #dc3545; + padding-right: calc(1.5em + 0.75rem); + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e"); + background-repeat: no-repeat; + background-position: right calc(0.375em + 0.1875rem) center; + background-size: calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.form-control.is-invalid:focus, +.was-validated .form-control:invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} +.was-validated textarea.form-control:invalid, +textarea.form-control.is-invalid { + padding-right: calc(1.5em + 0.75rem); + background-position: top calc(0.375em + 0.1875rem) right calc(0.375em + 0.1875rem); +} +.custom-select.is-invalid, +.was-validated .custom-select:invalid { + border-color: #dc3545; + padding-right: calc(0.75em + 2.3125rem); + background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") + no-repeat right 0.75rem center/8px 10px, + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e") + #fff no-repeat center right 1.75rem / calc(0.75em + 0.375rem) calc(0.75em + 0.375rem); +} +.custom-select.is-invalid:focus, +.was-validated .custom-select:invalid:focus { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} +.form-check-input.is-invalid ~ .form-check-label, +.was-validated .form-check-input:invalid ~ .form-check-label { + color: #dc3545; +} +.form-check-input.is-invalid ~ .invalid-feedback, +.form-check-input.is-invalid ~ .invalid-tooltip, +.was-validated .form-check-input:invalid ~ .invalid-feedback, +.was-validated .form-check-input:invalid ~ .invalid-tooltip { + display: block; +} +.custom-control-input.is-invalid ~ .custom-control-label, +.was-validated .custom-control-input:invalid ~ .custom-control-label { + color: #dc3545; +} +.custom-control-input.is-invalid ~ .custom-control-label::before, +.was-validated .custom-control-input:invalid ~ .custom-control-label::before { + border-color: #dc3545; +} +.custom-control-input.is-invalid:checked ~ .custom-control-label::before, +.was-validated .custom-control-input:invalid:checked ~ .custom-control-label::before { + border-color: #e4606d; + background-color: #e4606d; +} +.custom-control-input.is-invalid:focus ~ .custom-control-label::before, +.was-validated .custom-control-input:invalid:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} +.custom-control-input.is-invalid:focus:not(:checked) ~ .custom-control-label::before, +.was-validated .custom-control-input:invalid:focus:not(:checked) ~ .custom-control-label::before { + border-color: #dc3545; +} +.custom-file-input.is-invalid ~ .custom-file-label, +.was-validated .custom-file-input:invalid ~ .custom-file-label { + border-color: #dc3545; +} +.custom-file-input.is-invalid:focus ~ .custom-file-label, +.was-validated .custom-file-input:invalid:focus ~ .custom-file-label { + border-color: #dc3545; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25); +} +.form-inline { + display: -ms-flexbox; + display: flex; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -ms-flex-align: center; + align-items: center; +} +.form-inline .form-check { + width: 100%; +} +@media (min-width: 576px) { + .form-inline label { + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: center; + justify-content: center; + margin-bottom: 0; + } + .form-inline .form-group { + display: -ms-flexbox; + display: flex; + -ms-flex: 0 0 auto; + flex: 0 0 auto; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + -ms-flex-align: center; + align-items: center; + margin-bottom: 0; + } + .form-inline .form-control { + display: inline-block; + width: auto; + vertical-align: middle; + } + .form-inline .form-control-plaintext { + display: inline-block; + } + .form-inline .custom-select, + .form-inline .input-group { + width: auto; + } + .form-inline .form-check { + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: center; + justify-content: center; + width: auto; + padding-left: 0; + } + .form-inline .form-check-input { + position: relative; + -ms-flex-negative: 0; + flex-shrink: 0; + margin-top: 0; + margin-right: 0.25rem; + margin-left: 0; + } + .form-inline .custom-control { + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: center; + justify-content: center; + } + .form-inline .custom-control-label { + margin-bottom: 0; + } +} +.btn { + display: inline-block; + font-weight: 400; + color: #212529; + text-align: center; + vertical-align: middle; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + background-color: transparent; + border: 1px solid transparent; + padding: 0.375rem 0.75rem; + font-size: 1rem; + line-height: 1.5; + border-radius: 0.25rem; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .btn { + transition: none; + } +} +.btn:hover { + color: #212529; + text-decoration: none; +} +.btn.focus, +.btn:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.btn.disabled, +.btn:disabled { + opacity: 0.65; +} +.btn:not(:disabled):not(.disabled) { + cursor: pointer; +} +a.btn.disabled, +fieldset:disabled a.btn { + pointer-events: none; +} +.btn-primary { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-primary:hover { + color: #fff; + background-color: #0069d9; + border-color: #0062cc; +} +.btn-primary.focus, +.btn-primary:focus { + color: #fff; + background-color: #0069d9; + border-color: #0062cc; + box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5); +} +.btn-primary.disabled, +.btn-primary:disabled { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-primary:not(:disabled):not(.disabled).active, +.btn-primary:not(:disabled):not(.disabled):active, +.show > .btn-primary.dropdown-toggle { + color: #fff; + background-color: #0062cc; + border-color: #005cbf; +} +.btn-primary:not(:disabled):not(.disabled).active:focus, +.btn-primary:not(:disabled):not(.disabled):active:focus, +.show > .btn-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(38, 143, 255, 0.5); +} +.btn-secondary { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-secondary:hover { + color: #fff; + background-color: #5a6268; + border-color: #545b62; +} +.btn-secondary.focus, +.btn-secondary:focus { + color: #fff; + background-color: #5a6268; + border-color: #545b62; + box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5); +} +.btn-secondary.disabled, +.btn-secondary:disabled { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-secondary:not(:disabled):not(.disabled).active, +.btn-secondary:not(:disabled):not(.disabled):active, +.show > .btn-secondary.dropdown-toggle { + color: #fff; + background-color: #545b62; + border-color: #4e555b; +} +.btn-secondary:not(:disabled):not(.disabled).active:focus, +.btn-secondary:not(:disabled):not(.disabled):active:focus, +.show > .btn-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(130, 138, 145, 0.5); +} +.btn-success { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-success:hover { + color: #fff; + background-color: #218838; + border-color: #1e7e34; +} +.btn-success.focus, +.btn-success:focus { + color: #fff; + background-color: #218838; + border-color: #1e7e34; + box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5); +} +.btn-success.disabled, +.btn-success:disabled { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-success:not(:disabled):not(.disabled).active, +.btn-success:not(:disabled):not(.disabled):active, +.show > .btn-success.dropdown-toggle { + color: #fff; + background-color: #1e7e34; + border-color: #1c7430; +} +.btn-success:not(:disabled):not(.disabled).active:focus, +.btn-success:not(:disabled):not(.disabled):active:focus, +.show > .btn-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(72, 180, 97, 0.5); +} +.btn-info { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-info:hover { + color: #fff; + background-color: #138496; + border-color: #117a8b; +} +.btn-info.focus, +.btn-info:focus { + color: #fff; + background-color: #138496; + border-color: #117a8b; + box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5); +} +.btn-info.disabled, +.btn-info:disabled { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-info:not(:disabled):not(.disabled).active, +.btn-info:not(:disabled):not(.disabled):active, +.show > .btn-info.dropdown-toggle { + color: #fff; + background-color: #117a8b; + border-color: #10707f; +} +.btn-info:not(:disabled):not(.disabled).active:focus, +.btn-info:not(:disabled):not(.disabled):active:focus, +.show > .btn-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(58, 176, 195, 0.5); +} +.btn-warning { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-warning:hover { + color: #212529; + background-color: #e0a800; + border-color: #d39e00; +} +.btn-warning.focus, +.btn-warning:focus { + color: #212529; + background-color: #e0a800; + border-color: #d39e00; + box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5); +} +.btn-warning.disabled, +.btn-warning:disabled { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-warning:not(:disabled):not(.disabled).active, +.btn-warning:not(:disabled):not(.disabled):active, +.show > .btn-warning.dropdown-toggle { + color: #212529; + background-color: #d39e00; + border-color: #c69500; +} +.btn-warning:not(:disabled):not(.disabled).active:focus, +.btn-warning:not(:disabled):not(.disabled):active:focus, +.show > .btn-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(222, 170, 12, 0.5); +} +.btn-danger { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-danger:hover { + color: #fff; + background-color: #c82333; + border-color: #bd2130; +} +.btn-danger.focus, +.btn-danger:focus { + color: #fff; + background-color: #c82333; + border-color: #bd2130; + box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5); +} +.btn-danger.disabled, +.btn-danger:disabled { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-danger:not(:disabled):not(.disabled).active, +.btn-danger:not(:disabled):not(.disabled):active, +.show > .btn-danger.dropdown-toggle { + color: #fff; + background-color: #bd2130; + border-color: #b21f2d; +} +.btn-danger:not(:disabled):not(.disabled).active:focus, +.btn-danger:not(:disabled):not(.disabled):active:focus, +.show > .btn-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(225, 83, 97, 0.5); +} +.btn-light { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-light:hover { + color: #212529; + background-color: #e2e6ea; + border-color: #dae0e5; +} +.btn-light.focus, +.btn-light:focus { + color: #212529; + background-color: #e2e6ea; + border-color: #dae0e5; + box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5); +} +.btn-light.disabled, +.btn-light:disabled { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-light:not(:disabled):not(.disabled).active, +.btn-light:not(:disabled):not(.disabled):active, +.show > .btn-light.dropdown-toggle { + color: #212529; + background-color: #dae0e5; + border-color: #d3d9df; +} +.btn-light:not(:disabled):not(.disabled).active:focus, +.btn-light:not(:disabled):not(.disabled):active:focus, +.show > .btn-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(216, 217, 219, 0.5); +} +.btn-dark { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-dark:hover { + color: #fff; + background-color: #23272b; + border-color: #1d2124; +} +.btn-dark.focus, +.btn-dark:focus { + color: #fff; + background-color: #23272b; + border-color: #1d2124; + box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5); +} +.btn-dark.disabled, +.btn-dark:disabled { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-dark:not(:disabled):not(.disabled).active, +.btn-dark:not(:disabled):not(.disabled):active, +.show > .btn-dark.dropdown-toggle { + color: #fff; + background-color: #1d2124; + border-color: #171a1d; +} +.btn-dark:not(:disabled):not(.disabled).active:focus, +.btn-dark:not(:disabled):not(.disabled):active:focus, +.show > .btn-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(82, 88, 93, 0.5); +} +.btn-outline-primary { + color: #007bff; + border-color: #007bff; +} +.btn-outline-primary:hover { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-outline-primary.focus, +.btn-outline-primary:focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} +.btn-outline-primary.disabled, +.btn-outline-primary:disabled { + color: #007bff; + background-color: transparent; +} +.btn-outline-primary:not(:disabled):not(.disabled).active, +.btn-outline-primary:not(:disabled):not(.disabled):active, +.show > .btn-outline-primary.dropdown-toggle { + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.btn-outline-primary:not(:disabled):not(.disabled).active:focus, +.btn-outline-primary:not(:disabled):not(.disabled):active:focus, +.show > .btn-outline-primary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} +.btn-outline-secondary { + color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary:hover { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary.focus, +.btn-outline-secondary:focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} +.btn-outline-secondary.disabled, +.btn-outline-secondary:disabled { + color: #6c757d; + background-color: transparent; +} +.btn-outline-secondary:not(:disabled):not(.disabled).active, +.btn-outline-secondary:not(:disabled):not(.disabled):active, +.show > .btn-outline-secondary.dropdown-toggle { + color: #fff; + background-color: #6c757d; + border-color: #6c757d; +} +.btn-outline-secondary:not(:disabled):not(.disabled).active:focus, +.btn-outline-secondary:not(:disabled):not(.disabled):active:focus, +.show > .btn-outline-secondary.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} +.btn-outline-success { + color: #28a745; + border-color: #28a745; +} +.btn-outline-success:hover { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-outline-success.focus, +.btn-outline-success:focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} +.btn-outline-success.disabled, +.btn-outline-success:disabled { + color: #28a745; + background-color: transparent; +} +.btn-outline-success:not(:disabled):not(.disabled).active, +.btn-outline-success:not(:disabled):not(.disabled):active, +.show > .btn-outline-success.dropdown-toggle { + color: #fff; + background-color: #28a745; + border-color: #28a745; +} +.btn-outline-success:not(:disabled):not(.disabled).active:focus, +.btn-outline-success:not(:disabled):not(.disabled):active:focus, +.show > .btn-outline-success.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} +.btn-outline-info { + color: #17a2b8; + border-color: #17a2b8; +} +.btn-outline-info:hover { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-outline-info.focus, +.btn-outline-info:focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} +.btn-outline-info.disabled, +.btn-outline-info:disabled { + color: #17a2b8; + background-color: transparent; +} +.btn-outline-info:not(:disabled):not(.disabled).active, +.btn-outline-info:not(:disabled):not(.disabled):active, +.show > .btn-outline-info.dropdown-toggle { + color: #fff; + background-color: #17a2b8; + border-color: #17a2b8; +} +.btn-outline-info:not(:disabled):not(.disabled).active:focus, +.btn-outline-info:not(:disabled):not(.disabled):active:focus, +.show > .btn-outline-info.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} +.btn-outline-warning { + color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning:hover { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning.focus, +.btn-outline-warning:focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} +.btn-outline-warning.disabled, +.btn-outline-warning:disabled { + color: #ffc107; + background-color: transparent; +} +.btn-outline-warning:not(:disabled):not(.disabled).active, +.btn-outline-warning:not(:disabled):not(.disabled):active, +.show > .btn-outline-warning.dropdown-toggle { + color: #212529; + background-color: #ffc107; + border-color: #ffc107; +} +.btn-outline-warning:not(:disabled):not(.disabled).active:focus, +.btn-outline-warning:not(:disabled):not(.disabled):active:focus, +.show > .btn-outline-warning.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} +.btn-outline-danger { + color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger:hover { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger.focus, +.btn-outline-danger:focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} +.btn-outline-danger.disabled, +.btn-outline-danger:disabled { + color: #dc3545; + background-color: transparent; +} +.btn-outline-danger:not(:disabled):not(.disabled).active, +.btn-outline-danger:not(:disabled):not(.disabled):active, +.show > .btn-outline-danger.dropdown-toggle { + color: #fff; + background-color: #dc3545; + border-color: #dc3545; +} +.btn-outline-danger:not(:disabled):not(.disabled).active:focus, +.btn-outline-danger:not(:disabled):not(.disabled):active:focus, +.show > .btn-outline-danger.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} +.btn-outline-light { + color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light:hover { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light.focus, +.btn-outline-light:focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} +.btn-outline-light.disabled, +.btn-outline-light:disabled { + color: #f8f9fa; + background-color: transparent; +} +.btn-outline-light:not(:disabled):not(.disabled).active, +.btn-outline-light:not(:disabled):not(.disabled):active, +.show > .btn-outline-light.dropdown-toggle { + color: #212529; + background-color: #f8f9fa; + border-color: #f8f9fa; +} +.btn-outline-light:not(:disabled):not(.disabled).active:focus, +.btn-outline-light:not(:disabled):not(.disabled):active:focus, +.show > .btn-outline-light.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} +.btn-outline-dark { + color: #343a40; + border-color: #343a40; +} +.btn-outline-dark:hover { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-outline-dark.focus, +.btn-outline-dark:focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} +.btn-outline-dark.disabled, +.btn-outline-dark:disabled { + color: #343a40; + background-color: transparent; +} +.btn-outline-dark:not(:disabled):not(.disabled).active, +.btn-outline-dark:not(:disabled):not(.disabled):active, +.show > .btn-outline-dark.dropdown-toggle { + color: #fff; + background-color: #343a40; + border-color: #343a40; +} +.btn-outline-dark:not(:disabled):not(.disabled).active:focus, +.btn-outline-dark:not(:disabled):not(.disabled):active:focus, +.show > .btn-outline-dark.dropdown-toggle:focus { + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} +.btn-link { + font-weight: 400; + color: #007bff; + text-decoration: none; +} +.btn-link:hover { + color: #0056b3; + text-decoration: underline; +} +.btn-link.focus, +.btn-link:focus { + text-decoration: underline; +} +.btn-link.disabled, +.btn-link:disabled { + color: #6c757d; + pointer-events: none; +} +.btn-group-lg > .btn, +.btn-lg { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} +.btn-group-sm > .btn, +.btn-sm { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} +.btn-block { + display: block; + width: 100%; +} +.btn-block + .btn-block { + margin-top: 0.5rem; +} +input[type='button'].btn-block, +input[type='reset'].btn-block, +input[type='submit'].btn-block { + width: 100%; +} +.fade { + transition: opacity 0.15s linear; +} +@media (prefers-reduced-motion: reduce) { + .fade { + transition: none; + } +} +.fade:not(.show) { + opacity: 0; +} +.collapse:not(.show) { + display: none; +} +.collapsing { + position: relative; + height: 0; + overflow: hidden; + transition: height 0.35s ease; +} +@media (prefers-reduced-motion: reduce) { + .collapsing { + transition: none; + } +} +.dropdown, +.dropleft, +.dropright, +.dropup { + position: relative; +} +.dropdown-toggle { + white-space: nowrap; +} +.dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ''; + border-top: 0.3em solid; + border-right: 0.3em solid transparent; + border-bottom: 0; + border-left: 0.3em solid transparent; +} +.dropdown-toggle:empty::after { + margin-left: 0; +} +.dropdown-menu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + display: none; + float: left; + min-width: 10rem; + padding: 0.5rem 0; + margin: 0.125rem 0 0; + font-size: 1rem; + color: #212529; + text-align: left; + list-style: none; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25rem; +} +.dropdown-menu-left { + right: auto; + left: 0; +} +.dropdown-menu-right { + right: 0; + left: auto; +} +@media (min-width: 576px) { + .dropdown-menu-sm-left { + right: auto; + left: 0; + } + .dropdown-menu-sm-right { + right: 0; + left: auto; + } +} +@media (min-width: 768px) { + .dropdown-menu-md-left { + right: auto; + left: 0; + } + .dropdown-menu-md-right { + right: 0; + left: auto; + } +} +@media (min-width: 992px) { + .dropdown-menu-lg-left { + right: auto; + left: 0; + } + .dropdown-menu-lg-right { + right: 0; + left: auto; + } +} +@media (min-width: 1200px) { + .dropdown-menu-xl-left { + right: auto; + left: 0; + } + .dropdown-menu-xl-right { + right: 0; + left: auto; + } +} +.dropup .dropdown-menu { + top: auto; + bottom: 100%; + margin-top: 0; + margin-bottom: 0.125rem; +} +.dropup .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ''; + border-top: 0; + border-right: 0.3em solid transparent; + border-bottom: 0.3em solid; + border-left: 0.3em solid transparent; +} +.dropup .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropright .dropdown-menu { + top: 0; + right: auto; + left: 100%; + margin-top: 0; + margin-left: 0.125rem; +} +.dropright .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ''; + border-top: 0.3em solid transparent; + border-right: 0; + border-bottom: 0.3em solid transparent; + border-left: 0.3em solid; +} +.dropright .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropright .dropdown-toggle::after { + vertical-align: 0; +} +.dropleft .dropdown-menu { + top: 0; + right: 100%; + left: auto; + margin-top: 0; + margin-right: 0.125rem; +} +.dropleft .dropdown-toggle::after { + display: inline-block; + margin-left: 0.255em; + vertical-align: 0.255em; + content: ''; +} +.dropleft .dropdown-toggle::after { + display: none; +} +.dropleft .dropdown-toggle::before { + display: inline-block; + margin-right: 0.255em; + vertical-align: 0.255em; + content: ''; + border-top: 0.3em solid transparent; + border-right: 0.3em solid; + border-bottom: 0.3em solid transparent; +} +.dropleft .dropdown-toggle:empty::after { + margin-left: 0; +} +.dropleft .dropdown-toggle::before { + vertical-align: 0; +} +.dropdown-menu[x-placement^='bottom'], +.dropdown-menu[x-placement^='left'], +.dropdown-menu[x-placement^='right'], +.dropdown-menu[x-placement^='top'] { + right: auto; + bottom: auto; +} +.dropdown-divider { + height: 0; + margin: 0.5rem 0; + overflow: hidden; + border-top: 1px solid #e9ecef; +} +.dropdown-item { + display: block; + width: 100%; + padding: 0.25rem 1.5rem; + clear: both; + font-weight: 400; + color: #212529; + text-align: inherit; + white-space: nowrap; + background-color: transparent; + border: 0; +} +.dropdown-item:focus, +.dropdown-item:hover { + color: #16181b; + text-decoration: none; + background-color: #f8f9fa; +} +.dropdown-item.active, +.dropdown-item:active { + color: #fff; + text-decoration: none; + background-color: #007bff; +} +.dropdown-item.disabled, +.dropdown-item:disabled { + color: #6c757d; + pointer-events: none; + background-color: transparent; +} +.dropdown-menu.show { + display: block; +} +.dropdown-header { + display: block; + padding: 0.5rem 1.5rem; + margin-bottom: 0; + font-size: 0.875rem; + color: #6c757d; + white-space: nowrap; +} +.dropdown-item-text { + display: block; + padding: 0.25rem 1.5rem; + color: #212529; +} +.btn-group, +.btn-group-vertical { + position: relative; + display: -ms-inline-flexbox; + display: inline-flex; + vertical-align: middle; +} +.btn-group-vertical > .btn, +.btn-group > .btn { + position: relative; + -ms-flex: 1 1 auto; + flex: 1 1 auto; +} +.btn-group-vertical > .btn:hover, +.btn-group > .btn:hover { + z-index: 1; +} +.btn-group-vertical > .btn.active, +.btn-group-vertical > .btn:active, +.btn-group-vertical > .btn:focus, +.btn-group > .btn.active, +.btn-group > .btn:active, +.btn-group > .btn:focus { + z-index: 1; +} +.btn-toolbar { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-pack: start; + justify-content: flex-start; +} +.btn-toolbar .input-group { + width: auto; +} +.btn-group > .btn-group:not(:first-child), +.btn-group > .btn:not(:first-child) { + margin-left: -1px; +} +.btn-group > .btn-group:not(:last-child) > .btn, +.btn-group > .btn:not(:last-child):not(.dropdown-toggle) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.btn-group > .btn-group:not(:first-child) > .btn, +.btn-group > .btn:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.dropdown-toggle-split { + padding-right: 0.5625rem; + padding-left: 0.5625rem; +} +.dropdown-toggle-split::after, +.dropright .dropdown-toggle-split::after, +.dropup .dropdown-toggle-split::after { + margin-left: 0; +} +.dropleft .dropdown-toggle-split::before { + margin-right: 0; +} +.btn-group-sm > .btn + .dropdown-toggle-split, +.btn-sm + .dropdown-toggle-split { + padding-right: 0.375rem; + padding-left: 0.375rem; +} +.btn-group-lg > .btn + .dropdown-toggle-split, +.btn-lg + .dropdown-toggle-split { + padding-right: 0.75rem; + padding-left: 0.75rem; +} +.btn-group-vertical { + -ms-flex-direction: column; + flex-direction: column; + -ms-flex-align: start; + align-items: flex-start; + -ms-flex-pack: center; + justify-content: center; +} +.btn-group-vertical > .btn, +.btn-group-vertical > .btn-group { + width: 100%; +} +.btn-group-vertical > .btn-group:not(:first-child), +.btn-group-vertical > .btn:not(:first-child) { + margin-top: -1px; +} +.btn-group-vertical > .btn-group:not(:last-child) > .btn, +.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle) { + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.btn-group-vertical > .btn-group:not(:first-child) > .btn, +.btn-group-vertical > .btn:not(:first-child) { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.btn-group-toggle > .btn, +.btn-group-toggle > .btn-group > .btn { + margin-bottom: 0; +} +.btn-group-toggle > .btn input[type='checkbox'], +.btn-group-toggle > .btn input[type='radio'], +.btn-group-toggle > .btn-group > .btn input[type='checkbox'], +.btn-group-toggle > .btn-group > .btn input[type='radio'] { + position: absolute; + clip: rect(0, 0, 0, 0); + pointer-events: none; +} +.input-group { + position: relative; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-align: stretch; + align-items: stretch; + width: 100%; +} +.input-group > .custom-file, +.input-group > .custom-select, +.input-group > .form-control, +.input-group > .form-control-plaintext { + position: relative; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + width: 1%; + min-width: 0; + margin-bottom: 0; +} +.input-group > .custom-file + .custom-file, +.input-group > .custom-file + .custom-select, +.input-group > .custom-file + .form-control, +.input-group > .custom-select + .custom-file, +.input-group > .custom-select + .custom-select, +.input-group > .custom-select + .form-control, +.input-group > .form-control + .custom-file, +.input-group > .form-control + .custom-select, +.input-group > .form-control + .form-control, +.input-group > .form-control-plaintext + .custom-file, +.input-group > .form-control-plaintext + .custom-select, +.input-group > .form-control-plaintext + .form-control { + margin-left: -1px; +} +.input-group > .custom-file .custom-file-input:focus ~ .custom-file-label, +.input-group > .custom-select:focus, +.input-group > .form-control:focus { + z-index: 3; +} +.input-group > .custom-file .custom-file-input:focus { + z-index: 4; +} +.input-group > .custom-select:not(:last-child), +.input-group > .form-control:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .custom-select:not(:first-child), +.input-group > .form-control:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group > .custom-file { + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; +} +.input-group > .custom-file:not(:last-child) .custom-file-label, +.input-group > .custom-file:not(:last-child) .custom-file-label::after { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .custom-file:not(:first-child) .custom-file-label { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.input-group-append, +.input-group-prepend { + display: -ms-flexbox; + display: flex; +} +.input-group-append .btn, +.input-group-prepend .btn { + position: relative; + z-index: 2; +} +.input-group-append .btn:focus, +.input-group-prepend .btn:focus { + z-index: 3; +} +.input-group-append .btn + .btn, +.input-group-append .btn + .input-group-text, +.input-group-append .input-group-text + .btn, +.input-group-append .input-group-text + .input-group-text, +.input-group-prepend .btn + .btn, +.input-group-prepend .btn + .input-group-text, +.input-group-prepend .input-group-text + .btn, +.input-group-prepend .input-group-text + .input-group-text { + margin-left: -1px; +} +.input-group-prepend { + margin-right: -1px; +} +.input-group-append { + margin-left: -1px; +} +.input-group-text { + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + padding: 0.375rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + text-align: center; + white-space: nowrap; + background-color: #e9ecef; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} +.input-group-text input[type='checkbox'], +.input-group-text input[type='radio'] { + margin-top: 0; +} +.input-group-lg > .custom-select, +.input-group-lg > .form-control:not(textarea) { + height: calc(1.5em + 1rem + 2px); +} +.input-group-lg > .custom-select, +.input-group-lg > .form-control, +.input-group-lg > .input-group-append > .btn, +.input-group-lg > .input-group-append > .input-group-text, +.input-group-lg > .input-group-prepend > .btn, +.input-group-lg > .input-group-prepend > .input-group-text { + padding: 0.5rem 1rem; + font-size: 1.25rem; + line-height: 1.5; + border-radius: 0.3rem; +} +.input-group-sm > .custom-select, +.input-group-sm > .form-control:not(textarea) { + height: calc(1.5em + 0.5rem + 2px); +} +.input-group-sm > .custom-select, +.input-group-sm > .form-control, +.input-group-sm > .input-group-append > .btn, +.input-group-sm > .input-group-append > .input-group-text, +.input-group-sm > .input-group-prepend > .btn, +.input-group-sm > .input-group-prepend > .input-group-text { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; + border-radius: 0.2rem; +} +.input-group-lg > .custom-select, +.input-group-sm > .custom-select { + padding-right: 1.75rem; +} +.input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle), +.input-group > .input-group-append:last-child > .input-group-text:not(:last-child), +.input-group > .input-group-append:not(:last-child) > .btn, +.input-group > .input-group-append:not(:last-child) > .input-group-text, +.input-group > .input-group-prepend > .btn, +.input-group > .input-group-prepend > .input-group-text { + border-top-right-radius: 0; + border-bottom-right-radius: 0; +} +.input-group > .input-group-append > .btn, +.input-group > .input-group-append > .input-group-text, +.input-group > .input-group-prepend:first-child > .btn:not(:first-child), +.input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child), +.input-group > .input-group-prepend:not(:first-child) > .btn, +.input-group > .input-group-prepend:not(:first-child) > .input-group-text { + border-top-left-radius: 0; + border-bottom-left-radius: 0; +} +.custom-control { + position: relative; + z-index: 1; + display: block; + min-height: 1.5rem; + padding-left: 1.5rem; +} +.custom-control-inline { + display: -ms-inline-flexbox; + display: inline-flex; + margin-right: 1rem; +} +.custom-control-input { + position: absolute; + left: 0; + z-index: -1; + width: 1rem; + height: 1.25rem; + opacity: 0; +} +.custom-control-input:checked ~ .custom-control-label::before { + color: #fff; + border-color: #007bff; + background-color: #007bff; +} +.custom-control-input:focus ~ .custom-control-label::before { + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-control-input:focus:not(:checked) ~ .custom-control-label::before { + border-color: #80bdff; +} +.custom-control-input:not(:disabled):active ~ .custom-control-label::before { + color: #fff; + background-color: #b3d7ff; + border-color: #b3d7ff; +} +.custom-control-input:disabled ~ .custom-control-label, +.custom-control-input[disabled] ~ .custom-control-label { + color: #6c757d; +} +.custom-control-input:disabled ~ .custom-control-label::before, +.custom-control-input[disabled] ~ .custom-control-label::before { + background-color: #e9ecef; +} +.custom-control-label { + position: relative; + margin-bottom: 0; + vertical-align: top; +} +.custom-control-label::before { + position: absolute; + top: 0.25rem; + left: -1.5rem; + display: block; + width: 1rem; + height: 1rem; + pointer-events: none; + content: ''; + background-color: #fff; + border: #adb5bd solid 1px; +} +.custom-control-label::after { + position: absolute; + top: 0.25rem; + left: -1.5rem; + display: block; + width: 1rem; + height: 1rem; + content: ''; + background: no-repeat 50%/50% 50%; +} +.custom-checkbox .custom-control-label::before { + border-radius: 0.25rem; +} +.custom-checkbox .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26l2.974 2.99L8 2.193z'/%3e%3c/svg%3e"); +} +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before { + border-color: #007bff; + background-color: #007bff; +} +.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='4' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e"); +} +.custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} +.custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} +.custom-radio .custom-control-label::before { + border-radius: 50%; +} +.custom-radio .custom-control-input:checked ~ .custom-control-label::after { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e"); +} +.custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} +.custom-switch { + padding-left: 2.25rem; +} +.custom-switch .custom-control-label::before { + left: -2.25rem; + width: 1.75rem; + pointer-events: all; + border-radius: 0.5rem; +} +.custom-switch .custom-control-label::after { + top: calc(0.25rem + 2px); + left: calc(-2.25rem + 2px); + width: calc(1rem - 4px); + height: calc(1rem - 4px); + background-color: #adb5bd; + border-radius: 0.5rem; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, + -webkit-transform 0.15s ease-in-out; + transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: transform 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out, + -webkit-transform 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .custom-switch .custom-control-label::after { + transition: none; + } +} +.custom-switch .custom-control-input:checked ~ .custom-control-label::after { + background-color: #fff; + -webkit-transform: translateX(0.75rem); + transform: translateX(0.75rem); +} +.custom-switch .custom-control-input:disabled:checked ~ .custom-control-label::before { + background-color: rgba(0, 123, 255, 0.5); +} +.custom-select { + display: inline-block; + width: 100%; + height: calc(1.5em + 0.75rem + 2px); + padding: 0.375rem 1.75rem 0.375rem 0.75rem; + font-size: 1rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + vertical-align: middle; + background: #fff + url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='4' height='5' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") + no-repeat right 0.75rem center/8px 10px; + border: 1px solid #ced4da; + border-radius: 0.25rem; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.custom-select:focus { + border-color: #80bdff; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-select:focus::-ms-value { + color: #495057; + background-color: #fff; +} +.custom-select[multiple], +.custom-select[size]:not([size='1']) { + height: auto; + padding-right: 0.75rem; + background-image: none; +} +.custom-select:disabled { + color: #6c757d; + background-color: #e9ecef; +} +.custom-select::-ms-expand { + display: none; +} +.custom-select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 #495057; +} +.custom-select-sm { + height: calc(1.5em + 0.5rem + 2px); + padding-top: 0.25rem; + padding-bottom: 0.25rem; + padding-left: 0.5rem; + font-size: 0.875rem; +} +.custom-select-lg { + height: calc(1.5em + 1rem + 2px); + padding-top: 0.5rem; + padding-bottom: 0.5rem; + padding-left: 1rem; + font-size: 1.25rem; +} +.custom-file { + position: relative; + display: inline-block; + width: 100%; + height: calc(1.5em + 0.75rem + 2px); + margin-bottom: 0; +} +.custom-file-input { + position: relative; + z-index: 2; + width: 100%; + height: calc(1.5em + 0.75rem + 2px); + margin: 0; + opacity: 0; +} +.custom-file-input:focus ~ .custom-file-label { + border-color: #80bdff; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-file-input:disabled ~ .custom-file-label, +.custom-file-input[disabled] ~ .custom-file-label { + background-color: #e9ecef; +} +.custom-file-input:lang(en) ~ .custom-file-label::after { + content: 'Browse'; +} +.custom-file-input ~ .custom-file-label[data-browse]::after { + content: attr(data-browse); +} +.custom-file-label { + position: absolute; + top: 0; + right: 0; + left: 0; + z-index: 1; + height: calc(1.5em + 0.75rem + 2px); + padding: 0.375rem 0.75rem; + font-weight: 400; + line-height: 1.5; + color: #495057; + background-color: #fff; + border: 1px solid #ced4da; + border-radius: 0.25rem; +} +.custom-file-label::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + z-index: 3; + display: block; + height: calc(1.5em + 0.75rem); + padding: 0.375rem 0.75rem; + line-height: 1.5; + color: #495057; + content: 'Browse'; + background-color: #e9ecef; + border-left: inherit; + border-radius: 0 0.25rem 0.25rem 0; +} +.custom-range { + width: 100%; + height: 1.4rem; + padding: 0; + background-color: transparent; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} +.custom-range:focus { + outline: 0; +} +.custom-range:focus::-webkit-slider-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-range:focus::-moz-range-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-range:focus::-ms-thumb { + box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.custom-range::-moz-focus-outer { + border: 0; +} +.custom-range::-webkit-slider-thumb { + width: 1rem; + height: 1rem; + margin-top: -0.25rem; + background-color: #007bff; + border: 0; + border-radius: 1rem; + -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + -webkit-appearance: none; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .custom-range::-webkit-slider-thumb { + -webkit-transition: none; + transition: none; + } +} +.custom-range::-webkit-slider-thumb:active { + background-color: #b3d7ff; +} +.custom-range::-webkit-slider-runnable-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.custom-range::-moz-range-thumb { + width: 1rem; + height: 1rem; + background-color: #007bff; + border: 0; + border-radius: 1rem; + -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + -moz-appearance: none; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .custom-range::-moz-range-thumb { + -moz-transition: none; + transition: none; + } +} +.custom-range::-moz-range-thumb:active { + background-color: #b3d7ff; +} +.custom-range::-moz-range-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: #dee2e6; + border-color: transparent; + border-radius: 1rem; +} +.custom-range::-ms-thumb { + width: 1rem; + height: 1rem; + margin-top: 0; + margin-right: 0.2rem; + margin-left: 0.2rem; + background-color: #007bff; + border: 0; + border-radius: 1rem; + -ms-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; + appearance: none; +} +@media (prefers-reduced-motion: reduce) { + .custom-range::-ms-thumb { + -ms-transition: none; + transition: none; + } +} +.custom-range::-ms-thumb:active { + background-color: #b3d7ff; +} +.custom-range::-ms-track { + width: 100%; + height: 0.5rem; + color: transparent; + cursor: pointer; + background-color: transparent; + border-color: transparent; + border-width: 0.5rem; +} +.custom-range::-ms-fill-lower { + background-color: #dee2e6; + border-radius: 1rem; +} +.custom-range::-ms-fill-upper { + margin-right: 15px; + background-color: #dee2e6; + border-radius: 1rem; +} +.custom-range:disabled::-webkit-slider-thumb { + background-color: #adb5bd; +} +.custom-range:disabled::-webkit-slider-runnable-track { + cursor: default; +} +.custom-range:disabled::-moz-range-thumb { + background-color: #adb5bd; +} +.custom-range:disabled::-moz-range-track { + cursor: default; +} +.custom-range:disabled::-ms-thumb { + background-color: #adb5bd; +} +.custom-control-label::before, +.custom-file-label, +.custom-select { + transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .custom-control-label::before, + .custom-file-label, + .custom-select { + transition: none; + } +} +.nav { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.nav-link { + display: block; + padding: 0.5rem 1rem; +} +.nav-link:focus, +.nav-link:hover { + text-decoration: none; +} +.nav-link.disabled { + color: #6c757d; + pointer-events: none; + cursor: default; +} +.nav-tabs { + border-bottom: 1px solid #dee2e6; +} +.nav-tabs .nav-item { + margin-bottom: -1px; +} +.nav-tabs .nav-link { + border: 1px solid transparent; + border-top-left-radius: 0.25rem; + border-top-right-radius: 0.25rem; +} +.nav-tabs .nav-link:focus, +.nav-tabs .nav-link:hover { + border-color: #e9ecef #e9ecef #dee2e6; +} +.nav-tabs .nav-link.disabled { + color: #6c757d; + background-color: transparent; + border-color: transparent; +} +.nav-tabs .nav-item.show .nav-link, +.nav-tabs .nav-link.active { + color: #495057; + background-color: #fff; + border-color: #dee2e6 #dee2e6 #fff; +} +.nav-tabs .dropdown-menu { + margin-top: -1px; + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.nav-pills .nav-link { + border-radius: 0.25rem; +} +.nav-pills .nav-link.active, +.nav-pills .show > .nav-link { + color: #fff; + background-color: #007bff; +} +.nav-fill .nav-item, +.nav-fill > .nav-link { + -ms-flex: 1 1 auto; + flex: 1 1 auto; + text-align: center; +} +.nav-justified .nav-item, +.nav-justified > .nav-link { + -ms-flex-preferred-size: 0; + flex-basis: 0; + -ms-flex-positive: 1; + flex-grow: 1; + text-align: center; +} +.tab-content > .tab-pane { + display: none; +} +.tab-content > .active { + display: block; +} +.navbar { + position: relative; + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 0.5rem 1rem; +} +.navbar .container, +.navbar .container-fluid, +.navbar .container-lg, +.navbar .container-md, +.navbar .container-sm, +.navbar .container-xl { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: justify; + justify-content: space-between; +} +.navbar-brand { + display: inline-block; + padding-top: 0.3125rem; + padding-bottom: 0.3125rem; + margin-right: 1rem; + font-size: 1.25rem; + line-height: inherit; + white-space: nowrap; +} +.navbar-brand:focus, +.navbar-brand:hover { + text-decoration: none; +} +.navbar-nav { + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + list-style: none; +} +.navbar-nav .nav-link { + padding-right: 0; + padding-left: 0; +} +.navbar-nav .dropdown-menu { + position: static; + float: none; +} +.navbar-text { + display: inline-block; + padding-top: 0.5rem; + padding-bottom: 0.5rem; +} +.navbar-collapse { + -ms-flex-preferred-size: 100%; + flex-basis: 100%; + -ms-flex-positive: 1; + flex-grow: 1; + -ms-flex-align: center; + align-items: center; +} +.navbar-toggler { + padding: 0.25rem 0.75rem; + font-size: 1.25rem; + line-height: 1; + background-color: transparent; + border: 1px solid transparent; + border-radius: 0.25rem; +} +.navbar-toggler:focus, +.navbar-toggler:hover { + text-decoration: none; +} +.navbar-toggler-icon { + display: inline-block; + width: 1.5em; + height: 1.5em; + vertical-align: middle; + content: ''; + background: no-repeat center center; + background-size: 100% 100%; +} +@media (max-width: 575.98px) { + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid, + .navbar-expand-sm > .container-lg, + .navbar-expand-sm > .container-md, + .navbar-expand-sm > .container-sm, + .navbar-expand-sm > .container-xl { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 576px) { + .navbar-expand-sm { + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-sm .navbar-nav { + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-sm .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-sm .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-sm > .container, + .navbar-expand-sm > .container-fluid, + .navbar-expand-sm > .container-lg, + .navbar-expand-sm > .container-md, + .navbar-expand-sm > .container-sm, + .navbar-expand-sm > .container-xl { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-sm .navbar-collapse { + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-sm .navbar-toggler { + display: none; + } +} +@media (max-width: 767.98px) { + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid, + .navbar-expand-md > .container-lg, + .navbar-expand-md > .container-md, + .navbar-expand-md > .container-sm, + .navbar-expand-md > .container-xl { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 768px) { + .navbar-expand-md { + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-md .navbar-nav { + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-md .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-md .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-md > .container, + .navbar-expand-md > .container-fluid, + .navbar-expand-md > .container-lg, + .navbar-expand-md > .container-md, + .navbar-expand-md > .container-sm, + .navbar-expand-md > .container-xl { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-md .navbar-collapse { + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-md .navbar-toggler { + display: none; + } +} +@media (max-width: 991.98px) { + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid, + .navbar-expand-lg > .container-lg, + .navbar-expand-lg > .container-md, + .navbar-expand-lg > .container-sm, + .navbar-expand-lg > .container-xl { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 992px) { + .navbar-expand-lg { + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-lg .navbar-nav { + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-lg .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-lg .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-lg > .container, + .navbar-expand-lg > .container-fluid, + .navbar-expand-lg > .container-lg, + .navbar-expand-lg > .container-md, + .navbar-expand-lg > .container-sm, + .navbar-expand-lg > .container-xl { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-lg .navbar-collapse { + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-lg .navbar-toggler { + display: none; + } +} +@media (max-width: 1199.98px) { + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid, + .navbar-expand-xl > .container-lg, + .navbar-expand-xl > .container-md, + .navbar-expand-xl > .container-sm, + .navbar-expand-xl > .container-xl { + padding-right: 0; + padding-left: 0; + } +} +@media (min-width: 1200px) { + .navbar-expand-xl { + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -ms-flex-pack: start; + justify-content: flex-start; + } + .navbar-expand-xl .navbar-nav { + -ms-flex-direction: row; + flex-direction: row; + } + .navbar-expand-xl .navbar-nav .dropdown-menu { + position: absolute; + } + .navbar-expand-xl .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; + } + .navbar-expand-xl > .container, + .navbar-expand-xl > .container-fluid, + .navbar-expand-xl > .container-lg, + .navbar-expand-xl > .container-md, + .navbar-expand-xl > .container-sm, + .navbar-expand-xl > .container-xl { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; + } + .navbar-expand-xl .navbar-collapse { + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; + } + .navbar-expand-xl .navbar-toggler { + display: none; + } +} +.navbar-expand { + -ms-flex-flow: row nowrap; + flex-flow: row nowrap; + -ms-flex-pack: start; + justify-content: flex-start; +} +.navbar-expand > .container, +.navbar-expand > .container-fluid, +.navbar-expand > .container-lg, +.navbar-expand > .container-md, +.navbar-expand > .container-sm, +.navbar-expand > .container-xl { + padding-right: 0; + padding-left: 0; +} +.navbar-expand .navbar-nav { + -ms-flex-direction: row; + flex-direction: row; +} +.navbar-expand .navbar-nav .dropdown-menu { + position: absolute; +} +.navbar-expand .navbar-nav .nav-link { + padding-right: 0.5rem; + padding-left: 0.5rem; +} +.navbar-expand > .container, +.navbar-expand > .container-fluid, +.navbar-expand > .container-lg, +.navbar-expand > .container-md, +.navbar-expand > .container-sm, +.navbar-expand > .container-xl { + -ms-flex-wrap: nowrap; + flex-wrap: nowrap; +} +.navbar-expand .navbar-collapse { + display: -ms-flexbox !important; + display: flex !important; + -ms-flex-preferred-size: auto; + flex-basis: auto; +} +.navbar-expand .navbar-toggler { + display: none; +} +.navbar-light .navbar-brand { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-brand:focus, +.navbar-light .navbar-brand:hover { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-nav .nav-link { + color: rgba(0, 0, 0, 0.5); +} +.navbar-light .navbar-nav .nav-link:focus, +.navbar-light .navbar-nav .nav-link:hover { + color: rgba(0, 0, 0, 0.7); +} +.navbar-light .navbar-nav .nav-link.disabled { + color: rgba(0, 0, 0, 0.3); +} +.navbar-light .navbar-nav .active > .nav-link, +.navbar-light .navbar-nav .nav-link.active, +.navbar-light .navbar-nav .nav-link.show, +.navbar-light .navbar-nav .show > .nav-link { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-toggler { + color: rgba(0, 0, 0, 0.5); + border-color: rgba(0, 0, 0, 0.1); +} +.navbar-light .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} +.navbar-light .navbar-text { + color: rgba(0, 0, 0, 0.5); +} +.navbar-light .navbar-text a { + color: rgba(0, 0, 0, 0.9); +} +.navbar-light .navbar-text a:focus, +.navbar-light .navbar-text a:hover { + color: rgba(0, 0, 0, 0.9); +} +.navbar-dark .navbar-brand { + color: #fff; +} +.navbar-dark .navbar-brand:focus, +.navbar-dark .navbar-brand:hover { + color: #fff; +} +.navbar-dark .navbar-nav .nav-link { + color: rgba(255, 255, 255, 0.5); +} +.navbar-dark .navbar-nav .nav-link:focus, +.navbar-dark .navbar-nav .nav-link:hover { + color: rgba(255, 255, 255, 0.75); +} +.navbar-dark .navbar-nav .nav-link.disabled { + color: rgba(255, 255, 255, 0.25); +} +.navbar-dark .navbar-nav .active > .nav-link, +.navbar-dark .navbar-nav .nav-link.active, +.navbar-dark .navbar-nav .nav-link.show, +.navbar-dark .navbar-nav .show > .nav-link { + color: #fff; +} +.navbar-dark .navbar-toggler { + color: rgba(255, 255, 255, 0.5); + border-color: rgba(255, 255, 255, 0.1); +} +.navbar-dark .navbar-toggler-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.5%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e"); +} +.navbar-dark .navbar-text { + color: rgba(255, 255, 255, 0.5); +} +.navbar-dark .navbar-text a { + color: #fff; +} +.navbar-dark .navbar-text a:focus, +.navbar-dark .navbar-text a:hover { + color: #fff; +} +.card { + position: relative; + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + min-width: 0; + word-wrap: break-word; + background-color: #fff; + background-clip: border-box; + border: 1px solid rgba(0, 0, 0, 0.125); + border-radius: 0.25rem; +} +.card > hr { + margin-right: 0; + margin-left: 0; +} +.card > .list-group { + border-top: inherit; + border-bottom: inherit; +} +.card > .list-group:first-child { + border-top-width: 0; + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.card > .list-group:last-child { + border-bottom-width: 0; + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} +.card > .card-header + .list-group, +.card > .list-group + .card-footer { + border-top: 0; +} +.card-body { + -ms-flex: 1 1 auto; + flex: 1 1 auto; + min-height: 1px; + padding: 1.25rem; +} +.card-title { + margin-bottom: 0.75rem; +} +.card-subtitle { + margin-top: -0.375rem; + margin-bottom: 0; +} +.card-text:last-child { + margin-bottom: 0; +} +.card-link:hover { + text-decoration: none; +} +.card-link + .card-link { + margin-left: 1.25rem; +} +.card-header { + padding: 0.75rem 1.25rem; + margin-bottom: 0; + background-color: rgba(0, 0, 0, 0.03); + border-bottom: 1px solid rgba(0, 0, 0, 0.125); +} +.card-header:first-child { + border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; +} +.card-footer { + padding: 0.75rem 1.25rem; + background-color: rgba(0, 0, 0, 0.03); + border-top: 1px solid rgba(0, 0, 0, 0.125); +} +.card-footer:last-child { + border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); +} +.card-header-tabs { + margin-right: -0.625rem; + margin-bottom: -0.75rem; + margin-left: -0.625rem; + border-bottom: 0; +} +.card-header-pills { + margin-right: -0.625rem; + margin-left: -0.625rem; +} +.card-img-overlay { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + padding: 1.25rem; + border-radius: calc(0.25rem - 1px); +} +.card-img, +.card-img-bottom, +.card-img-top { + -ms-flex-negative: 0; + flex-shrink: 0; + width: 100%; +} +.card-img, +.card-img-top { + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.card-img, +.card-img-bottom { + border-bottom-right-radius: calc(0.25rem - 1px); + border-bottom-left-radius: calc(0.25rem - 1px); +} +.card-deck .card { + margin-bottom: 15px; +} +@media (min-width: 576px) { + .card-deck { + display: -ms-flexbox; + display: flex; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + margin-right: -15px; + margin-left: -15px; + } + .card-deck .card { + -ms-flex: 1 0 0%; + flex: 1 0 0%; + margin-right: 15px; + margin-bottom: 0; + margin-left: 15px; + } +} +.card-group > .card { + margin-bottom: 15px; +} +@media (min-width: 576px) { + .card-group { + display: -ms-flexbox; + display: flex; + -ms-flex-flow: row wrap; + flex-flow: row wrap; + } + .card-group > .card { + -ms-flex: 1 0 0%; + flex: 1 0 0%; + margin-bottom: 0; + } + .card-group > .card + .card { + margin-left: 0; + border-left: 0; + } + .card-group > .card:not(:last-child) { + border-top-right-radius: 0; + border-bottom-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-header, + .card-group > .card:not(:last-child) .card-img-top { + border-top-right-radius: 0; + } + .card-group > .card:not(:last-child) .card-footer, + .card-group > .card:not(:last-child) .card-img-bottom { + border-bottom-right-radius: 0; + } + .card-group > .card:not(:first-child) { + border-top-left-radius: 0; + border-bottom-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-header, + .card-group > .card:not(:first-child) .card-img-top { + border-top-left-radius: 0; + } + .card-group > .card:not(:first-child) .card-footer, + .card-group > .card:not(:first-child) .card-img-bottom { + border-bottom-left-radius: 0; + } +} +.card-columns .card { + margin-bottom: 0.75rem; +} +@media (min-width: 576px) { + .card-columns { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + -webkit-column-gap: 1.25rem; + -moz-column-gap: 1.25rem; + column-gap: 1.25rem; + orphans: 1; + widows: 1; + } + .card-columns .card { + display: inline-block; + width: 100%; + } +} +.accordion { + overflow-anchor: none; +} +.accordion > .card { + overflow: hidden; +} +.accordion > .card:not(:last-of-type) { + border-bottom: 0; + border-bottom-right-radius: 0; + border-bottom-left-radius: 0; +} +.accordion > .card:not(:first-of-type) { + border-top-left-radius: 0; + border-top-right-radius: 0; +} +.accordion > .card > .card-header { + border-radius: 0; + margin-bottom: -1px; +} +.breadcrumb { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + padding: 0.75rem 1rem; + margin-bottom: 1rem; + list-style: none; + background-color: #e9ecef; + border-radius: 0.25rem; +} +.breadcrumb-item { + display: -ms-flexbox; + display: flex; +} +.breadcrumb-item + .breadcrumb-item { + padding-left: 0.5rem; +} +.breadcrumb-item + .breadcrumb-item::before { + display: inline-block; + padding-right: 0.5rem; + color: #6c757d; + content: '/'; +} +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: underline; +} +.breadcrumb-item + .breadcrumb-item:hover::before { + text-decoration: none; +} +.breadcrumb-item.active { + color: #6c757d; +} +.pagination { + display: -ms-flexbox; + display: flex; + padding-left: 0; + list-style: none; + border-radius: 0.25rem; +} +.page-link { + position: relative; + display: block; + padding: 0.5rem 0.75rem; + margin-left: -1px; + line-height: 1.25; + color: #007bff; + background-color: #fff; + border: 1px solid #dee2e6; +} +.page-link:hover { + z-index: 2; + color: #0056b3; + text-decoration: none; + background-color: #e9ecef; + border-color: #dee2e6; +} +.page-link:focus { + z-index: 3; + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25); +} +.page-item:first-child .page-link { + margin-left: 0; + border-top-left-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; +} +.page-item:last-child .page-link { + border-top-right-radius: 0.25rem; + border-bottom-right-radius: 0.25rem; +} +.page-item.active .page-link { + z-index: 3; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.page-item.disabled .page-link { + color: #6c757d; + pointer-events: none; + cursor: auto; + background-color: #fff; + border-color: #dee2e6; +} +.pagination-lg .page-link { + padding: 0.75rem 1.5rem; + font-size: 1.25rem; + line-height: 1.5; +} +.pagination-lg .page-item:first-child .page-link { + border-top-left-radius: 0.3rem; + border-bottom-left-radius: 0.3rem; +} +.pagination-lg .page-item:last-child .page-link { + border-top-right-radius: 0.3rem; + border-bottom-right-radius: 0.3rem; +} +.pagination-sm .page-link { + padding: 0.25rem 0.5rem; + font-size: 0.875rem; + line-height: 1.5; +} +.pagination-sm .page-item:first-child .page-link { + border-top-left-radius: 0.2rem; + border-bottom-left-radius: 0.2rem; +} +.pagination-sm .page-item:last-child .page-link { + border-top-right-radius: 0.2rem; + border-bottom-right-radius: 0.2rem; +} +.badge { + display: inline-block; + padding: 0.25em 0.4em; + font-size: 75%; + font-weight: 700; + line-height: 1; + text-align: center; + white-space: nowrap; + vertical-align: baseline; + border-radius: 0.25rem; + transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .badge { + transition: none; + } +} +a.badge:focus, +a.badge:hover { + text-decoration: none; +} +.badge:empty { + display: none; +} +.btn .badge { + position: relative; + top: -1px; +} +.badge-pill { + padding-right: 0.6em; + padding-left: 0.6em; + border-radius: 10rem; +} +.badge-primary { + color: #fff; + background-color: #007bff; +} +a.badge-primary:focus, +a.badge-primary:hover { + color: #fff; + background-color: #0062cc; +} +a.badge-primary.focus, +a.badge-primary:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5); +} +.badge-secondary { + color: #fff; + background-color: #6c757d; +} +a.badge-secondary:focus, +a.badge-secondary:hover { + color: #fff; + background-color: #545b62; +} +a.badge-secondary.focus, +a.badge-secondary:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); +} +.badge-success { + color: #fff; + background-color: #28a745; +} +a.badge-success:focus, +a.badge-success:hover { + color: #fff; + background-color: #1e7e34; +} +a.badge-success.focus, +a.badge-success:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5); +} +.badge-info { + color: #fff; + background-color: #17a2b8; +} +a.badge-info:focus, +a.badge-info:hover { + color: #fff; + background-color: #117a8b; +} +a.badge-info.focus, +a.badge-info:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); +} +.badge-warning { + color: #212529; + background-color: #ffc107; +} +a.badge-warning:focus, +a.badge-warning:hover { + color: #212529; + background-color: #d39e00; +} +a.badge-warning.focus, +a.badge-warning:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); +} +.badge-danger { + color: #fff; + background-color: #dc3545; +} +a.badge-danger:focus, +a.badge-danger:hover { + color: #fff; + background-color: #bd2130; +} +a.badge-danger.focus, +a.badge-danger:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5); +} +.badge-light { + color: #212529; + background-color: #f8f9fa; +} +a.badge-light:focus, +a.badge-light:hover { + color: #212529; + background-color: #dae0e5; +} +a.badge-light.focus, +a.badge-light:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); +} +.badge-dark { + color: #fff; + background-color: #343a40; +} +a.badge-dark:focus, +a.badge-dark:hover { + color: #fff; + background-color: #1d2124; +} +a.badge-dark.focus, +a.badge-dark:focus { + outline: 0; + box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); +} +.jumbotron { + padding: 2rem 1rem; + margin-bottom: 2rem; + background-color: #e9ecef; + border-radius: 0.3rem; +} +@media (min-width: 576px) { + .jumbotron { + padding: 4rem 2rem; + } +} +.jumbotron-fluid { + padding-right: 0; + padding-left: 0; + border-radius: 0; +} +.alert { + position: relative; + padding: 0.75rem 1.25rem; + margin-bottom: 1rem; + border: 1px solid transparent; + border-radius: 0.25rem; +} +.alert-heading { + color: inherit; +} +.alert-link { + font-weight: 700; +} +.alert-dismissible { + padding-right: 4rem; +} +.alert-dismissible .close { + position: absolute; + top: 0; + right: 0; + padding: 0.75rem 1.25rem; + color: inherit; +} +.alert-primary { + color: #004085; + background-color: #cce5ff; + border-color: #b8daff; +} +.alert-primary hr { + border-top-color: #9fcdff; +} +.alert-primary .alert-link { + color: #002752; +} +.alert-secondary { + color: #383d41; + background-color: #e2e3e5; + border-color: #d6d8db; +} +.alert-secondary hr { + border-top-color: #c8cbcf; +} +.alert-secondary .alert-link { + color: #202326; +} +.alert-success { + color: #155724; + background-color: #d4edda; + border-color: #c3e6cb; +} +.alert-success hr { + border-top-color: #b1dfbb; +} +.alert-success .alert-link { + color: #0b2e13; +} +.alert-info { + color: #0c5460; + background-color: #d1ecf1; + border-color: #bee5eb; +} +.alert-info hr { + border-top-color: #abdde5; +} +.alert-info .alert-link { + color: #062c33; +} +.alert-warning { + color: #856404; + background-color: #fff3cd; + border-color: #ffeeba; +} +.alert-warning hr { + border-top-color: #ffe8a1; +} +.alert-warning .alert-link { + color: #533f03; +} +.alert-danger { + color: #721c24; + background-color: #f8d7da; + border-color: #f5c6cb; +} +.alert-danger hr { + border-top-color: #f1b0b7; +} +.alert-danger .alert-link { + color: #491217; +} +.alert-light { + color: #818182; + background-color: #fefefe; + border-color: #fdfdfe; +} +.alert-light hr { + border-top-color: #ececf6; +} +.alert-light .alert-link { + color: #686868; +} +.alert-dark { + color: #1b1e21; + background-color: #d6d8d9; + border-color: #c6c8ca; +} +.alert-dark hr { + border-top-color: #b9bbbe; +} +.alert-dark .alert-link { + color: #040505; +} +@-webkit-keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} +@keyframes progress-bar-stripes { + from { + background-position: 1rem 0; + } + to { + background-position: 0 0; + } +} +.progress { + display: -ms-flexbox; + display: flex; + height: 1rem; + overflow: hidden; + line-height: 0; + font-size: 0.75rem; + background-color: #e9ecef; + border-radius: 0.25rem; +} +.progress-bar { + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + -ms-flex-pack: center; + justify-content: center; + overflow: hidden; + color: #fff; + text-align: center; + white-space: nowrap; + background-color: #007bff; + transition: width 0.6s ease; +} +@media (prefers-reduced-motion: reduce) { + .progress-bar { + transition: none; + } +} +.progress-bar-striped { + background-image: linear-gradient( + 45deg, + rgba(255, 255, 255, 0.15) 25%, + transparent 25%, + transparent 50%, + rgba(255, 255, 255, 0.15) 50%, + rgba(255, 255, 255, 0.15) 75%, + transparent 75%, + transparent + ); + background-size: 1rem 1rem; +} +.progress-bar-animated { + -webkit-animation: progress-bar-stripes 1s linear infinite; + animation: progress-bar-stripes 1s linear infinite; +} +@media (prefers-reduced-motion: reduce) { + .progress-bar-animated { + -webkit-animation: none; + animation: none; + } +} +.media { + display: -ms-flexbox; + display: flex; + -ms-flex-align: start; + align-items: flex-start; +} +.media-body { + -ms-flex: 1; + flex: 1; +} +.list-group { + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + padding-left: 0; + margin-bottom: 0; + border-radius: 0.25rem; +} +.list-group-item-action { + width: 100%; + color: #495057; + text-align: inherit; +} +.list-group-item-action:focus, +.list-group-item-action:hover { + z-index: 1; + color: #495057; + text-decoration: none; + background-color: #f8f9fa; +} +.list-group-item-action:active { + color: #212529; + background-color: #e9ecef; +} +.list-group-item { + position: relative; + display: block; + padding: 0.75rem 1.25rem; + background-color: #fff; + border: 1px solid rgba(0, 0, 0, 0.125); +} +.list-group-item:first-child { + border-top-left-radius: inherit; + border-top-right-radius: inherit; +} +.list-group-item:last-child { + border-bottom-right-radius: inherit; + border-bottom-left-radius: inherit; +} +.list-group-item.disabled, +.list-group-item:disabled { + color: #6c757d; + pointer-events: none; + background-color: #fff; +} +.list-group-item.active { + z-index: 2; + color: #fff; + background-color: #007bff; + border-color: #007bff; +} +.list-group-item + .list-group-item { + border-top-width: 0; +} +.list-group-item + .list-group-item.active { + margin-top: -1px; + border-top-width: 1px; +} +.list-group-horizontal { + -ms-flex-direction: row; + flex-direction: row; +} +.list-group-horizontal > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; +} +.list-group-horizontal > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; +} +.list-group-horizontal > .list-group-item.active { + margin-top: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; +} +.list-group-horizontal > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; +} +@media (min-width: 576px) { + .list-group-horizontal-sm { + -ms-flex-direction: row; + flex-direction: row; + } + .list-group-horizontal-sm > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-sm > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-sm > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-sm > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 768px) { + .list-group-horizontal-md { + -ms-flex-direction: row; + flex-direction: row; + } + .list-group-horizontal-md > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-md > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-md > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-md > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 992px) { + .list-group-horizontal-lg { + -ms-flex-direction: row; + flex-direction: row; + } + .list-group-horizontal-lg > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-lg > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-lg > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-lg > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +@media (min-width: 1200px) { + .list-group-horizontal-xl { + -ms-flex-direction: row; + flex-direction: row; + } + .list-group-horizontal-xl > .list-group-item:first-child { + border-bottom-left-radius: 0.25rem; + border-top-right-radius: 0; + } + .list-group-horizontal-xl > .list-group-item:last-child { + border-top-right-radius: 0.25rem; + border-bottom-left-radius: 0; + } + .list-group-horizontal-xl > .list-group-item.active { + margin-top: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item { + border-top-width: 1px; + border-left-width: 0; + } + .list-group-horizontal-xl > .list-group-item + .list-group-item.active { + margin-left: -1px; + border-left-width: 1px; + } +} +.list-group-flush { + border-radius: 0; +} +.list-group-flush > .list-group-item { + border-width: 0 0 1px; +} +.list-group-flush > .list-group-item:last-child { + border-bottom-width: 0; +} +.list-group-item-primary { + color: #004085; + background-color: #b8daff; +} +.list-group-item-primary.list-group-item-action:focus, +.list-group-item-primary.list-group-item-action:hover { + color: #004085; + background-color: #9fcdff; +} +.list-group-item-primary.list-group-item-action.active { + color: #fff; + background-color: #004085; + border-color: #004085; +} +.list-group-item-secondary { + color: #383d41; + background-color: #d6d8db; +} +.list-group-item-secondary.list-group-item-action:focus, +.list-group-item-secondary.list-group-item-action:hover { + color: #383d41; + background-color: #c8cbcf; +} +.list-group-item-secondary.list-group-item-action.active { + color: #fff; + background-color: #383d41; + border-color: #383d41; +} +.list-group-item-success { + color: #155724; + background-color: #c3e6cb; +} +.list-group-item-success.list-group-item-action:focus, +.list-group-item-success.list-group-item-action:hover { + color: #155724; + background-color: #b1dfbb; +} +.list-group-item-success.list-group-item-action.active { + color: #fff; + background-color: #155724; + border-color: #155724; +} +.list-group-item-info { + color: #0c5460; + background-color: #bee5eb; +} +.list-group-item-info.list-group-item-action:focus, +.list-group-item-info.list-group-item-action:hover { + color: #0c5460; + background-color: #abdde5; +} +.list-group-item-info.list-group-item-action.active { + color: #fff; + background-color: #0c5460; + border-color: #0c5460; +} +.list-group-item-warning { + color: #856404; + background-color: #ffeeba; +} +.list-group-item-warning.list-group-item-action:focus, +.list-group-item-warning.list-group-item-action:hover { + color: #856404; + background-color: #ffe8a1; +} +.list-group-item-warning.list-group-item-action.active { + color: #fff; + background-color: #856404; + border-color: #856404; +} +.list-group-item-danger { + color: #721c24; + background-color: #f5c6cb; +} +.list-group-item-danger.list-group-item-action:focus, +.list-group-item-danger.list-group-item-action:hover { + color: #721c24; + background-color: #f1b0b7; +} +.list-group-item-danger.list-group-item-action.active { + color: #fff; + background-color: #721c24; + border-color: #721c24; +} +.list-group-item-light { + color: #818182; + background-color: #fdfdfe; +} +.list-group-item-light.list-group-item-action:focus, +.list-group-item-light.list-group-item-action:hover { + color: #818182; + background-color: #ececf6; +} +.list-group-item-light.list-group-item-action.active { + color: #fff; + background-color: #818182; + border-color: #818182; +} +.list-group-item-dark { + color: #1b1e21; + background-color: #c6c8ca; +} +.list-group-item-dark.list-group-item-action:focus, +.list-group-item-dark.list-group-item-action:hover { + color: #1b1e21; + background-color: #b9bbbe; +} +.list-group-item-dark.list-group-item-action.active { + color: #fff; + background-color: #1b1e21; + border-color: #1b1e21; +} +.close { + float: right; + font-size: 1.5rem; + font-weight: 700; + line-height: 1; + color: #000; + text-shadow: 0 1px 0 #fff; + opacity: 0.5; +} +.close:hover { + color: #000; + text-decoration: none; +} +.close:not(:disabled):not(.disabled):focus, +.close:not(:disabled):not(.disabled):hover { + opacity: 0.75; +} +button.close { + padding: 0; + background-color: transparent; + border: 0; +} +a.close.disabled { + pointer-events: none; +} +.toast { + -ms-flex-preferred-size: 350px; + flex-basis: 350px; + max-width: 350px; + font-size: 0.875rem; + background-color: rgba(255, 255, 255, 0.85); + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.1); + box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.1); + opacity: 0; + border-radius: 0.25rem; +} +.toast:not(:last-child) { + margin-bottom: 0.75rem; +} +.toast.showing { + opacity: 1; +} +.toast.show { + display: block; + opacity: 1; +} +.toast.hide { + display: none; +} +.toast-header { + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + padding: 0.25rem 0.75rem; + color: #6c757d; + background-color: rgba(255, 255, 255, 0.85); + background-clip: padding-box; + border-bottom: 1px solid rgba(0, 0, 0, 0.05); + border-top-left-radius: calc(0.25rem - 1px); + border-top-right-radius: calc(0.25rem - 1px); +} +.toast-body { + padding: 0.75rem; +} +.modal-open { + overflow: hidden; +} +.modal-open .modal { + overflow-x: hidden; + overflow-y: auto; +} +.modal { + position: fixed; + top: 0; + left: 0; + z-index: 1050; + display: none; + width: 100%; + height: 100%; + overflow: hidden; + outline: 0; +} +.modal-dialog { + position: relative; + width: auto; + margin: 0.5rem; + pointer-events: none; +} +.modal.fade .modal-dialog { + transition: -webkit-transform 0.3s ease-out; + transition: transform 0.3s ease-out; + transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out; + -webkit-transform: translate(0, -50px); + transform: translate(0, -50px); +} +@media (prefers-reduced-motion: reduce) { + .modal.fade .modal-dialog { + transition: none; + } +} +.modal.show .modal-dialog { + -webkit-transform: none; + transform: none; +} +.modal.modal-static .modal-dialog { + -webkit-transform: scale(1.02); + transform: scale(1.02); +} +.modal-dialog-scrollable { + display: -ms-flexbox; + display: flex; + max-height: calc(100% - 1rem); +} +.modal-dialog-scrollable .modal-content { + max-height: calc(100vh - 1rem); + overflow: hidden; +} +.modal-dialog-scrollable .modal-footer, +.modal-dialog-scrollable .modal-header { + -ms-flex-negative: 0; + flex-shrink: 0; +} +.modal-dialog-scrollable .modal-body { + overflow-y: auto; +} +.modal-dialog-centered { + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + min-height: calc(100% - 1rem); +} +.modal-dialog-centered::before { + display: block; + height: calc(100vh - 1rem); + height: -webkit-min-content; + height: -moz-min-content; + height: min-content; + content: ''; +} +.modal-dialog-centered.modal-dialog-scrollable { + -ms-flex-direction: column; + flex-direction: column; + -ms-flex-pack: center; + justify-content: center; + height: 100%; +} +.modal-dialog-centered.modal-dialog-scrollable .modal-content { + max-height: none; +} +.modal-dialog-centered.modal-dialog-scrollable::before { + content: none; +} +.modal-content { + position: relative; + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + width: 100%; + pointer-events: auto; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; + outline: 0; +} +.modal-backdrop { + position: fixed; + top: 0; + left: 0; + z-index: 1040; + width: 100vw; + height: 100vh; + background-color: #000; +} +.modal-backdrop.fade { + opacity: 0; +} +.modal-backdrop.show { + opacity: 0.5; +} +.modal-header { + display: -ms-flexbox; + display: flex; + -ms-flex-align: start; + align-items: flex-start; + -ms-flex-pack: justify; + justify-content: space-between; + padding: 1rem 1rem; + border-bottom: 1px solid #dee2e6; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.modal-header .close { + padding: 1rem 1rem; + margin: -1rem -1rem -1rem auto; +} +.modal-title { + margin-bottom: 0; + line-height: 1.5; +} +.modal-body { + position: relative; + -ms-flex: 1 1 auto; + flex: 1 1 auto; + padding: 1rem; +} +.modal-footer { + display: -ms-flexbox; + display: flex; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: end; + justify-content: flex-end; + padding: 0.75rem; + border-top: 1px solid #dee2e6; + border-bottom-right-radius: calc(0.3rem - 1px); + border-bottom-left-radius: calc(0.3rem - 1px); +} +.modal-footer > * { + margin: 0.25rem; +} +.modal-scrollbar-measure { + position: absolute; + top: -9999px; + width: 50px; + height: 50px; + overflow: scroll; +} +@media (min-width: 576px) { + .modal-dialog { + max-width: 500px; + margin: 1.75rem auto; + } + .modal-dialog-scrollable { + max-height: calc(100% - 3.5rem); + } + .modal-dialog-scrollable .modal-content { + max-height: calc(100vh - 3.5rem); + } + .modal-dialog-centered { + min-height: calc(100% - 3.5rem); + } + .modal-dialog-centered::before { + height: calc(100vh - 3.5rem); + height: -webkit-min-content; + height: -moz-min-content; + height: min-content; + } + .modal-sm { + max-width: 300px; + } +} +@media (min-width: 992px) { + .modal-lg, + .modal-xl { + max-width: 800px; + } +} +@media (min-width: 1200px) { + .modal-xl { + max-width: 1140px; + } +} +.tooltip { + position: absolute; + z-index: 1070; + display: block; + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', + 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + opacity: 0; +} +.tooltip.show { + opacity: 0.9; +} +.tooltip .arrow { + position: absolute; + display: block; + width: 0.8rem; + height: 0.4rem; +} +.tooltip .arrow::before { + position: absolute; + content: ''; + border-color: transparent; + border-style: solid; +} +.bs-tooltip-auto[x-placement^='top'], +.bs-tooltip-top { + padding: 0.4rem 0; +} +.bs-tooltip-auto[x-placement^='top'] .arrow, +.bs-tooltip-top .arrow { + bottom: 0; +} +.bs-tooltip-auto[x-placement^='top'] .arrow::before, +.bs-tooltip-top .arrow::before { + top: 0; + border-width: 0.4rem 0.4rem 0; + border-top-color: #000; +} +.bs-tooltip-auto[x-placement^='right'], +.bs-tooltip-right { + padding: 0 0.4rem; +} +.bs-tooltip-auto[x-placement^='right'] .arrow, +.bs-tooltip-right .arrow { + left: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-auto[x-placement^='right'] .arrow::before, +.bs-tooltip-right .arrow::before { + right: 0; + border-width: 0.4rem 0.4rem 0.4rem 0; + border-right-color: #000; +} +.bs-tooltip-auto[x-placement^='bottom'], +.bs-tooltip-bottom { + padding: 0.4rem 0; +} +.bs-tooltip-auto[x-placement^='bottom'] .arrow, +.bs-tooltip-bottom .arrow { + top: 0; +} +.bs-tooltip-auto[x-placement^='bottom'] .arrow::before, +.bs-tooltip-bottom .arrow::before { + bottom: 0; + border-width: 0 0.4rem 0.4rem; + border-bottom-color: #000; +} +.bs-tooltip-auto[x-placement^='left'], +.bs-tooltip-left { + padding: 0 0.4rem; +} +.bs-tooltip-auto[x-placement^='left'] .arrow, +.bs-tooltip-left .arrow { + right: 0; + width: 0.4rem; + height: 0.8rem; +} +.bs-tooltip-auto[x-placement^='left'] .arrow::before, +.bs-tooltip-left .arrow::before { + left: 0; + border-width: 0.4rem 0 0.4rem 0.4rem; + border-left-color: #000; +} +.tooltip-inner { + max-width: 200px; + padding: 0.25rem 0.5rem; + color: #fff; + text-align: center; + background-color: #000; + border-radius: 0.25rem; +} +.popover { + position: absolute; + top: 0; + left: 0; + z-index: 1060; + display: block; + max-width: 276px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', sans-serif, 'Apple Color Emoji', + 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'; + font-style: normal; + font-weight: 400; + line-height: 1.5; + text-align: left; + text-align: start; + text-decoration: none; + text-shadow: none; + text-transform: none; + letter-spacing: normal; + word-break: normal; + word-spacing: normal; + white-space: normal; + line-break: auto; + font-size: 0.875rem; + word-wrap: break-word; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, 0.2); + border-radius: 0.3rem; +} +.popover .arrow { + position: absolute; + display: block; + width: 1rem; + height: 0.5rem; + margin: 0 0.3rem; +} +.popover .arrow::after, +.popover .arrow::before { + position: absolute; + display: block; + content: ''; + border-color: transparent; + border-style: solid; +} +.bs-popover-auto[x-placement^='top'], +.bs-popover-top { + margin-bottom: 0.5rem; +} +.bs-popover-auto[x-placement^='top'] > .arrow, +.bs-popover-top > .arrow { + bottom: calc(-0.5rem - 1px); +} +.bs-popover-auto[x-placement^='top'] > .arrow::before, +.bs-popover-top > .arrow::before { + bottom: 0; + border-width: 0.5rem 0.5rem 0; + border-top-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-auto[x-placement^='top'] > .arrow::after, +.bs-popover-top > .arrow::after { + bottom: 1px; + border-width: 0.5rem 0.5rem 0; + border-top-color: #fff; +} +.bs-popover-auto[x-placement^='right'], +.bs-popover-right { + margin-left: 0.5rem; +} +.bs-popover-auto[x-placement^='right'] > .arrow, +.bs-popover-right > .arrow { + left: calc(-0.5rem - 1px); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} +.bs-popover-auto[x-placement^='right'] > .arrow::before, +.bs-popover-right > .arrow::before { + left: 0; + border-width: 0.5rem 0.5rem 0.5rem 0; + border-right-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-auto[x-placement^='right'] > .arrow::after, +.bs-popover-right > .arrow::after { + left: 1px; + border-width: 0.5rem 0.5rem 0.5rem 0; + border-right-color: #fff; +} +.bs-popover-auto[x-placement^='bottom'], +.bs-popover-bottom { + margin-top: 0.5rem; +} +.bs-popover-auto[x-placement^='bottom'] > .arrow, +.bs-popover-bottom > .arrow { + top: calc(-0.5rem - 1px); +} +.bs-popover-auto[x-placement^='bottom'] > .arrow::before, +.bs-popover-bottom > .arrow::before { + top: 0; + border-width: 0 0.5rem 0.5rem 0.5rem; + border-bottom-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-auto[x-placement^='bottom'] > .arrow::after, +.bs-popover-bottom > .arrow::after { + top: 1px; + border-width: 0 0.5rem 0.5rem 0.5rem; + border-bottom-color: #fff; +} +.bs-popover-auto[x-placement^='bottom'] .popover-header::before, +.bs-popover-bottom .popover-header::before { + position: absolute; + top: 0; + left: 50%; + display: block; + width: 1rem; + margin-left: -0.5rem; + content: ''; + border-bottom: 1px solid #f7f7f7; +} +.bs-popover-auto[x-placement^='left'], +.bs-popover-left { + margin-right: 0.5rem; +} +.bs-popover-auto[x-placement^='left'] > .arrow, +.bs-popover-left > .arrow { + right: calc(-0.5rem - 1px); + width: 0.5rem; + height: 1rem; + margin: 0.3rem 0; +} +.bs-popover-auto[x-placement^='left'] > .arrow::before, +.bs-popover-left > .arrow::before { + right: 0; + border-width: 0.5rem 0 0.5rem 0.5rem; + border-left-color: rgba(0, 0, 0, 0.25); +} +.bs-popover-auto[x-placement^='left'] > .arrow::after, +.bs-popover-left > .arrow::after { + right: 1px; + border-width: 0.5rem 0 0.5rem 0.5rem; + border-left-color: #fff; +} +.popover-header { + padding: 0.5rem 0.75rem; + margin-bottom: 0; + font-size: 1rem; + background-color: #f7f7f7; + border-bottom: 1px solid #ebebeb; + border-top-left-radius: calc(0.3rem - 1px); + border-top-right-radius: calc(0.3rem - 1px); +} +.popover-header:empty { + display: none; +} +.popover-body { + padding: 0.5rem 0.75rem; + color: #212529; +} +.carousel { + position: relative; +} +.carousel.pointer-event { + -ms-touch-action: pan-y; + touch-action: pan-y; +} +.carousel-inner { + position: relative; + width: 100%; + overflow: hidden; +} +.carousel-inner::after { + display: block; + clear: both; + content: ''; +} +.carousel-item { + position: relative; + display: none; + float: left; + width: 100%; + margin-right: -100%; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + transition: -webkit-transform 0.6s ease-in-out; + transition: transform 0.6s ease-in-out; + transition: transform 0.6s ease-in-out, -webkit-transform 0.6s ease-in-out; +} +@media (prefers-reduced-motion: reduce) { + .carousel-item { + transition: none; + } +} +.carousel-item-next, +.carousel-item-prev, +.carousel-item.active { + display: block; +} +.active.carousel-item-right, +.carousel-item-next:not(.carousel-item-left) { + -webkit-transform: translateX(100%); + transform: translateX(100%); +} +.active.carousel-item-left, +.carousel-item-prev:not(.carousel-item-right) { + -webkit-transform: translateX(-100%); + transform: translateX(-100%); +} +.carousel-fade .carousel-item { + opacity: 0; + transition-property: opacity; + -webkit-transform: none; + transform: none; +} +.carousel-fade .carousel-item-next.carousel-item-left, +.carousel-fade .carousel-item-prev.carousel-item-right, +.carousel-fade .carousel-item.active { + z-index: 1; + opacity: 1; +} +.carousel-fade .active.carousel-item-left, +.carousel-fade .active.carousel-item-right { + z-index: 0; + opacity: 0; + transition: opacity 0s 0.6s; +} +@media (prefers-reduced-motion: reduce) { + .carousel-fade .active.carousel-item-left, + .carousel-fade .active.carousel-item-right { + transition: none; + } +} +.carousel-control-next, +.carousel-control-prev { + position: absolute; + top: 0; + bottom: 0; + z-index: 1; + display: -ms-flexbox; + display: flex; + -ms-flex-align: center; + align-items: center; + -ms-flex-pack: center; + justify-content: center; + width: 15%; + color: #fff; + text-align: center; + opacity: 0.5; + transition: opacity 0.15s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-control-next, + .carousel-control-prev { + transition: none; + } +} +.carousel-control-next:focus, +.carousel-control-next:hover, +.carousel-control-prev:focus, +.carousel-control-prev:hover { + color: #fff; + text-decoration: none; + outline: 0; + opacity: 0.9; +} +.carousel-control-prev { + left: 0; +} +.carousel-control-next { + right: 0; +} +.carousel-control-next-icon, +.carousel-control-prev-icon { + display: inline-block; + width: 20px; + height: 20px; + background: no-repeat 50%/100% 100%; +} +.carousel-control-prev-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5L4.25 4l2.5-2.5L5.25 0z'/%3e%3c/svg%3e"); +} +.carousel-control-next-icon { + background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5L3.75 4l-2.5 2.5L2.75 8l4-4-4-4z'/%3e%3c/svg%3e"); +} +.carousel-indicators { + position: absolute; + right: 0; + bottom: 0; + left: 0; + z-index: 15; + display: -ms-flexbox; + display: flex; + -ms-flex-pack: center; + justify-content: center; + padding-left: 0; + margin-right: 15%; + margin-left: 15%; + list-style: none; +} +.carousel-indicators li { + box-sizing: content-box; + -ms-flex: 0 1 auto; + flex: 0 1 auto; + width: 30px; + height: 3px; + margin-right: 3px; + margin-left: 3px; + text-indent: -999px; + cursor: pointer; + background-color: #fff; + background-clip: padding-box; + border-top: 10px solid transparent; + border-bottom: 10px solid transparent; + opacity: 0.5; + transition: opacity 0.6s ease; +} +@media (prefers-reduced-motion: reduce) { + .carousel-indicators li { + transition: none; + } +} +.carousel-indicators .active { + opacity: 1; +} +.carousel-caption { + position: absolute; + right: 15%; + bottom: 20px; + left: 15%; + z-index: 10; + padding-top: 20px; + padding-bottom: 20px; + color: #fff; + text-align: center; +} +@-webkit-keyframes spinner-border { + to { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes spinner-border { + to { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +.spinner-border { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: text-bottom; + border: 0.25em solid currentColor; + border-right-color: transparent; + border-radius: 50%; + -webkit-animation: spinner-border 0.75s linear infinite; + animation: spinner-border 0.75s linear infinite; +} +.spinner-border-sm { + width: 1rem; + height: 1rem; + border-width: 0.2em; +} +@-webkit-keyframes spinner-grow { + 0% { + -webkit-transform: scale(0); + transform: scale(0); + } + 50% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} +@keyframes spinner-grow { + 0% { + -webkit-transform: scale(0); + transform: scale(0); + } + 50% { + opacity: 1; + -webkit-transform: none; + transform: none; + } +} +.spinner-grow { + display: inline-block; + width: 2rem; + height: 2rem; + vertical-align: text-bottom; + background-color: currentColor; + border-radius: 50%; + opacity: 0; + -webkit-animation: spinner-grow 0.75s linear infinite; + animation: spinner-grow 0.75s linear infinite; +} +.spinner-grow-sm { + width: 1rem; + height: 1rem; +} +.align-baseline { + vertical-align: baseline !important; +} +.align-top { + vertical-align: top !important; +} +.align-middle { + vertical-align: middle !important; +} +.align-bottom { + vertical-align: bottom !important; +} +.align-text-bottom { + vertical-align: text-bottom !important; +} +.align-text-top { + vertical-align: text-top !important; +} +.bg-primary { + background-color: #007bff !important; +} +a.bg-primary:focus, +a.bg-primary:hover, +button.bg-primary:focus, +button.bg-primary:hover { + background-color: #0062cc !important; +} +.bg-secondary { + background-color: #6c757d !important; +} +a.bg-secondary:focus, +a.bg-secondary:hover, +button.bg-secondary:focus, +button.bg-secondary:hover { + background-color: #545b62 !important; +} +.bg-success { + background-color: #28a745 !important; +} +a.bg-success:focus, +a.bg-success:hover, +button.bg-success:focus, +button.bg-success:hover { + background-color: #1e7e34 !important; +} +.bg-info { + background-color: #17a2b8 !important; +} +a.bg-info:focus, +a.bg-info:hover, +button.bg-info:focus, +button.bg-info:hover { + background-color: #117a8b !important; +} +.bg-warning { + background-color: #ffc107 !important; +} +a.bg-warning:focus, +a.bg-warning:hover, +button.bg-warning:focus, +button.bg-warning:hover { + background-color: #d39e00 !important; +} +.bg-danger { + background-color: #dc3545 !important; +} +a.bg-danger:focus, +a.bg-danger:hover, +button.bg-danger:focus, +button.bg-danger:hover { + background-color: #bd2130 !important; +} +.bg-light { + background-color: #f8f9fa !important; +} +a.bg-light:focus, +a.bg-light:hover, +button.bg-light:focus, +button.bg-light:hover { + background-color: #dae0e5 !important; +} +.bg-dark { + background-color: #343a40 !important; +} +a.bg-dark:focus, +a.bg-dark:hover, +button.bg-dark:focus, +button.bg-dark:hover { + background-color: #1d2124 !important; +} +.bg-white { + background-color: #fff !important; +} +.bg-transparent { + background-color: transparent !important; +} +.border { + border: 1px solid #dee2e6 !important; +} +.border-top { + border-top: 1px solid #dee2e6 !important; +} +.border-right { + border-right: 1px solid #dee2e6 !important; +} +.border-bottom { + border-bottom: 1px solid #dee2e6 !important; +} +.border-left { + border-left: 1px solid #dee2e6 !important; +} +.border-0 { + border: 0 !important; +} +.border-top-0 { + border-top: 0 !important; +} +.border-right-0 { + border-right: 0 !important; +} +.border-bottom-0 { + border-bottom: 0 !important; +} +.border-left-0 { + border-left: 0 !important; +} +.border-primary { + border-color: #007bff !important; +} +.border-secondary { + border-color: #6c757d !important; +} +.border-success { + border-color: #28a745 !important; +} +.border-info { + border-color: #17a2b8 !important; +} +.border-warning { + border-color: #ffc107 !important; +} +.border-danger { + border-color: #dc3545 !important; +} +.border-light { + border-color: #f8f9fa !important; +} +.border-dark { + border-color: #343a40 !important; +} +.border-white { + border-color: #fff !important; +} +.rounded-sm { + border-radius: 0.2rem !important; +} +.rounded { + border-radius: 0.25rem !important; +} +.rounded-top { + border-top-left-radius: 0.25rem !important; + border-top-right-radius: 0.25rem !important; +} +.rounded-right { + border-top-right-radius: 0.25rem !important; + border-bottom-right-radius: 0.25rem !important; +} +.rounded-bottom { + border-bottom-right-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} +.rounded-left { + border-top-left-radius: 0.25rem !important; + border-bottom-left-radius: 0.25rem !important; +} +.rounded-lg { + border-radius: 0.3rem !important; +} +.rounded-circle { + border-radius: 50% !important; +} +.rounded-pill { + border-radius: 50rem !important; +} +.rounded-0 { + border-radius: 0 !important; +} +.clearfix::after { + display: block; + clear: both; + content: ''; +} +.d-none { + display: none !important; +} +.d-inline { + display: inline !important; +} +.d-inline-block { + display: inline-block !important; +} +.d-block { + display: block !important; +} +.d-table { + display: table !important; +} +.d-table-row { + display: table-row !important; +} +.d-table-cell { + display: table-cell !important; +} +.d-flex { + display: -ms-flexbox !important; + display: flex !important; +} +.d-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; +} +@media (min-width: 576px) { + .d-sm-none { + display: none !important; + } + .d-sm-inline { + display: inline !important; + } + .d-sm-inline-block { + display: inline-block !important; + } + .d-sm-block { + display: block !important; + } + .d-sm-table { + display: table !important; + } + .d-sm-table-row { + display: table-row !important; + } + .d-sm-table-cell { + display: table-cell !important; + } + .d-sm-flex { + display: -ms-flexbox !important; + display: flex !important; + } + .d-sm-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 768px) { + .d-md-none { + display: none !important; + } + .d-md-inline { + display: inline !important; + } + .d-md-inline-block { + display: inline-block !important; + } + .d-md-block { + display: block !important; + } + .d-md-table { + display: table !important; + } + .d-md-table-row { + display: table-row !important; + } + .d-md-table-cell { + display: table-cell !important; + } + .d-md-flex { + display: -ms-flexbox !important; + display: flex !important; + } + .d-md-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 992px) { + .d-lg-none { + display: none !important; + } + .d-lg-inline { + display: inline !important; + } + .d-lg-inline-block { + display: inline-block !important; + } + .d-lg-block { + display: block !important; + } + .d-lg-table { + display: table !important; + } + .d-lg-table-row { + display: table-row !important; + } + .d-lg-table-cell { + display: table-cell !important; + } + .d-lg-flex { + display: -ms-flexbox !important; + display: flex !important; + } + .d-lg-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media (min-width: 1200px) { + .d-xl-none { + display: none !important; + } + .d-xl-inline { + display: inline !important; + } + .d-xl-inline-block { + display: inline-block !important; + } + .d-xl-block { + display: block !important; + } + .d-xl-table { + display: table !important; + } + .d-xl-table-row { + display: table-row !important; + } + .d-xl-table-cell { + display: table-cell !important; + } + .d-xl-flex { + display: -ms-flexbox !important; + display: flex !important; + } + .d-xl-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +@media print { + .d-print-none { + display: none !important; + } + .d-print-inline { + display: inline !important; + } + .d-print-inline-block { + display: inline-block !important; + } + .d-print-block { + display: block !important; + } + .d-print-table { + display: table !important; + } + .d-print-table-row { + display: table-row !important; + } + .d-print-table-cell { + display: table-cell !important; + } + .d-print-flex { + display: -ms-flexbox !important; + display: flex !important; + } + .d-print-inline-flex { + display: -ms-inline-flexbox !important; + display: inline-flex !important; + } +} +.embed-responsive { + position: relative; + display: block; + width: 100%; + padding: 0; + overflow: hidden; +} +.embed-responsive::before { + display: block; + content: ''; +} +.embed-responsive .embed-responsive-item, +.embed-responsive embed, +.embed-responsive iframe, +.embed-responsive object, +.embed-responsive video { + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: 100%; + height: 100%; + border: 0; +} +.embed-responsive-21by9::before { + padding-top: 42.857143%; +} +.embed-responsive-16by9::before { + padding-top: 56.25%; +} +.embed-responsive-4by3::before { + padding-top: 75%; +} +.embed-responsive-1by1::before { + padding-top: 100%; +} +.flex-row { + -ms-flex-direction: row !important; + flex-direction: row !important; +} +.flex-column { + -ms-flex-direction: column !important; + flex-direction: column !important; +} +.flex-row-reverse { + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; +} +.flex-column-reverse { + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; +} +.flex-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; +} +.flex-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; +} +.flex-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; +} +.flex-fill { + -ms-flex: 1 1 auto !important; + flex: 1 1 auto !important; +} +.flex-grow-0 { + -ms-flex-positive: 0 !important; + flex-grow: 0 !important; +} +.flex-grow-1 { + -ms-flex-positive: 1 !important; + flex-grow: 1 !important; +} +.flex-shrink-0 { + -ms-flex-negative: 0 !important; + flex-shrink: 0 !important; +} +.flex-shrink-1 { + -ms-flex-negative: 1 !important; + flex-shrink: 1 !important; +} +.justify-content-start { + -ms-flex-pack: start !important; + justify-content: flex-start !important; +} +.justify-content-end { + -ms-flex-pack: end !important; + justify-content: flex-end !important; +} +.justify-content-center { + -ms-flex-pack: center !important; + justify-content: center !important; +} +.justify-content-between { + -ms-flex-pack: justify !important; + justify-content: space-between !important; +} +.justify-content-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; +} +.align-items-start { + -ms-flex-align: start !important; + align-items: flex-start !important; +} +.align-items-end { + -ms-flex-align: end !important; + align-items: flex-end !important; +} +.align-items-center { + -ms-flex-align: center !important; + align-items: center !important; +} +.align-items-baseline { + -ms-flex-align: baseline !important; + align-items: baseline !important; +} +.align-items-stretch { + -ms-flex-align: stretch !important; + align-items: stretch !important; +} +.align-content-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; +} +.align-content-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; +} +.align-content-center { + -ms-flex-line-pack: center !important; + align-content: center !important; +} +.align-content-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; +} +.align-content-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; +} +.align-content-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; +} +.align-self-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; +} +.align-self-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; +} +.align-self-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; +} +.align-self-center { + -ms-flex-item-align: center !important; + align-self: center !important; +} +.align-self-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; +} +.align-self-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; +} +@media (min-width: 576px) { + .flex-sm-row { + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-sm-column { + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-sm-row-reverse { + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-sm-column-reverse { + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-sm-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-sm-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-sm-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .flex-sm-fill { + -ms-flex: 1 1 auto !important; + flex: 1 1 auto !important; + } + .flex-sm-grow-0 { + -ms-flex-positive: 0 !important; + flex-grow: 0 !important; + } + .flex-sm-grow-1 { + -ms-flex-positive: 1 !important; + flex-grow: 1 !important; + } + .flex-sm-shrink-0 { + -ms-flex-negative: 0 !important; + flex-shrink: 0 !important; + } + .flex-sm-shrink-1 { + -ms-flex-negative: 1 !important; + flex-shrink: 1 !important; + } + .justify-content-sm-start { + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-sm-end { + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-sm-center { + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-sm-between { + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-sm-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-sm-start { + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-sm-end { + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-sm-center { + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-sm-baseline { + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-sm-stretch { + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-sm-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-sm-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-sm-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-sm-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-sm-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-sm-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-sm-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-sm-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-sm-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-sm-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-sm-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-sm-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 768px) { + .flex-md-row { + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-md-column { + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-md-row-reverse { + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-md-column-reverse { + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-md-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-md-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-md-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .flex-md-fill { + -ms-flex: 1 1 auto !important; + flex: 1 1 auto !important; + } + .flex-md-grow-0 { + -ms-flex-positive: 0 !important; + flex-grow: 0 !important; + } + .flex-md-grow-1 { + -ms-flex-positive: 1 !important; + flex-grow: 1 !important; + } + .flex-md-shrink-0 { + -ms-flex-negative: 0 !important; + flex-shrink: 0 !important; + } + .flex-md-shrink-1 { + -ms-flex-negative: 1 !important; + flex-shrink: 1 !important; + } + .justify-content-md-start { + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-md-end { + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-md-center { + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-md-between { + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-md-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-md-start { + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-md-end { + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-md-center { + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-md-baseline { + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-md-stretch { + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-md-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-md-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-md-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-md-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-md-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-md-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-md-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-md-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-md-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-md-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-md-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-md-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 992px) { + .flex-lg-row { + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-lg-column { + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-lg-row-reverse { + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-lg-column-reverse { + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-lg-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-lg-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-lg-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .flex-lg-fill { + -ms-flex: 1 1 auto !important; + flex: 1 1 auto !important; + } + .flex-lg-grow-0 { + -ms-flex-positive: 0 !important; + flex-grow: 0 !important; + } + .flex-lg-grow-1 { + -ms-flex-positive: 1 !important; + flex-grow: 1 !important; + } + .flex-lg-shrink-0 { + -ms-flex-negative: 0 !important; + flex-shrink: 0 !important; + } + .flex-lg-shrink-1 { + -ms-flex-negative: 1 !important; + flex-shrink: 1 !important; + } + .justify-content-lg-start { + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-lg-end { + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-lg-center { + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-lg-between { + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-lg-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-lg-start { + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-lg-end { + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-lg-center { + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-lg-baseline { + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-lg-stretch { + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-lg-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-lg-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-lg-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-lg-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-lg-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-lg-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-lg-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-lg-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-lg-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-lg-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-lg-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-lg-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +@media (min-width: 1200px) { + .flex-xl-row { + -ms-flex-direction: row !important; + flex-direction: row !important; + } + .flex-xl-column { + -ms-flex-direction: column !important; + flex-direction: column !important; + } + .flex-xl-row-reverse { + -ms-flex-direction: row-reverse !important; + flex-direction: row-reverse !important; + } + .flex-xl-column-reverse { + -ms-flex-direction: column-reverse !important; + flex-direction: column-reverse !important; + } + .flex-xl-wrap { + -ms-flex-wrap: wrap !important; + flex-wrap: wrap !important; + } + .flex-xl-nowrap { + -ms-flex-wrap: nowrap !important; + flex-wrap: nowrap !important; + } + .flex-xl-wrap-reverse { + -ms-flex-wrap: wrap-reverse !important; + flex-wrap: wrap-reverse !important; + } + .flex-xl-fill { + -ms-flex: 1 1 auto !important; + flex: 1 1 auto !important; + } + .flex-xl-grow-0 { + -ms-flex-positive: 0 !important; + flex-grow: 0 !important; + } + .flex-xl-grow-1 { + -ms-flex-positive: 1 !important; + flex-grow: 1 !important; + } + .flex-xl-shrink-0 { + -ms-flex-negative: 0 !important; + flex-shrink: 0 !important; + } + .flex-xl-shrink-1 { + -ms-flex-negative: 1 !important; + flex-shrink: 1 !important; + } + .justify-content-xl-start { + -ms-flex-pack: start !important; + justify-content: flex-start !important; + } + .justify-content-xl-end { + -ms-flex-pack: end !important; + justify-content: flex-end !important; + } + .justify-content-xl-center { + -ms-flex-pack: center !important; + justify-content: center !important; + } + .justify-content-xl-between { + -ms-flex-pack: justify !important; + justify-content: space-between !important; + } + .justify-content-xl-around { + -ms-flex-pack: distribute !important; + justify-content: space-around !important; + } + .align-items-xl-start { + -ms-flex-align: start !important; + align-items: flex-start !important; + } + .align-items-xl-end { + -ms-flex-align: end !important; + align-items: flex-end !important; + } + .align-items-xl-center { + -ms-flex-align: center !important; + align-items: center !important; + } + .align-items-xl-baseline { + -ms-flex-align: baseline !important; + align-items: baseline !important; + } + .align-items-xl-stretch { + -ms-flex-align: stretch !important; + align-items: stretch !important; + } + .align-content-xl-start { + -ms-flex-line-pack: start !important; + align-content: flex-start !important; + } + .align-content-xl-end { + -ms-flex-line-pack: end !important; + align-content: flex-end !important; + } + .align-content-xl-center { + -ms-flex-line-pack: center !important; + align-content: center !important; + } + .align-content-xl-between { + -ms-flex-line-pack: justify !important; + align-content: space-between !important; + } + .align-content-xl-around { + -ms-flex-line-pack: distribute !important; + align-content: space-around !important; + } + .align-content-xl-stretch { + -ms-flex-line-pack: stretch !important; + align-content: stretch !important; + } + .align-self-xl-auto { + -ms-flex-item-align: auto !important; + align-self: auto !important; + } + .align-self-xl-start { + -ms-flex-item-align: start !important; + align-self: flex-start !important; + } + .align-self-xl-end { + -ms-flex-item-align: end !important; + align-self: flex-end !important; + } + .align-self-xl-center { + -ms-flex-item-align: center !important; + align-self: center !important; + } + .align-self-xl-baseline { + -ms-flex-item-align: baseline !important; + align-self: baseline !important; + } + .align-self-xl-stretch { + -ms-flex-item-align: stretch !important; + align-self: stretch !important; + } +} +.float-left { + float: left !important; +} +.float-right { + float: right !important; +} +.float-none { + float: none !important; +} +@media (min-width: 576px) { + .float-sm-left { + float: left !important; + } + .float-sm-right { + float: right !important; + } + .float-sm-none { + float: none !important; + } +} +@media (min-width: 768px) { + .float-md-left { + float: left !important; + } + .float-md-right { + float: right !important; + } + .float-md-none { + float: none !important; + } +} +@media (min-width: 992px) { + .float-lg-left { + float: left !important; + } + .float-lg-right { + float: right !important; + } + .float-lg-none { + float: none !important; + } +} +@media (min-width: 1200px) { + .float-xl-left { + float: left !important; + } + .float-xl-right { + float: right !important; + } + .float-xl-none { + float: none !important; + } +} +.user-select-all { + -webkit-user-select: all !important; + -moz-user-select: all !important; + -ms-user-select: all !important; + user-select: all !important; +} +.user-select-auto { + -webkit-user-select: auto !important; + -moz-user-select: auto !important; + -ms-user-select: auto !important; + user-select: auto !important; +} +.user-select-none { + -webkit-user-select: none !important; + -moz-user-select: none !important; + -ms-user-select: none !important; + user-select: none !important; +} +.overflow-auto { + overflow: auto !important; +} +.overflow-hidden { + overflow: hidden !important; +} +.position-static { + position: static !important; +} +.position-relative { + position: relative !important; +} +.position-absolute { + position: absolute !important; +} +.position-fixed { + position: fixed !important; +} +.position-sticky { + position: -webkit-sticky !important; + position: sticky !important; +} +.fixed-top { + position: fixed; + top: 0; + right: 0; + left: 0; + z-index: 1030; +} +.fixed-bottom { + position: fixed; + right: 0; + bottom: 0; + left: 0; + z-index: 1030; +} +@supports ((position: -webkit-sticky) or (position: sticky)) { + .sticky-top { + position: -webkit-sticky; + position: sticky; + top: 0; + z-index: 1020; + } +} +.sr-only { + position: absolute; + width: 1px; + height: 1px; + padding: 0; + margin: -1px; + overflow: hidden; + clip: rect(0, 0, 0, 0); + white-space: nowrap; + border: 0; +} +.sr-only-focusable:active, +.sr-only-focusable:focus { + position: static; + width: auto; + height: auto; + overflow: visible; + clip: auto; + white-space: normal; +} +.shadow-sm { + box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important; +} +.shadow { + box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important; +} +.shadow-lg { + box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important; +} +.shadow-none { + box-shadow: none !important; +} +.w-25 { + width: 25% !important; +} +.w-50 { + width: 50% !important; +} +.w-75 { + width: 75% !important; +} +.w-100 { + width: 100% !important; +} +.w-auto { + width: auto !important; +} +.h-25 { + height: 25% !important; +} +.h-50 { + height: 50% !important; +} +.h-75 { + height: 75% !important; +} +.h-100 { + height: 100% !important; +} +.h-auto { + height: auto !important; +} +.mw-100 { + max-width: 100% !important; +} +.mh-100 { + max-height: 100% !important; +} +.min-vw-100 { + min-width: 100vw !important; +} +.min-vh-100 { + min-height: 100vh !important; +} +.vw-100 { + width: 100vw !important; +} +.vh-100 { + height: 100vh !important; +} +.m-0 { + margin: 0 !important; +} +.mt-0, +.my-0 { + margin-top: 0 !important; +} +.mr-0, +.mx-0 { + margin-right: 0 !important; +} +.mb-0, +.my-0 { + margin-bottom: 0 !important; +} +.ml-0, +.mx-0 { + margin-left: 0 !important; +} +.m-1 { + margin: 0.25rem !important; +} +.mt-1, +.my-1 { + margin-top: 0.25rem !important; +} +.mr-1, +.mx-1 { + margin-right: 0.25rem !important; +} +.mb-1, +.my-1 { + margin-bottom: 0.25rem !important; +} +.ml-1, +.mx-1 { + margin-left: 0.25rem !important; +} +.m-2 { + margin: 0.5rem !important; +} +.mt-2, +.my-2 { + margin-top: 0.5rem !important; +} +.mr-2, +.mx-2 { + margin-right: 0.5rem !important; +} +.mb-2, +.my-2 { + margin-bottom: 0.5rem !important; +} +.ml-2, +.mx-2 { + margin-left: 0.5rem !important; +} +.m-3 { + margin: 1rem !important; +} +.mt-3, +.my-3 { + margin-top: 1rem !important; +} +.mr-3, +.mx-3 { + margin-right: 1rem !important; +} +.mb-3, +.my-3 { + margin-bottom: 1rem !important; +} +.ml-3, +.mx-3 { + margin-left: 1rem !important; +} +.m-4 { + margin: 1.5rem !important; +} +.mt-4, +.my-4 { + margin-top: 1.5rem !important; +} +.mr-4, +.mx-4 { + margin-right: 1.5rem !important; +} +.mb-4, +.my-4 { + margin-bottom: 1.5rem !important; +} +.ml-4, +.mx-4 { + margin-left: 1.5rem !important; +} +.m-5 { + margin: 3rem !important; +} +.mt-5, +.my-5 { + margin-top: 3rem !important; +} +.mr-5, +.mx-5 { + margin-right: 3rem !important; +} +.mb-5, +.my-5 { + margin-bottom: 3rem !important; +} +.ml-5, +.mx-5 { + margin-left: 3rem !important; +} +.p-0 { + padding: 0 !important; +} +.pt-0, +.py-0 { + padding-top: 0 !important; +} +.pr-0, +.px-0 { + padding-right: 0 !important; +} +.pb-0, +.py-0 { + padding-bottom: 0 !important; +} +.pl-0, +.px-0 { + padding-left: 0 !important; +} +.p-1 { + padding: 0.25rem !important; +} +.pt-1, +.py-1 { + padding-top: 0.25rem !important; +} +.pr-1, +.px-1 { + padding-right: 0.25rem !important; +} +.pb-1, +.py-1 { + padding-bottom: 0.25rem !important; +} +.pl-1, +.px-1 { + padding-left: 0.25rem !important; +} +.p-2 { + padding: 0.5rem !important; +} +.pt-2, +.py-2 { + padding-top: 0.5rem !important; +} +.pr-2, +.px-2 { + padding-right: 0.5rem !important; +} +.pb-2, +.py-2 { + padding-bottom: 0.5rem !important; +} +.pl-2, +.px-2 { + padding-left: 0.5rem !important; +} +.p-3 { + padding: 1rem !important; +} +.pt-3, +.py-3 { + padding-top: 1rem !important; +} +.pr-3, +.px-3 { + padding-right: 1rem !important; +} +.pb-3, +.py-3 { + padding-bottom: 1rem !important; +} +.pl-3, +.px-3 { + padding-left: 1rem !important; +} +.p-4 { + padding: 1.5rem !important; +} +.pt-4, +.py-4 { + padding-top: 1.5rem !important; +} +.pr-4, +.px-4 { + padding-right: 1.5rem !important; +} +.pb-4, +.py-4 { + padding-bottom: 1.5rem !important; +} +.pl-4, +.px-4 { + padding-left: 1.5rem !important; +} +.p-5 { + padding: 3rem !important; +} +.pt-5, +.py-5 { + padding-top: 3rem !important; +} +.pr-5, +.px-5 { + padding-right: 3rem !important; +} +.pb-5, +.py-5 { + padding-bottom: 3rem !important; +} +.pl-5, +.px-5 { + padding-left: 3rem !important; +} +.m-n1 { + margin: -0.25rem !important; +} +.mt-n1, +.my-n1 { + margin-top: -0.25rem !important; +} +.mr-n1, +.mx-n1 { + margin-right: -0.25rem !important; +} +.mb-n1, +.my-n1 { + margin-bottom: -0.25rem !important; +} +.ml-n1, +.mx-n1 { + margin-left: -0.25rem !important; +} +.m-n2 { + margin: -0.5rem !important; +} +.mt-n2, +.my-n2 { + margin-top: -0.5rem !important; +} +.mr-n2, +.mx-n2 { + margin-right: -0.5rem !important; +} +.mb-n2, +.my-n2 { + margin-bottom: -0.5rem !important; +} +.ml-n2, +.mx-n2 { + margin-left: -0.5rem !important; +} +.m-n3 { + margin: -1rem !important; +} +.mt-n3, +.my-n3 { + margin-top: -1rem !important; +} +.mr-n3, +.mx-n3 { + margin-right: -1rem !important; +} +.mb-n3, +.my-n3 { + margin-bottom: -1rem !important; +} +.ml-n3, +.mx-n3 { + margin-left: -1rem !important; +} +.m-n4 { + margin: -1.5rem !important; +} +.mt-n4, +.my-n4 { + margin-top: -1.5rem !important; +} +.mr-n4, +.mx-n4 { + margin-right: -1.5rem !important; +} +.mb-n4, +.my-n4 { + margin-bottom: -1.5rem !important; +} +.ml-n4, +.mx-n4 { + margin-left: -1.5rem !important; +} +.m-n5 { + margin: -3rem !important; +} +.mt-n5, +.my-n5 { + margin-top: -3rem !important; +} +.mr-n5, +.mx-n5 { + margin-right: -3rem !important; +} +.mb-n5, +.my-n5 { + margin-bottom: -3rem !important; +} +.ml-n5, +.mx-n5 { + margin-left: -3rem !important; +} +.m-auto { + margin: auto !important; +} +.mt-auto, +.my-auto { + margin-top: auto !important; +} +.mr-auto, +.mx-auto { + margin-right: auto !important; +} +.mb-auto, +.my-auto { + margin-bottom: auto !important; +} +.ml-auto, +.mx-auto { + margin-left: auto !important; +} +@media (min-width: 576px) { + .m-sm-0 { + margin: 0 !important; + } + .mt-sm-0, + .my-sm-0 { + margin-top: 0 !important; + } + .mr-sm-0, + .mx-sm-0 { + margin-right: 0 !important; + } + .mb-sm-0, + .my-sm-0 { + margin-bottom: 0 !important; + } + .ml-sm-0, + .mx-sm-0 { + margin-left: 0 !important; + } + .m-sm-1 { + margin: 0.25rem !important; + } + .mt-sm-1, + .my-sm-1 { + margin-top: 0.25rem !important; + } + .mr-sm-1, + .mx-sm-1 { + margin-right: 0.25rem !important; + } + .mb-sm-1, + .my-sm-1 { + margin-bottom: 0.25rem !important; + } + .ml-sm-1, + .mx-sm-1 { + margin-left: 0.25rem !important; + } + .m-sm-2 { + margin: 0.5rem !important; + } + .mt-sm-2, + .my-sm-2 { + margin-top: 0.5rem !important; + } + .mr-sm-2, + .mx-sm-2 { + margin-right: 0.5rem !important; + } + .mb-sm-2, + .my-sm-2 { + margin-bottom: 0.5rem !important; + } + .ml-sm-2, + .mx-sm-2 { + margin-left: 0.5rem !important; + } + .m-sm-3 { + margin: 1rem !important; + } + .mt-sm-3, + .my-sm-3 { + margin-top: 1rem !important; + } + .mr-sm-3, + .mx-sm-3 { + margin-right: 1rem !important; + } + .mb-sm-3, + .my-sm-3 { + margin-bottom: 1rem !important; + } + .ml-sm-3, + .mx-sm-3 { + margin-left: 1rem !important; + } + .m-sm-4 { + margin: 1.5rem !important; + } + .mt-sm-4, + .my-sm-4 { + margin-top: 1.5rem !important; + } + .mr-sm-4, + .mx-sm-4 { + margin-right: 1.5rem !important; + } + .mb-sm-4, + .my-sm-4 { + margin-bottom: 1.5rem !important; + } + .ml-sm-4, + .mx-sm-4 { + margin-left: 1.5rem !important; + } + .m-sm-5 { + margin: 3rem !important; + } + .mt-sm-5, + .my-sm-5 { + margin-top: 3rem !important; + } + .mr-sm-5, + .mx-sm-5 { + margin-right: 3rem !important; + } + .mb-sm-5, + .my-sm-5 { + margin-bottom: 3rem !important; + } + .ml-sm-5, + .mx-sm-5 { + margin-left: 3rem !important; + } + .p-sm-0 { + padding: 0 !important; + } + .pt-sm-0, + .py-sm-0 { + padding-top: 0 !important; + } + .pr-sm-0, + .px-sm-0 { + padding-right: 0 !important; + } + .pb-sm-0, + .py-sm-0 { + padding-bottom: 0 !important; + } + .pl-sm-0, + .px-sm-0 { + padding-left: 0 !important; + } + .p-sm-1 { + padding: 0.25rem !important; + } + .pt-sm-1, + .py-sm-1 { + padding-top: 0.25rem !important; + } + .pr-sm-1, + .px-sm-1 { + padding-right: 0.25rem !important; + } + .pb-sm-1, + .py-sm-1 { + padding-bottom: 0.25rem !important; + } + .pl-sm-1, + .px-sm-1 { + padding-left: 0.25rem !important; + } + .p-sm-2 { + padding: 0.5rem !important; + } + .pt-sm-2, + .py-sm-2 { + padding-top: 0.5rem !important; + } + .pr-sm-2, + .px-sm-2 { + padding-right: 0.5rem !important; + } + .pb-sm-2, + .py-sm-2 { + padding-bottom: 0.5rem !important; + } + .pl-sm-2, + .px-sm-2 { + padding-left: 0.5rem !important; + } + .p-sm-3 { + padding: 1rem !important; + } + .pt-sm-3, + .py-sm-3 { + padding-top: 1rem !important; + } + .pr-sm-3, + .px-sm-3 { + padding-right: 1rem !important; + } + .pb-sm-3, + .py-sm-3 { + padding-bottom: 1rem !important; + } + .pl-sm-3, + .px-sm-3 { + padding-left: 1rem !important; + } + .p-sm-4 { + padding: 1.5rem !important; + } + .pt-sm-4, + .py-sm-4 { + padding-top: 1.5rem !important; + } + .pr-sm-4, + .px-sm-4 { + padding-right: 1.5rem !important; + } + .pb-sm-4, + .py-sm-4 { + padding-bottom: 1.5rem !important; + } + .pl-sm-4, + .px-sm-4 { + padding-left: 1.5rem !important; + } + .p-sm-5 { + padding: 3rem !important; + } + .pt-sm-5, + .py-sm-5 { + padding-top: 3rem !important; + } + .pr-sm-5, + .px-sm-5 { + padding-right: 3rem !important; + } + .pb-sm-5, + .py-sm-5 { + padding-bottom: 3rem !important; + } + .pl-sm-5, + .px-sm-5 { + padding-left: 3rem !important; + } + .m-sm-n1 { + margin: -0.25rem !important; + } + .mt-sm-n1, + .my-sm-n1 { + margin-top: -0.25rem !important; + } + .mr-sm-n1, + .mx-sm-n1 { + margin-right: -0.25rem !important; + } + .mb-sm-n1, + .my-sm-n1 { + margin-bottom: -0.25rem !important; + } + .ml-sm-n1, + .mx-sm-n1 { + margin-left: -0.25rem !important; + } + .m-sm-n2 { + margin: -0.5rem !important; + } + .mt-sm-n2, + .my-sm-n2 { + margin-top: -0.5rem !important; + } + .mr-sm-n2, + .mx-sm-n2 { + margin-right: -0.5rem !important; + } + .mb-sm-n2, + .my-sm-n2 { + margin-bottom: -0.5rem !important; + } + .ml-sm-n2, + .mx-sm-n2 { + margin-left: -0.5rem !important; + } + .m-sm-n3 { + margin: -1rem !important; + } + .mt-sm-n3, + .my-sm-n3 { + margin-top: -1rem !important; + } + .mr-sm-n3, + .mx-sm-n3 { + margin-right: -1rem !important; + } + .mb-sm-n3, + .my-sm-n3 { + margin-bottom: -1rem !important; + } + .ml-sm-n3, + .mx-sm-n3 { + margin-left: -1rem !important; + } + .m-sm-n4 { + margin: -1.5rem !important; + } + .mt-sm-n4, + .my-sm-n4 { + margin-top: -1.5rem !important; + } + .mr-sm-n4, + .mx-sm-n4 { + margin-right: -1.5rem !important; + } + .mb-sm-n4, + .my-sm-n4 { + margin-bottom: -1.5rem !important; + } + .ml-sm-n4, + .mx-sm-n4 { + margin-left: -1.5rem !important; + } + .m-sm-n5 { + margin: -3rem !important; + } + .mt-sm-n5, + .my-sm-n5 { + margin-top: -3rem !important; + } + .mr-sm-n5, + .mx-sm-n5 { + margin-right: -3rem !important; + } + .mb-sm-n5, + .my-sm-n5 { + margin-bottom: -3rem !important; + } + .ml-sm-n5, + .mx-sm-n5 { + margin-left: -3rem !important; + } + .m-sm-auto { + margin: auto !important; + } + .mt-sm-auto, + .my-sm-auto { + margin-top: auto !important; + } + .mr-sm-auto, + .mx-sm-auto { + margin-right: auto !important; + } + .mb-sm-auto, + .my-sm-auto { + margin-bottom: auto !important; + } + .ml-sm-auto, + .mx-sm-auto { + margin-left: auto !important; + } +} +@media (min-width: 768px) { + .m-md-0 { + margin: 0 !important; + } + .mt-md-0, + .my-md-0 { + margin-top: 0 !important; + } + .mr-md-0, + .mx-md-0 { + margin-right: 0 !important; + } + .mb-md-0, + .my-md-0 { + margin-bottom: 0 !important; + } + .ml-md-0, + .mx-md-0 { + margin-left: 0 !important; + } + .m-md-1 { + margin: 0.25rem !important; + } + .mt-md-1, + .my-md-1 { + margin-top: 0.25rem !important; + } + .mr-md-1, + .mx-md-1 { + margin-right: 0.25rem !important; + } + .mb-md-1, + .my-md-1 { + margin-bottom: 0.25rem !important; + } + .ml-md-1, + .mx-md-1 { + margin-left: 0.25rem !important; + } + .m-md-2 { + margin: 0.5rem !important; + } + .mt-md-2, + .my-md-2 { + margin-top: 0.5rem !important; + } + .mr-md-2, + .mx-md-2 { + margin-right: 0.5rem !important; + } + .mb-md-2, + .my-md-2 { + margin-bottom: 0.5rem !important; + } + .ml-md-2, + .mx-md-2 { + margin-left: 0.5rem !important; + } + .m-md-3 { + margin: 1rem !important; + } + .mt-md-3, + .my-md-3 { + margin-top: 1rem !important; + } + .mr-md-3, + .mx-md-3 { + margin-right: 1rem !important; + } + .mb-md-3, + .my-md-3 { + margin-bottom: 1rem !important; + } + .ml-md-3, + .mx-md-3 { + margin-left: 1rem !important; + } + .m-md-4 { + margin: 1.5rem !important; + } + .mt-md-4, + .my-md-4 { + margin-top: 1.5rem !important; + } + .mr-md-4, + .mx-md-4 { + margin-right: 1.5rem !important; + } + .mb-md-4, + .my-md-4 { + margin-bottom: 1.5rem !important; + } + .ml-md-4, + .mx-md-4 { + margin-left: 1.5rem !important; + } + .m-md-5 { + margin: 3rem !important; + } + .mt-md-5, + .my-md-5 { + margin-top: 3rem !important; + } + .mr-md-5, + .mx-md-5 { + margin-right: 3rem !important; + } + .mb-md-5, + .my-md-5 { + margin-bottom: 3rem !important; + } + .ml-md-5, + .mx-md-5 { + margin-left: 3rem !important; + } + .p-md-0 { + padding: 0 !important; + } + .pt-md-0, + .py-md-0 { + padding-top: 0 !important; + } + .pr-md-0, + .px-md-0 { + padding-right: 0 !important; + } + .pb-md-0, + .py-md-0 { + padding-bottom: 0 !important; + } + .pl-md-0, + .px-md-0 { + padding-left: 0 !important; + } + .p-md-1 { + padding: 0.25rem !important; + } + .pt-md-1, + .py-md-1 { + padding-top: 0.25rem !important; + } + .pr-md-1, + .px-md-1 { + padding-right: 0.25rem !important; + } + .pb-md-1, + .py-md-1 { + padding-bottom: 0.25rem !important; + } + .pl-md-1, + .px-md-1 { + padding-left: 0.25rem !important; + } + .p-md-2 { + padding: 0.5rem !important; + } + .pt-md-2, + .py-md-2 { + padding-top: 0.5rem !important; + } + .pr-md-2, + .px-md-2 { + padding-right: 0.5rem !important; + } + .pb-md-2, + .py-md-2 { + padding-bottom: 0.5rem !important; + } + .pl-md-2, + .px-md-2 { + padding-left: 0.5rem !important; + } + .p-md-3 { + padding: 1rem !important; + } + .pt-md-3, + .py-md-3 { + padding-top: 1rem !important; + } + .pr-md-3, + .px-md-3 { + padding-right: 1rem !important; + } + .pb-md-3, + .py-md-3 { + padding-bottom: 1rem !important; + } + .pl-md-3, + .px-md-3 { + padding-left: 1rem !important; + } + .p-md-4 { + padding: 1.5rem !important; + } + .pt-md-4, + .py-md-4 { + padding-top: 1.5rem !important; + } + .pr-md-4, + .px-md-4 { + padding-right: 1.5rem !important; + } + .pb-md-4, + .py-md-4 { + padding-bottom: 1.5rem !important; + } + .pl-md-4, + .px-md-4 { + padding-left: 1.5rem !important; + } + .p-md-5 { + padding: 3rem !important; + } + .pt-md-5, + .py-md-5 { + padding-top: 3rem !important; + } + .pr-md-5, + .px-md-5 { + padding-right: 3rem !important; + } + .pb-md-5, + .py-md-5 { + padding-bottom: 3rem !important; + } + .pl-md-5, + .px-md-5 { + padding-left: 3rem !important; + } + .m-md-n1 { + margin: -0.25rem !important; + } + .mt-md-n1, + .my-md-n1 { + margin-top: -0.25rem !important; + } + .mr-md-n1, + .mx-md-n1 { + margin-right: -0.25rem !important; + } + .mb-md-n1, + .my-md-n1 { + margin-bottom: -0.25rem !important; + } + .ml-md-n1, + .mx-md-n1 { + margin-left: -0.25rem !important; + } + .m-md-n2 { + margin: -0.5rem !important; + } + .mt-md-n2, + .my-md-n2 { + margin-top: -0.5rem !important; + } + .mr-md-n2, + .mx-md-n2 { + margin-right: -0.5rem !important; + } + .mb-md-n2, + .my-md-n2 { + margin-bottom: -0.5rem !important; + } + .ml-md-n2, + .mx-md-n2 { + margin-left: -0.5rem !important; + } + .m-md-n3 { + margin: -1rem !important; + } + .mt-md-n3, + .my-md-n3 { + margin-top: -1rem !important; + } + .mr-md-n3, + .mx-md-n3 { + margin-right: -1rem !important; + } + .mb-md-n3, + .my-md-n3 { + margin-bottom: -1rem !important; + } + .ml-md-n3, + .mx-md-n3 { + margin-left: -1rem !important; + } + .m-md-n4 { + margin: -1.5rem !important; + } + .mt-md-n4, + .my-md-n4 { + margin-top: -1.5rem !important; + } + .mr-md-n4, + .mx-md-n4 { + margin-right: -1.5rem !important; + } + .mb-md-n4, + .my-md-n4 { + margin-bottom: -1.5rem !important; + } + .ml-md-n4, + .mx-md-n4 { + margin-left: -1.5rem !important; + } + .m-md-n5 { + margin: -3rem !important; + } + .mt-md-n5, + .my-md-n5 { + margin-top: -3rem !important; + } + .mr-md-n5, + .mx-md-n5 { + margin-right: -3rem !important; + } + .mb-md-n5, + .my-md-n5 { + margin-bottom: -3rem !important; + } + .ml-md-n5, + .mx-md-n5 { + margin-left: -3rem !important; + } + .m-md-auto { + margin: auto !important; + } + .mt-md-auto, + .my-md-auto { + margin-top: auto !important; + } + .mr-md-auto, + .mx-md-auto { + margin-right: auto !important; + } + .mb-md-auto, + .my-md-auto { + margin-bottom: auto !important; + } + .ml-md-auto, + .mx-md-auto { + margin-left: auto !important; + } +} +@media (min-width: 992px) { + .m-lg-0 { + margin: 0 !important; + } + .mt-lg-0, + .my-lg-0 { + margin-top: 0 !important; + } + .mr-lg-0, + .mx-lg-0 { + margin-right: 0 !important; + } + .mb-lg-0, + .my-lg-0 { + margin-bottom: 0 !important; + } + .ml-lg-0, + .mx-lg-0 { + margin-left: 0 !important; + } + .m-lg-1 { + margin: 0.25rem !important; + } + .mt-lg-1, + .my-lg-1 { + margin-top: 0.25rem !important; + } + .mr-lg-1, + .mx-lg-1 { + margin-right: 0.25rem !important; + } + .mb-lg-1, + .my-lg-1 { + margin-bottom: 0.25rem !important; + } + .ml-lg-1, + .mx-lg-1 { + margin-left: 0.25rem !important; + } + .m-lg-2 { + margin: 0.5rem !important; + } + .mt-lg-2, + .my-lg-2 { + margin-top: 0.5rem !important; + } + .mr-lg-2, + .mx-lg-2 { + margin-right: 0.5rem !important; + } + .mb-lg-2, + .my-lg-2 { + margin-bottom: 0.5rem !important; + } + .ml-lg-2, + .mx-lg-2 { + margin-left: 0.5rem !important; + } + .m-lg-3 { + margin: 1rem !important; + } + .mt-lg-3, + .my-lg-3 { + margin-top: 1rem !important; + } + .mr-lg-3, + .mx-lg-3 { + margin-right: 1rem !important; + } + .mb-lg-3, + .my-lg-3 { + margin-bottom: 1rem !important; + } + .ml-lg-3, + .mx-lg-3 { + margin-left: 1rem !important; + } + .m-lg-4 { + margin: 1.5rem !important; + } + .mt-lg-4, + .my-lg-4 { + margin-top: 1.5rem !important; + } + .mr-lg-4, + .mx-lg-4 { + margin-right: 1.5rem !important; + } + .mb-lg-4, + .my-lg-4 { + margin-bottom: 1.5rem !important; + } + .ml-lg-4, + .mx-lg-4 { + margin-left: 1.5rem !important; + } + .m-lg-5 { + margin: 3rem !important; + } + .mt-lg-5, + .my-lg-5 { + margin-top: 3rem !important; + } + .mr-lg-5, + .mx-lg-5 { + margin-right: 3rem !important; + } + .mb-lg-5, + .my-lg-5 { + margin-bottom: 3rem !important; + } + .ml-lg-5, + .mx-lg-5 { + margin-left: 3rem !important; + } + .p-lg-0 { + padding: 0 !important; + } + .pt-lg-0, + .py-lg-0 { + padding-top: 0 !important; + } + .pr-lg-0, + .px-lg-0 { + padding-right: 0 !important; + } + .pb-lg-0, + .py-lg-0 { + padding-bottom: 0 !important; + } + .pl-lg-0, + .px-lg-0 { + padding-left: 0 !important; + } + .p-lg-1 { + padding: 0.25rem !important; + } + .pt-lg-1, + .py-lg-1 { + padding-top: 0.25rem !important; + } + .pr-lg-1, + .px-lg-1 { + padding-right: 0.25rem !important; + } + .pb-lg-1, + .py-lg-1 { + padding-bottom: 0.25rem !important; + } + .pl-lg-1, + .px-lg-1 { + padding-left: 0.25rem !important; + } + .p-lg-2 { + padding: 0.5rem !important; + } + .pt-lg-2, + .py-lg-2 { + padding-top: 0.5rem !important; + } + .pr-lg-2, + .px-lg-2 { + padding-right: 0.5rem !important; + } + .pb-lg-2, + .py-lg-2 { + padding-bottom: 0.5rem !important; + } + .pl-lg-2, + .px-lg-2 { + padding-left: 0.5rem !important; + } + .p-lg-3 { + padding: 1rem !important; + } + .pt-lg-3, + .py-lg-3 { + padding-top: 1rem !important; + } + .pr-lg-3, + .px-lg-3 { + padding-right: 1rem !important; + } + .pb-lg-3, + .py-lg-3 { + padding-bottom: 1rem !important; + } + .pl-lg-3, + .px-lg-3 { + padding-left: 1rem !important; + } + .p-lg-4 { + padding: 1.5rem !important; + } + .pt-lg-4, + .py-lg-4 { + padding-top: 1.5rem !important; + } + .pr-lg-4, + .px-lg-4 { + padding-right: 1.5rem !important; + } + .pb-lg-4, + .py-lg-4 { + padding-bottom: 1.5rem !important; + } + .pl-lg-4, + .px-lg-4 { + padding-left: 1.5rem !important; + } + .p-lg-5 { + padding: 3rem !important; + } + .pt-lg-5, + .py-lg-5 { + padding-top: 3rem !important; + } + .pr-lg-5, + .px-lg-5 { + padding-right: 3rem !important; + } + .pb-lg-5, + .py-lg-5 { + padding-bottom: 3rem !important; + } + .pl-lg-5, + .px-lg-5 { + padding-left: 3rem !important; + } + .m-lg-n1 { + margin: -0.25rem !important; + } + .mt-lg-n1, + .my-lg-n1 { + margin-top: -0.25rem !important; + } + .mr-lg-n1, + .mx-lg-n1 { + margin-right: -0.25rem !important; + } + .mb-lg-n1, + .my-lg-n1 { + margin-bottom: -0.25rem !important; + } + .ml-lg-n1, + .mx-lg-n1 { + margin-left: -0.25rem !important; + } + .m-lg-n2 { + margin: -0.5rem !important; + } + .mt-lg-n2, + .my-lg-n2 { + margin-top: -0.5rem !important; + } + .mr-lg-n2, + .mx-lg-n2 { + margin-right: -0.5rem !important; + } + .mb-lg-n2, + .my-lg-n2 { + margin-bottom: -0.5rem !important; + } + .ml-lg-n2, + .mx-lg-n2 { + margin-left: -0.5rem !important; + } + .m-lg-n3 { + margin: -1rem !important; + } + .mt-lg-n3, + .my-lg-n3 { + margin-top: -1rem !important; + } + .mr-lg-n3, + .mx-lg-n3 { + margin-right: -1rem !important; + } + .mb-lg-n3, + .my-lg-n3 { + margin-bottom: -1rem !important; + } + .ml-lg-n3, + .mx-lg-n3 { + margin-left: -1rem !important; + } + .m-lg-n4 { + margin: -1.5rem !important; + } + .mt-lg-n4, + .my-lg-n4 { + margin-top: -1.5rem !important; + } + .mr-lg-n4, + .mx-lg-n4 { + margin-right: -1.5rem !important; + } + .mb-lg-n4, + .my-lg-n4 { + margin-bottom: -1.5rem !important; + } + .ml-lg-n4, + .mx-lg-n4 { + margin-left: -1.5rem !important; + } + .m-lg-n5 { + margin: -3rem !important; + } + .mt-lg-n5, + .my-lg-n5 { + margin-top: -3rem !important; + } + .mr-lg-n5, + .mx-lg-n5 { + margin-right: -3rem !important; + } + .mb-lg-n5, + .my-lg-n5 { + margin-bottom: -3rem !important; + } + .ml-lg-n5, + .mx-lg-n5 { + margin-left: -3rem !important; + } + .m-lg-auto { + margin: auto !important; + } + .mt-lg-auto, + .my-lg-auto { + margin-top: auto !important; + } + .mr-lg-auto, + .mx-lg-auto { + margin-right: auto !important; + } + .mb-lg-auto, + .my-lg-auto { + margin-bottom: auto !important; + } + .ml-lg-auto, + .mx-lg-auto { + margin-left: auto !important; + } +} +@media (min-width: 1200px) { + .m-xl-0 { + margin: 0 !important; + } + .mt-xl-0, + .my-xl-0 { + margin-top: 0 !important; + } + .mr-xl-0, + .mx-xl-0 { + margin-right: 0 !important; + } + .mb-xl-0, + .my-xl-0 { + margin-bottom: 0 !important; + } + .ml-xl-0, + .mx-xl-0 { + margin-left: 0 !important; + } + .m-xl-1 { + margin: 0.25rem !important; + } + .mt-xl-1, + .my-xl-1 { + margin-top: 0.25rem !important; + } + .mr-xl-1, + .mx-xl-1 { + margin-right: 0.25rem !important; + } + .mb-xl-1, + .my-xl-1 { + margin-bottom: 0.25rem !important; + } + .ml-xl-1, + .mx-xl-1 { + margin-left: 0.25rem !important; + } + .m-xl-2 { + margin: 0.5rem !important; + } + .mt-xl-2, + .my-xl-2 { + margin-top: 0.5rem !important; + } + .mr-xl-2, + .mx-xl-2 { + margin-right: 0.5rem !important; + } + .mb-xl-2, + .my-xl-2 { + margin-bottom: 0.5rem !important; + } + .ml-xl-2, + .mx-xl-2 { + margin-left: 0.5rem !important; + } + .m-xl-3 { + margin: 1rem !important; + } + .mt-xl-3, + .my-xl-3 { + margin-top: 1rem !important; + } + .mr-xl-3, + .mx-xl-3 { + margin-right: 1rem !important; + } + .mb-xl-3, + .my-xl-3 { + margin-bottom: 1rem !important; + } + .ml-xl-3, + .mx-xl-3 { + margin-left: 1rem !important; + } + .m-xl-4 { + margin: 1.5rem !important; + } + .mt-xl-4, + .my-xl-4 { + margin-top: 1.5rem !important; + } + .mr-xl-4, + .mx-xl-4 { + margin-right: 1.5rem !important; + } + .mb-xl-4, + .my-xl-4 { + margin-bottom: 1.5rem !important; + } + .ml-xl-4, + .mx-xl-4 { + margin-left: 1.5rem !important; + } + .m-xl-5 { + margin: 3rem !important; + } + .mt-xl-5, + .my-xl-5 { + margin-top: 3rem !important; + } + .mr-xl-5, + .mx-xl-5 { + margin-right: 3rem !important; + } + .mb-xl-5, + .my-xl-5 { + margin-bottom: 3rem !important; + } + .ml-xl-5, + .mx-xl-5 { + margin-left: 3rem !important; + } + .p-xl-0 { + padding: 0 !important; + } + .pt-xl-0, + .py-xl-0 { + padding-top: 0 !important; + } + .pr-xl-0, + .px-xl-0 { + padding-right: 0 !important; + } + .pb-xl-0, + .py-xl-0 { + padding-bottom: 0 !important; + } + .pl-xl-0, + .px-xl-0 { + padding-left: 0 !important; + } + .p-xl-1 { + padding: 0.25rem !important; + } + .pt-xl-1, + .py-xl-1 { + padding-top: 0.25rem !important; + } + .pr-xl-1, + .px-xl-1 { + padding-right: 0.25rem !important; + } + .pb-xl-1, + .py-xl-1 { + padding-bottom: 0.25rem !important; + } + .pl-xl-1, + .px-xl-1 { + padding-left: 0.25rem !important; + } + .p-xl-2 { + padding: 0.5rem !important; + } + .pt-xl-2, + .py-xl-2 { + padding-top: 0.5rem !important; + } + .pr-xl-2, + .px-xl-2 { + padding-right: 0.5rem !important; + } + .pb-xl-2, + .py-xl-2 { + padding-bottom: 0.5rem !important; + } + .pl-xl-2, + .px-xl-2 { + padding-left: 0.5rem !important; + } + .p-xl-3 { + padding: 1rem !important; + } + .pt-xl-3, + .py-xl-3 { + padding-top: 1rem !important; + } + .pr-xl-3, + .px-xl-3 { + padding-right: 1rem !important; + } + .pb-xl-3, + .py-xl-3 { + padding-bottom: 1rem !important; + } + .pl-xl-3, + .px-xl-3 { + padding-left: 1rem !important; + } + .p-xl-4 { + padding: 1.5rem !important; + } + .pt-xl-4, + .py-xl-4 { + padding-top: 1.5rem !important; + } + .pr-xl-4, + .px-xl-4 { + padding-right: 1.5rem !important; + } + .pb-xl-4, + .py-xl-4 { + padding-bottom: 1.5rem !important; + } + .pl-xl-4, + .px-xl-4 { + padding-left: 1.5rem !important; + } + .p-xl-5 { + padding: 3rem !important; + } + .pt-xl-5, + .py-xl-5 { + padding-top: 3rem !important; + } + .pr-xl-5, + .px-xl-5 { + padding-right: 3rem !important; + } + .pb-xl-5, + .py-xl-5 { + padding-bottom: 3rem !important; + } + .pl-xl-5, + .px-xl-5 { + padding-left: 3rem !important; + } + .m-xl-n1 { + margin: -0.25rem !important; + } + .mt-xl-n1, + .my-xl-n1 { + margin-top: -0.25rem !important; + } + .mr-xl-n1, + .mx-xl-n1 { + margin-right: -0.25rem !important; + } + .mb-xl-n1, + .my-xl-n1 { + margin-bottom: -0.25rem !important; + } + .ml-xl-n1, + .mx-xl-n1 { + margin-left: -0.25rem !important; + } + .m-xl-n2 { + margin: -0.5rem !important; + } + .mt-xl-n2, + .my-xl-n2 { + margin-top: -0.5rem !important; + } + .mr-xl-n2, + .mx-xl-n2 { + margin-right: -0.5rem !important; + } + .mb-xl-n2, + .my-xl-n2 { + margin-bottom: -0.5rem !important; + } + .ml-xl-n2, + .mx-xl-n2 { + margin-left: -0.5rem !important; + } + .m-xl-n3 { + margin: -1rem !important; + } + .mt-xl-n3, + .my-xl-n3 { + margin-top: -1rem !important; + } + .mr-xl-n3, + .mx-xl-n3 { + margin-right: -1rem !important; + } + .mb-xl-n3, + .my-xl-n3 { + margin-bottom: -1rem !important; + } + .ml-xl-n3, + .mx-xl-n3 { + margin-left: -1rem !important; + } + .m-xl-n4 { + margin: -1.5rem !important; + } + .mt-xl-n4, + .my-xl-n4 { + margin-top: -1.5rem !important; + } + .mr-xl-n4, + .mx-xl-n4 { + margin-right: -1.5rem !important; + } + .mb-xl-n4, + .my-xl-n4 { + margin-bottom: -1.5rem !important; + } + .ml-xl-n4, + .mx-xl-n4 { + margin-left: -1.5rem !important; + } + .m-xl-n5 { + margin: -3rem !important; + } + .mt-xl-n5, + .my-xl-n5 { + margin-top: -3rem !important; + } + .mr-xl-n5, + .mx-xl-n5 { + margin-right: -3rem !important; + } + .mb-xl-n5, + .my-xl-n5 { + margin-bottom: -3rem !important; + } + .ml-xl-n5, + .mx-xl-n5 { + margin-left: -3rem !important; + } + .m-xl-auto { + margin: auto !important; + } + .mt-xl-auto, + .my-xl-auto { + margin-top: auto !important; + } + .mr-xl-auto, + .mx-xl-auto { + margin-right: auto !important; + } + .mb-xl-auto, + .my-xl-auto { + margin-bottom: auto !important; + } + .ml-xl-auto, + .mx-xl-auto { + margin-left: auto !important; + } +} +.stretched-link::after { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: 1; + pointer-events: auto; + content: ''; + background-color: rgba(0, 0, 0, 0); +} +.text-monospace { + font-family: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace !important; +} +.text-justify { + text-align: justify !important; +} +.text-wrap { + white-space: normal !important; +} +.text-nowrap { + white-space: nowrap !important; +} +.text-truncate { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.text-left { + text-align: left !important; +} +.text-right { + text-align: right !important; +} +.text-center { + text-align: center !important; +} +@media (min-width: 576px) { + .text-sm-left { + text-align: left !important; + } + .text-sm-right { + text-align: right !important; + } + .text-sm-center { + text-align: center !important; + } +} +@media (min-width: 768px) { + .text-md-left { + text-align: left !important; + } + .text-md-right { + text-align: right !important; + } + .text-md-center { + text-align: center !important; + } +} +@media (min-width: 992px) { + .text-lg-left { + text-align: left !important; + } + .text-lg-right { + text-align: right !important; + } + .text-lg-center { + text-align: center !important; + } +} +@media (min-width: 1200px) { + .text-xl-left { + text-align: left !important; + } + .text-xl-right { + text-align: right !important; + } + .text-xl-center { + text-align: center !important; + } +} +.text-lowercase { + text-transform: lowercase !important; +} +.text-uppercase { + text-transform: uppercase !important; +} +.text-capitalize { + text-transform: capitalize !important; +} +.font-weight-light { + font-weight: 300 !important; +} +.font-weight-lighter { + font-weight: lighter !important; +} +.font-weight-normal { + font-weight: 400 !important; +} +.font-weight-bold { + font-weight: 700 !important; +} +.font-weight-bolder { + font-weight: bolder !important; +} +.font-italic { + font-style: italic !important; +} +.text-white { + color: #fff !important; +} +.text-primary { + color: #007bff !important; +} +a.text-primary:focus, +a.text-primary:hover { + color: #0056b3 !important; +} +.text-secondary { + color: #6c757d !important; +} +a.text-secondary:focus, +a.text-secondary:hover { + color: #494f54 !important; +} +.text-success { + color: #28a745 !important; +} +a.text-success:focus, +a.text-success:hover { + color: #19692c !important; +} +.text-info { + color: #17a2b8 !important; +} +a.text-info:focus, +a.text-info:hover { + color: #0f6674 !important; +} +.text-warning { + color: #ffc107 !important; +} +a.text-warning:focus, +a.text-warning:hover { + color: #ba8b00 !important; +} +.text-danger { + color: #dc3545 !important; +} +a.text-danger:focus, +a.text-danger:hover { + color: #a71d2a !important; +} +.text-light { + color: #f8f9fa !important; +} +a.text-light:focus, +a.text-light:hover { + color: #cbd3da !important; +} +.text-dark { + color: #343a40 !important; +} +a.text-dark:focus, +a.text-dark:hover { + color: #121416 !important; +} +.text-body { + color: #212529 !important; +} +.text-muted { + color: #6c757d !important; +} +.text-black-50 { + color: rgba(0, 0, 0, 0.5) !important; +} +.text-white-50 { + color: rgba(255, 255, 255, 0.5) !important; +} +.text-hide { + font: 0/0 a; + color: transparent; + text-shadow: none; + background-color: transparent; + border: 0; +} +.text-decoration-none { + text-decoration: none !important; +} +.text-break { + word-break: break-word !important; + overflow-wrap: break-word !important; +} +.text-reset { + color: inherit !important; +} +.visible { + visibility: visible !important; +} +.invisible { + visibility: hidden !important; +} +@media print { + *, + ::after, + ::before { + text-shadow: none !important; + box-shadow: none !important; + } + a:not(.btn) { + text-decoration: underline; + } + abbr[title]::after { + content: ' (' attr(title) ')'; + } + pre { + white-space: pre-wrap !important; + } + blockquote, + pre { + border: 1px solid #adb5bd; + page-break-inside: avoid; + } + thead { + display: table-header-group; + } + img, + tr { + page-break-inside: avoid; + } + h2, + h3, + p { + orphans: 3; + widows: 3; + } + h2, + h3 { + page-break-after: avoid; + } + @page { + size: a3; + } + body { + min-width: 992px !important; + } + .container { + min-width: 992px !important; + } + .navbar { + display: none; + } + .badge { + border: 1px solid #000; + } + .table { + border-collapse: collapse !important; + } + .table td, + .table th { + background-color: #fff !important; + } + .table-bordered td, + .table-bordered th { + border: 1px solid #dee2e6 !important; + } + .table-dark { + color: inherit; + } + .table-dark tbody + tbody, + .table-dark td, + .table-dark th, + .table-dark thead th { + border-color: #dee2e6; + } + .table .thead-dark th { + color: inherit; + border-color: #dee2e6; + } +} +/*# sourceMappingURL=bootstrap.min.css.map */ diff --git a/src/main/webapp/content/scss/global.scss b/src/main/webapp/content/scss/global.scss index 6bc4bcb5624c887fdc0daaa08996fa310e141a65..74ff0a703b78a07bf9be6e9f828dda52eea8a51f 100644 --- a/src/main/webapp/content/scss/global.scss +++ b/src/main/webapp/content/scss/global.scss @@ -21,9 +21,10 @@ &:hover { background-color: #222222; } - } /* specific for markup handling */ /* centering on home page */ -.home h1 { text-align: center;} +.home h1 { + text-align: center; +} diff --git a/src/main/webapp/content/scss/vendor.scss b/src/main/webapp/content/scss/vendor.scss index db4b0ca5dd73391d9571542ebb740f69ec0510d0..c8eda20ae5accf48b554e0140179e4ae2c343819 100644 --- a/src/main/webapp/content/scss/vendor.scss +++ b/src/main/webapp/content/scss/vendor.scss @@ -12,4 +12,3 @@ eg $input-color: red; /* jhipster-needle-scss-add-vendor JHipster will add new css style */ //@import "~@ng-select/ng-select/themes/default.theme.css"; //@import '~katex/dist/katex.min.css'; - diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index e326ebf26bbc61d9164a64b990dbc58d4c2f493f..66f8afe4695f76cb0652d07ea0e4dc569247ff7a 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -12,12 +12,12 @@ <link rel="icon" href="favicon.ico" /> <link rel="manifest" href="manifest.webapp" /> <link rel="stylesheet" href="content/css/loading.css" /> - <!-- jQuery library --> - <script src="content/js/jquery3.5.1.min.js"></script> - <!-- Popper JS --> - <script src="content/js/popper1.16.0.min.js"></script> - <!-- Latest compiled JavaScript --> - <script src="content/js/bootstrap4.5.2.min.js"></script> + <!-- jQuery library --> + <script src="content/js/jquery3.5.1.min.js"></script> + <!-- Popper JS --> + <script src="content/js/popper1.16.0.min.js"></script> + <!-- Latest compiled JavaScript --> + <script src="content/js/bootstrap4.5.2.min.js"></script> <script src="content/js/duplicate/katex.min.js"></script> <script src="content/js/duplicate/joypixels.min.js"></script> <!-- jhipster-needle-add-resources-to-root - JHipster will add new resources here --> diff --git a/src/test/java/at/ac/uibk/gitsearch/ArchTest.java b/src/test/java/at/ac/uibk/gitsearch/ArchTest.java index 88424a7520afa760544d35527fb0e96e8a30cf07..b222e741e02111ed715318ec4227e43bd4d092b1 100644 --- a/src/test/java/at/ac/uibk/gitsearch/ArchTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/ArchTest.java @@ -1,29 +1,29 @@ package at.ac.uibk.gitsearch; +import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; + import com.tngtech.archunit.core.domain.JavaClasses; import com.tngtech.archunit.core.importer.ClassFileImporter; import com.tngtech.archunit.core.importer.ImportOption; import org.junit.jupiter.api.Test; -import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses; - class ArchTest { @Test void servicesAndRepositoriesShouldNotDependOnWebLayer() { - JavaClasses importedClasses = new ClassFileImporter() .withImportOption(ImportOption.Predefined.DO_NOT_INCLUDE_TESTS) .importPackages("at.ac.uibk.gitsearch"); noClasses() .that() - .resideInAnyPackage("at.ac.uibk.gitsearch.service..") + .resideInAnyPackage("at.ac.uibk.gitsearch.service..") .or() - .resideInAnyPackage("at.ac.uibk.gitsearch.repository..") - .should().dependOnClassesThat() - .resideInAnyPackage("..at.ac.uibk.gitsearch.web..") - .because("Services and repositories should not depend on web layer") - .check(importedClasses); + .resideInAnyPackage("at.ac.uibk.gitsearch.repository..") + .should() + .dependOnClassesThat() + .resideInAnyPackage("..at.ac.uibk.gitsearch.web..") + .because("Services and repositories should not depend on web layer") + .check(importedClasses); } } diff --git a/src/test/java/at/ac/uibk/gitsearch/IntegrationTest.java b/src/test/java/at/ac/uibk/gitsearch/IntegrationTest.java index 3e4188bb314ddf8b3e0dc02d536550b86e722fb2..54b7bd8786564b5e16e0246d8167ed90491bb0d7 100644 --- a/src/test/java/at/ac/uibk/gitsearch/IntegrationTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/IntegrationTest.java @@ -4,7 +4,6 @@ import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; - import org.springframework.boot.test.context.SpringBootTest; /** diff --git a/src/test/java/at/ac/uibk/gitsearch/TechnicalStructureTest.java b/src/test/java/at/ac/uibk/gitsearch/TechnicalStructureTest.java index a90e0886bc279a01078db4fd52225ec7856f0013..1748930e69301630587e58b9756af1d6e3923473 100644 --- a/src/test/java/at/ac/uibk/gitsearch/TechnicalStructureTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/TechnicalStructureTest.java @@ -4,6 +4,8 @@ import static com.tngtech.archunit.base.DescribedPredicate.alwaysTrue; import static com.tngtech.archunit.core.domain.JavaClass.Predicates.belongToAnyOf; import static com.tngtech.archunit.library.Architectures.layeredArchitecture; +import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; +import at.ac.uibk.gitsearch.security.jwt.TokenProvider; import com.tngtech.archunit.base.DescribedPredicate; import com.tngtech.archunit.core.domain.JavaClass; import com.tngtech.archunit.core.importer.ImportOption.DoNotIncludeTests; @@ -11,23 +13,21 @@ import com.tngtech.archunit.junit.AnalyzeClasses; import com.tngtech.archunit.junit.ArchTest; import com.tngtech.archunit.lang.ArchRule; -import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; -import at.ac.uibk.gitsearch.security.jwt.TokenProvider; - @AnalyzeClasses(packagesOf = GitsearchApp.class, importOptions = DoNotIncludeTests.class) class TechnicalStructureTest { - static class ServiceLayer extends DescribedPredicate<JavaClass> { - public ServiceLayer() { - super("ServiceLayer"); - } - - @Override - public boolean apply(JavaClass input) { - return input.getPackageName().contains(".service") && !input.getPackageName().contains(".service.dto"); - } - } - + static class ServiceLayer extends DescribedPredicate<JavaClass> { + + public ServiceLayer() { + super("ServiceLayer"); + } + + @Override + public boolean apply(JavaClass input) { + return input.getPackageName().contains(".service") && !input.getPackageName().contains(".service.dto"); + } + } + // prettier-ignore @ArchTest static final ArchRule respectsTechnicalArchitectureLayers = layeredArchitecture() diff --git a/src/test/java/at/ac/uibk/gitsearch/domain/ExerciseIdTest.java b/src/test/java/at/ac/uibk/gitsearch/domain/ExerciseIdTest.java index 564c03202e541dd8182b8111782da77678842d5e..ebba2facadd6bcc620e14b919f443798dfb1f5ed 100644 --- a/src/test/java/at/ac/uibk/gitsearch/domain/ExerciseIdTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/domain/ExerciseIdTest.java @@ -1,7 +1,6 @@ package at.ac.uibk.gitsearch.domain; import java.text.ParseException; - import org.codeability.sharing.plugins.api.search.util.ExerciseId; import org.junit.Assert; import org.junit.jupiter.api.Assertions; @@ -10,25 +9,24 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.ValueSource; public class ExerciseIdTest { - - @ParameterizedTest - @ValueSource(strings = {"3", "3:path", "3:path1/path2"} ) - public void parseVariousIds(String externalRepresentation) throws ParseException { - Assert.assertEquals(externalRepresentation, ExerciseId.fromString(externalRepresentation).toString()); - } - - @Test - public void parseIdsWithTrailingSlashes() throws ParseException { - Assert.assertEquals("30:abc", ExerciseId.fromString("30:/abc").toString()); - Assert.assertEquals("30:abc", ExerciseId.fromString("30://abc").toString()); - Assert.assertEquals("30", ExerciseId.fromString("30://").toString()); - Assert.assertEquals("30:abc/def", ExerciseId.fromString("30:/abc/def").toString()); - } - - @ParameterizedTest - @ValueSource(strings = {"=", ":path", "3x2", "3x2:/asd", "asdf=asd:30"} ) - public void parseCorruptIds(String corruptIds) throws ParseException { - Assertions.assertThrows(ParseException.class, () -> ExerciseId.fromString(corruptIds)); - } + @ParameterizedTest + @ValueSource(strings = { "3", "3:path", "3:path1/path2" }) + public void parseVariousIds(String externalRepresentation) throws ParseException { + Assert.assertEquals(externalRepresentation, ExerciseId.fromString(externalRepresentation).toString()); + } + + @Test + public void parseIdsWithTrailingSlashes() throws ParseException { + Assert.assertEquals("30:abc", ExerciseId.fromString("30:/abc").toString()); + Assert.assertEquals("30:abc", ExerciseId.fromString("30://abc").toString()); + Assert.assertEquals("30", ExerciseId.fromString("30://").toString()); + Assert.assertEquals("30:abc/def", ExerciseId.fromString("30:/abc/def").toString()); + } + + @ParameterizedTest + @ValueSource(strings = { "=", ":path", "3x2", "3x2:/asd", "asdf=asd:30" }) + public void parseCorruptIds(String corruptIds) throws ParseException { + Assertions.assertThrows(ParseException.class, () -> ExerciseId.fromString(corruptIds)); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/domain/LikesTest.java b/src/test/java/at/ac/uibk/gitsearch/domain/LikesTest.java index 20f70a7d8d04d7c61aebfb5127fbb4c2c9787db6..e8d9b0b67b4e70754ce5f917d2f071378c9f148d 100644 --- a/src/test/java/at/ac/uibk/gitsearch/domain/LikesTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/domain/LikesTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.domain; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + import at.ac.uibk.gitsearch.web.rest.TestUtil; +import org.junit.jupiter.api.Test; public class LikesTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/domain/StatisticsTest.java b/src/test/java/at/ac/uibk/gitsearch/domain/StatisticsTest.java index 1aa9897f0b6bbbec493514b5663f9c6d9c095e0e..2a4810a3f96d5cc93ca7fdf9fa0bdb91b2b0754f 100644 --- a/src/test/java/at/ac/uibk/gitsearch/domain/StatisticsTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/domain/StatisticsTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.domain; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + import at.ac.uibk.gitsearch.web.rest.TestUtil; +import org.junit.jupiter.api.Test; public class StatisticsTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/domain/UserWatchListTest.java b/src/test/java/at/ac/uibk/gitsearch/domain/UserWatchListTest.java index 439f91854cb52c5d7ec712c2e668141dd622b968..cc9bb8d89a9f6e33e26d239defa85098858ed78d 100644 --- a/src/test/java/at/ac/uibk/gitsearch/domain/UserWatchListTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/domain/UserWatchListTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.domain; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + import at.ac.uibk.gitsearch.web.rest.TestUtil; +import org.junit.jupiter.api.Test; public class UserWatchListTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/domain/WatchListEntryTest.java b/src/test/java/at/ac/uibk/gitsearch/domain/WatchListEntryTest.java index 1514b3a69d17f1358451bcba9b11aa02d0f07459..9e9404fec8e64b2c6f28e99258d6d65eb48a46b5 100644 --- a/src/test/java/at/ac/uibk/gitsearch/domain/WatchListEntryTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/domain/WatchListEntryTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.domain; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + import at.ac.uibk.gitsearch.web.rest.TestUtil; +import org.junit.jupiter.api.Test; public class WatchListEntryTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/es/model/ArtemisExerciseInfoTest.java b/src/test/java/at/ac/uibk/gitsearch/es/model/ArtemisExerciseInfoTest.java index 40fd531f34e7fbf79155031a07a5fe375a518cff..1681367dc4f4c8e7f18bfa9d731bd076e8e51a96 100644 --- a/src/test/java/at/ac/uibk/gitsearch/es/model/ArtemisExerciseInfoTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/es/model/ArtemisExerciseInfoTest.java @@ -1,10 +1,9 @@ package at.ac.uibk.gitsearch.es.model; -import org.junit.jupiter.api.Test; - import at.ac.uibk.gitsearch.testingUtilities.PropertiesTester; import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.Warning; +import org.junit.jupiter.api.Test; /** * just some very simple tests for test coverage :-) @@ -13,18 +12,20 @@ import nl.jqno.equalsverifier.Warning; */ class ArtemisExerciseInfoTest { - PropertiesTester propertiesTester = new PropertiesTester(); + PropertiesTester propertiesTester = new PropertiesTester(); - @Test - void testProperties() { - propertiesTester.testProperties(ArtemisExerciseInfo.class); - } + @Test + void testProperties() { + propertiesTester.testProperties(ArtemisExerciseInfo.class); + } - @Test - void testEquals() { - EqualsVerifier.simple().forClass(ArtemisExerciseInfo.class) - .suppress(Warning.NONFINAL_FIELDS) -// .suppress(Warning.INHERITED_DIRECTLY_FROM_OBJECT) - .verify(); - } + @Test + void testEquals() { + EqualsVerifier + .simple() + .forClass(ArtemisExerciseInfo.class) + .suppress(Warning.NONFINAL_FIELDS) + // .suppress(Warning.INHERITED_DIRECTLY_FROM_OBJECT) + .verify(); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/es/model/ExerciseInfoTest.java b/src/test/java/at/ac/uibk/gitsearch/es/model/ExerciseInfoTest.java index 1b0fdf7af99d707817545a8c3cc977935eff8e29..a703856029a7db6de7990518b3262a619383d49e 100644 --- a/src/test/java/at/ac/uibk/gitsearch/es/model/ExerciseInfoTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/es/model/ExerciseInfoTest.java @@ -1,10 +1,9 @@ package at.ac.uibk.gitsearch.es.model; -import org.junit.jupiter.api.Test; - import at.ac.uibk.gitsearch.testingUtilities.PropertiesTester; import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.Warning; +import org.junit.jupiter.api.Test; /** * just some very simple tests for test coverage :-) @@ -13,15 +12,15 @@ import nl.jqno.equalsverifier.Warning; */ class ExerciseInfoTest { - PropertiesTester propertiesTester = new PropertiesTester(); + PropertiesTester propertiesTester = new PropertiesTester(); - @Test - void testProperties() { - propertiesTester.testProperties(ExerciseInfo.class); - } + @Test + void testProperties() { + propertiesTester.testProperties(ExerciseInfo.class); + } - @Test - void testEquals() { - EqualsVerifier.simple().forClass(ExerciseInfo.class).suppress(Warning.NONFINAL_FIELDS).verify(); - } + @Test + void testEquals() { + EqualsVerifier.simple().forClass(ExerciseInfo.class).suppress(Warning.NONFINAL_FIELDS).verify(); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/CustomAuditEventRepositoryIT.java b/src/test/java/at/ac/uibk/gitsearch/repository/CustomAuditEventRepositoryIT.java index 839c7f4867e0c3f205b8548a882bf9ddb1fef8ab..f1a1fd19aa0691340fb6ccfc3c8621359673d2bc 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/CustomAuditEventRepositoryIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/CustomAuditEventRepositoryIT.java @@ -1,9 +1,17 @@ package at.ac.uibk.gitsearch.repository; -import at.ac.uibk.gitsearch.GitsearchApp; +import static at.ac.uibk.gitsearch.repository.CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH; +import static org.assertj.core.api.Assertions.assertThat; +import at.ac.uibk.gitsearch.GitsearchApp; import at.ac.uibk.gitsearch.config.Constants; import at.ac.uibk.gitsearch.domain.PersistentAuditEvent; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpSession; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -14,16 +22,6 @@ import org.springframework.mock.web.MockHttpSession; import org.springframework.security.web.authentication.WebAuthenticationDetails; import org.springframework.transaction.annotation.Transactional; -import javax.servlet.http.HttpSession; -import java.time.Instant; -import java.time.temporal.ChronoUnit; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static at.ac.uibk.gitsearch.repository.CustomAuditEventRepository.EVENT_DATA_COLUMN_MAX_LENGTH; - /** * Integration tests for {@link CustomAuditEventRepository}. */ @@ -153,5 +151,4 @@ public class CustomAuditEventRepositoryIT { List<PersistentAuditEvent> persistentAuditEvents = persistenceAuditEventRepository.findAll(); assertThat(persistentAuditEvents).hasSize(0); } - } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepositoryIT.java b/src/test/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepositoryIT.java index ba21d2184cbe89fa0fc5f473f3ab1ee1df8e06a4..f185302020fb953f72cd44faaf23feb3bf16edaa 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepositoryIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/gitlab/GitLabRepositoryIT.java @@ -3,6 +3,7 @@ package at.ac.uibk.gitsearch.repository.gitlab; //import static at.ac.uibk.gitsearch.web.rest.AccountResourceIT.TEST_USER_LOGIN; import static org.junit.Assert.assertNotNull; +import at.ac.uibk.gitsearch.GitsearchApp; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.gitlab4j.api.GitLabApi; @@ -12,29 +13,25 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.test.context.support.WithMockUser; -import at.ac.uibk.gitsearch.GitsearchApp; - @SpringBootTest(classes = GitsearchApp.class) @WithMockUser(value = "test", authorities = "sharing") public class GitLabRepositoryIT { - - - @SuppressWarnings("unused") - private static final Logger LOGGER = LogManager.getLogger(GitLabRepositoryIT.class); - @Autowired - private GitLabRepository gitLabRepository; - - @Test - public void getGitLabAccessInfoTest() { - gitLabRepository.getGitLabAccessInfo(); - } - - @Test - public void getGitLabApiTest() { - final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(); - final ApiVersion apiVersion = gitLabApi.getApiVersion(); - assertNotNull(apiVersion); - } + @SuppressWarnings("unused") + private static final Logger LOGGER = LogManager.getLogger(GitLabRepositoryIT.class); + + @Autowired + private GitLabRepository gitLabRepository; + + @Test + public void getGitLabAccessInfoTest() { + gitLabRepository.getGitLabAccessInfo(); + } + @Test + public void getGitLabApiTest() { + final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(); + final ApiVersion apiVersion = gitLabApi.getApiVersion(); + assertNotNull(apiVersion); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/gitlab/TestMetaDataGenerator.java b/src/test/java/at/ac/uibk/gitsearch/repository/gitlab/TestMetaDataGenerator.java index 0ba7ecf9c426037a9dfe867395fabcfeda964e69..690477921a7b56d6df3172d1b07e6bc33109a704 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/gitlab/TestMetaDataGenerator.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/gitlab/TestMetaDataGenerator.java @@ -11,7 +11,6 @@ import java.nio.file.Paths; import java.util.Base64; import java.util.List; import java.util.Optional; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.gitlab4j.api.Constants.Encoding; @@ -29,99 +28,97 @@ import org.springframework.beans.factory.annotation.Autowired; //@SpringBootTest(classes = GitsearchApp.class) public class TestMetaDataGenerator { - private static final Logger logger = LogManager.getLogger(TestMetaDataGenerator.class); - - @Autowired - GitLabRepository gitLabRepository; - @Test() - @Disabled // should only be activated for generation of test data - public void generateMetadata() throws GitLabApiException, IOException, URISyntaxException { - GitLabApi gitLabApi = new GitLabApi("https://sharing.codeability-austria.uibk.ac.at/", TokenType.ACCESS, "Hjh1Gk4yFHZs3z7XKonB"); - - generateTestData(gitLabApi, null, "Hjh1Gk4yFHZs3z7XKonB"); - } - - public byte[] getTestMetaData(File f, int count) throws IOException { - byte[] fileContent = new byte[] {}; - - fileContent = Files.readAllBytes(f.toPath()); - if(f.getName().endsWith(".yaml")) { - String content = new String(fileContent, StandardCharsets.UTF_8); - return content.replace("${title}", "Meta Test Data " + count).replace("${keyword}", "testing" + count).getBytes(); - } else { - return fileContent; - } - } - - /** - * just a weird location to generate Test Data :-(. Should be purged as soon as - * possible . - * - * @throws GitLabApiException - * @throws IOException - * @throws URISyntaxException - */ - public void generateTestData(GitLabApi gitLabApi, String issuerURI, String idToken) throws GitLabApiException, IOException, URISyntaxException { - final String projectPrefix = "apiTest"; - gitLabApi.enableRequestResponseLogging(); - boolean skipDelete = false; - if (!skipDelete) { - @SuppressWarnings("unchecked") - final List<Project> projects = (List<Project>) gitLabApi.getSearchApi().globalSearch(SearchScope.PROJECTS, - projectPrefix); - projects.stream().forEach(p -> { - try { - gitLabApi.getProjectApi().deleteProject(p.getId()); - } catch (GitLabApiException e) { - logger.warn("Cannot delete project {}", p.getName(), e); - } - }); - } - - final List<Namespace> namespaces = gitLabApi.getNamespaceApi().getNamespaces(); - Optional<Namespace> heathCheckNSO = namespaces.stream().filter(ns -> ns.getName().equals("health-check-tests")) - .findFirst(); - if (heathCheckNSO.isEmpty()) { - logger.warn("Namespace health-check-tests not found"); - return; - } - Namespace healthNS = heathCheckNSO.get(); - - final URL resourceFolder = this.getClass().getResource("testProject1"); - final Path dirPath = Paths.get(resourceFolder.toURI()); - File folderDir = dirPath.toFile(); - - if(!folderDir.exists() || !folderDir.isDirectory()) { - logger.error("No content folder found!"); - return; - } - - for (int i = 1; i <= 20; i++) { - Project p = new Project(); - p.setName("apiTest_" + i + "_" + System.currentTimeMillis()); - p.setDescription("Automatically generated testapi"); - p.setNamespace(healthNS); - p.setSharedWithGroups(null); - - - logger.info("Creating project {} in {}", p.getName(), healthNS.getFullPath()); - - Project createdProject = gitLabApi.getProjectApi().createProject(p); - - for(String path: folderDir.list()) { - File contentFile = new File(folderDir, path); - RepositoryFile rf = new RepositoryFile(); - rf.setFileName(path); - String base64encoded = Base64.getEncoder().encodeToString(getTestMetaData(contentFile, i)); - rf.setContent(base64encoded); - rf.setEncoding(Encoding.BASE64); - rf.setFilePath(path); - - gitLabApi.getRepositoryFileApi().createFile(createdProject.getId(), rf, "master", - "automagically generated file: " + path); - } - } - - } + private static final Logger logger = LogManager.getLogger(TestMetaDataGenerator.class); + + @Autowired + GitLabRepository gitLabRepository; + + @Test + @Disabled // should only be activated for generation of test data + public void generateMetadata() throws GitLabApiException, IOException, URISyntaxException { + GitLabApi gitLabApi = new GitLabApi("https://sharing.codeability-austria.uibk.ac.at/", TokenType.ACCESS, "Hjh1Gk4yFHZs3z7XKonB"); + + generateTestData(gitLabApi, null, "Hjh1Gk4yFHZs3z7XKonB"); + } + + public byte[] getTestMetaData(File f, int count) throws IOException { + byte[] fileContent = new byte[] {}; + + fileContent = Files.readAllBytes(f.toPath()); + if (f.getName().endsWith(".yaml")) { + String content = new String(fileContent, StandardCharsets.UTF_8); + return content.replace("${title}", "Meta Test Data " + count).replace("${keyword}", "testing" + count).getBytes(); + } else { + return fileContent; + } + } + + /** + * just a weird location to generate Test Data :-(. Should be purged as soon as + * possible . + * + * @throws GitLabApiException + * @throws IOException + * @throws URISyntaxException + */ + public void generateTestData(GitLabApi gitLabApi, String issuerURI, String idToken) + throws GitLabApiException, IOException, URISyntaxException { + final String projectPrefix = "apiTest"; + gitLabApi.enableRequestResponseLogging(); + boolean skipDelete = false; + if (!skipDelete) { + @SuppressWarnings("unchecked") + final List<Project> projects = (List<Project>) gitLabApi.getSearchApi().globalSearch(SearchScope.PROJECTS, projectPrefix); + projects + .stream() + .forEach(p -> { + try { + gitLabApi.getProjectApi().deleteProject(p.getId()); + } catch (GitLabApiException e) { + logger.warn("Cannot delete project {}", p.getName(), e); + } + }); + } + + final List<Namespace> namespaces = gitLabApi.getNamespaceApi().getNamespaces(); + Optional<Namespace> heathCheckNSO = namespaces.stream().filter(ns -> ns.getName().equals("health-check-tests")).findFirst(); + if (heathCheckNSO.isEmpty()) { + logger.warn("Namespace health-check-tests not found"); + return; + } + Namespace healthNS = heathCheckNSO.get(); + + final URL resourceFolder = this.getClass().getResource("testProject1"); + final Path dirPath = Paths.get(resourceFolder.toURI()); + File folderDir = dirPath.toFile(); + + if (!folderDir.exists() || !folderDir.isDirectory()) { + logger.error("No content folder found!"); + return; + } + + for (int i = 1; i <= 20; i++) { + Project p = new Project(); + p.setName("apiTest_" + i + "_" + System.currentTimeMillis()); + p.setDescription("Automatically generated testapi"); + p.setNamespace(healthNS); + p.setSharedWithGroups(null); + + logger.info("Creating project {} in {}", p.getName(), healthNS.getFullPath()); + + Project createdProject = gitLabApi.getProjectApi().createProject(p); + + for (String path : folderDir.list()) { + File contentFile = new File(folderDir, path); + RepositoryFile rf = new RepositoryFile(); + rf.setFileName(path); + String base64encoded = Base64.getEncoder().encodeToString(getTestMetaData(contentFile, i)); + rf.setContent(base64encoded); + rf.setEncoding(Encoding.BASE64); + rf.setFilePath(path); + gitLabApi.getRepositoryFileApi().createFile(createdProject.getId(), rf, "master", "automagically generated file: " + path); + } + } + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepositoryImplIT.java b/src/test/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepositoryImplIT.java index c08035c4959b61e6095bdc137bd1f9906dc0fdc7..bc78635d8672660f2c44cbd4726e531001f4deb7 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepositoryImplIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/search/GitFilesRepositoryImplIT.java @@ -2,17 +2,14 @@ package at.ac.uibk.gitsearch.repository.search; import static org.junit.jupiter.api.Assertions.fail; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.service.dto.GitFilesPageDetailsDTO; import java.io.IOException; - import org.codeability.sharing.plugins.api.search.SearchInputDTO; import org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.service.dto.GitFilesPageDetailsDTO; - - /** * is test fixture is currently empty. It seems very hard, to provide trivial tests. * TODO: Either remove GitFilesRepository infrastructure, or provide good tests. @@ -22,20 +19,19 @@ import at.ac.uibk.gitsearch.service.dto.GitFilesPageDetailsDTO; @SpringBootTest(classes = GitsearchApp.class) class GitFilesRepositoryImplIT { - @Autowired - private GitFilesRepository gitFilesRepository; - - // @Test - void testPageDetails() throws IOException { - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "testing", null, null, null,null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - @SuppressWarnings("unused") - GitFilesPageDetailsDTO searchResultPage = gitFilesRepository.pageDetails(searchQuery); - } - - // @Test - void testAggregation() { - fail("Not yet implemented"); - } - + @Autowired + private GitFilesRepository gitFilesRepository; + + // @Test + void testPageDetails() throws IOException { + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "testing", null, null, null, null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + @SuppressWarnings("unused") + GitFilesPageDetailsDTO searchResultPage = gitFilesRepository.pageDetails(searchQuery); + } + + // @Test + void testAggregation() { + fail("Not yet implemented"); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/search/LikesSearchRepositoryMockConfiguration.java b/src/test/java/at/ac/uibk/gitsearch/repository/search/LikesSearchRepositoryMockConfiguration.java index ccf865ef3be47a1d45d909dfb9c5b7aa7589b656..d2940e9b156f58de2db4678793517abfe55d9d71 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/search/LikesSearchRepositoryMockConfiguration.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/search/LikesSearchRepositoryMockConfiguration.java @@ -12,5 +12,4 @@ public class LikesSearchRepositoryMockConfiguration { @MockBean private LikesSearchRepository mockLikesSearchRepository; - } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/search/MetaDataRepositoryIT.java b/src/test/java/at/ac/uibk/gitsearch/repository/search/MetaDataRepositoryIT.java index 5d627e97fc45aa41dd6fe01ed3d3f69bf5156408..9958cb5f81300cb22f8338dc127b684960ba707b 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/search/MetaDataRepositoryIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/search/MetaDataRepositoryIT.java @@ -6,13 +6,14 @@ import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; import java.io.IOException; import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; - import javax.ws.rs.NotFoundException; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.codeability.sharing.plugins.api.search.SearchResultDTO; @@ -27,90 +28,89 @@ import org.junit.jupiter.api.Timeout; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; - @SpringBootTest(classes = GitsearchApp.class) public class MetaDataRepositoryIT { - @SuppressWarnings("unused") - private static final Logger LOGGER = LogManager.getLogger(MetaDataRepositoryIT.class); - - @Autowired - RestHighLevelClient elasticsearchTestClient; - - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } - - @BeforeEach - public void setUpIndex() { - } - - @Autowired - private MetaDataRepository metaDataRepository; - - @Test - public void testKeywordAutocompletion() throws IOException { - final List<AutoCompleteEntry> keywordsAutoComplete = metaDataRepository.getKeywordsAutoComplete("Jav", 10); - MatcherAssert.assertThat(keywordsAutoComplete, contains(hasProperty("target", is("Java")))); - } - - @Test - public void testCreatorAutocompletion() throws IOException { - final List<AutoCompleteEntry> creatorAutoComplete = metaDataRepository.getCreatorAutoComplete("Pod", 10); - MatcherAssert.assertThat(creatorAutoComplete, contains(hasProperty("target", is("Stefan Podlipnig")))); - final List<AutoCompleteEntry> creatorAutoComplete2 = metaDataRepository.getCreatorAutoComplete("Po", 10); - MatcherAssert.assertThat(creatorAutoComplete2, contains(hasProperty("target", is("Stefan Podlipnig")))); - } - - @Test - public void testContributorAutocompletion() throws IOException { - final List<AutoCompleteEntry> contributorAutoComplete = metaDataRepository.getContributorAutoComplete("Bast", 10); - MatcherAssert.assertThat(contributorAutoComplete, contains(hasProperty("target", is("Daniel Bastta")))); - } - - @Test - public void testProgrammingLanguageAutocompletion() throws IOException { - final List<AutoCompleteEntry> plAutoComplete = metaDataRepository.getProgrammingLanguageAutoComplete("Ja", 10); - MatcherAssert.assertThat(plAutoComplete, contains(hasProperty("target", is("JAVA")))); - } - - @Test - public void getByExerciseId() throws IOException { - // This test assumes that the test entries are public - for (int i : new int[] { 1 }) { - final SearchResultDTO exerciseById = metaDataRepository.getExerciseById(i + "", Optional.empty()); - assertNotNull("should be found:", exerciseById); - assertEquals("Id should be the same", i + "", exerciseById.getExerciseId()); - } - } - - @Test() - public void getByExerciseIdNegative() throws IOException { - // This test assumes that the test entries have consecutive ids - String exerciseId = "999999"; // should not exist - Assertions.assertThrows(NotFoundException.class, () -> { - metaDataRepository.getExerciseById(exerciseId, Optional.empty());}, - "Exercise for id " + exerciseId + " should not exist:"); - } + @SuppressWarnings("unused") + private static final Logger LOGGER = LogManager.getLogger(MetaDataRepositoryIT.class); + + @Autowired + RestHighLevelClient elasticsearchTestClient; + + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } + + @BeforeEach + public void setUpIndex() {} + + @Autowired + private MetaDataRepository metaDataRepository; + + @Test + public void testKeywordAutocompletion() throws IOException { + final List<AutoCompleteEntry> keywordsAutoComplete = metaDataRepository.getKeywordsAutoComplete("Jav", 10); + MatcherAssert.assertThat(keywordsAutoComplete, contains(hasProperty("target", is("Java")))); + } + + @Test + public void testCreatorAutocompletion() throws IOException { + final List<AutoCompleteEntry> creatorAutoComplete = metaDataRepository.getCreatorAutoComplete("Pod", 10); + MatcherAssert.assertThat(creatorAutoComplete, contains(hasProperty("target", is("Stefan Podlipnig")))); + final List<AutoCompleteEntry> creatorAutoComplete2 = metaDataRepository.getCreatorAutoComplete("Po", 10); + MatcherAssert.assertThat(creatorAutoComplete2, contains(hasProperty("target", is("Stefan Podlipnig")))); + } + + @Test + public void testContributorAutocompletion() throws IOException { + final List<AutoCompleteEntry> contributorAutoComplete = metaDataRepository.getContributorAutoComplete("Bast", 10); + MatcherAssert.assertThat(contributorAutoComplete, contains(hasProperty("target", is("Daniel Bastta")))); + } + + @Test + public void testProgrammingLanguageAutocompletion() throws IOException { + final List<AutoCompleteEntry> plAutoComplete = metaDataRepository.getProgrammingLanguageAutoComplete("Ja", 10); + MatcherAssert.assertThat(plAutoComplete, contains(hasProperty("target", is("JAVA")))); + } + + @Test + public void getByExerciseId() throws IOException { + // This test assumes that the test entries are public + for (int i : new int[] { 1 }) { + final SearchResultDTO exerciseById = metaDataRepository.getExerciseById(i + "", Optional.empty()); + assertNotNull("should be found:", exerciseById); + assertEquals("Id should be the same", i + "", exerciseById.getExerciseId()); + } + } + + @Test + public void getByExerciseIdNegative() throws IOException { + // This test assumes that the test entries have consecutive ids + String exerciseId = "999999"; // should not exist + Assertions.assertThrows( + NotFoundException.class, + () -> { + metaDataRepository.getExerciseById(exerciseId, Optional.empty()); + }, + "Exercise for id " + exerciseId + " should not exist:" + ); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/search/StatisticsSearchRepositoryMockConfiguration.java b/src/test/java/at/ac/uibk/gitsearch/repository/search/StatisticsSearchRepositoryMockConfiguration.java index 0be41bb6ec747d2b4726958c152a50e4237db509..ba0d9e80b8a6b5607d1bc3b105c8cb75939f69fc 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/search/StatisticsSearchRepositoryMockConfiguration.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/search/StatisticsSearchRepositoryMockConfiguration.java @@ -12,5 +12,4 @@ public class StatisticsSearchRepositoryMockConfiguration { @MockBean private StatisticsSearchRepository mockStatisticsSearchRepository; - } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/search/WatchListEntrySearchRepositoryMockConfiguration.java b/src/test/java/at/ac/uibk/gitsearch/repository/search/WatchListEntrySearchRepositoryMockConfiguration.java index a06ecf6f5113227774e2e995d7f197390816c6d2..f56cb7b844d41a81b40c355e1a03d6d225bbcd53 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/search/WatchListEntrySearchRepositoryMockConfiguration.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/search/WatchListEntrySearchRepositoryMockConfiguration.java @@ -12,5 +12,4 @@ public class WatchListEntrySearchRepositoryMockConfiguration { @MockBean private WatchListEntrySearchRepository mockWatchListEntrySearchRepository; - } diff --git a/src/test/java/at/ac/uibk/gitsearch/repository/search/testESService/ElasticSearchTestConfiguration.java b/src/test/java/at/ac/uibk/gitsearch/repository/search/testESService/ElasticSearchTestConfiguration.java index 8b79b49008cfafd1013a8cced3210b4cce72a05c..7060268b990d0e4e51c7777b998ce20952a8a555 100644 --- a/src/test/java/at/ac/uibk/gitsearch/repository/search/testESService/ElasticSearchTestConfiguration.java +++ b/src/test/java/at/ac/uibk/gitsearch/repository/search/testESService/ElasticSearchTestConfiguration.java @@ -1,5 +1,19 @@ package at.ac.uibk.gitsearch.repository.search.testESService; +import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; +import at.ac.uibk.gitsearch.repository.search.SearchRepositoryConstants; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.google.common.io.ByteSource; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -20,7 +34,6 @@ import java.util.HashMap; import java.util.List; import java.util.function.Consumer; import java.util.stream.Collectors; - import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpHost; import org.apache.http.util.EntityUtils; @@ -63,644 +76,619 @@ import org.testcontainers.elasticsearch.ElasticsearchContainer; import org.testcontainers.utility.DockerImageName; import org.testcontainers.utility.TestcontainersConfiguration; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; -import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.github.dockerjava.api.command.CreateContainerCmd; -import com.google.common.io.ByteSource; - -import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; -import at.ac.uibk.gitsearch.repository.search.SearchRepositoryConstants; - /** * this class provides test infrastructure for a local elastic search service * for local tests. - * + * * @author Michael Breu * */ @Service public class ElasticSearchTestConfiguration { - final static DockerImageName ELASTICSEARCH_IMAGE = DockerImageName - .parse("docker.elastic.co/elasticsearch/elasticsearch:7.17.0"); - - private ElasticsearchContainer esContainer; - - @Autowired - private RestHighLevelClient elasticsearchClient; - - public void stopTestContainer() { - if(esContainer!=null && esContainer.isCreated() && esContainer.isRunning()) { - esContainer.stop(); - esContainer.close(); - esContainer = null; - } - } - - private static int containerCounter = 0; - @SuppressWarnings("resource") - protected HttpHost startTestESContainer() throws IOException { - - TestcontainersConfiguration.getInstance().getClientPingTimeout(); - TestcontainersConfiguration.getInstance().updateGlobalConfig(getMetaDataConfigDefinition(), getMetaDataConfigDefinition()); - - final int hostPort = 9200; - - long memSize = 2 * 1024 * 1024 * 1024L; - - Consumer<CreateContainerCmd> memoryCmd = e -> e.getHostConfig().withMemory(memSize); - - WaitStrategy waitStrategy = new HttpWaitStrategy().withReadTimeout(Duration.of(10, ChronoUnit.SECONDS)) - .withStartupTimeout(Duration.of(5, ChronoUnit.MINUTES)); - - esContainer = new ElasticsearchContainer(ELASTICSEARCH_IMAGE) - .withStartupAttempts(200) - .withExposedPorts(hostPort).withCreateContainerCmdModifier(memoryCmd) - .waitingFor(waitStrategy) - .withCreateContainerCmdModifier( e -> e.withName("elasticsearchTestContainer" + (containerCounter++)) ) - ; - - // Start the container. This step might take some time... - esContainer.start(); - - Integer esPort = esContainer.getMappedPort(9200); - - String ipAddress = esContainer.getContainerIpAddress(); - - LOGGER.info("ES port is {}@{}", esPort, ipAddress); - - return new HttpHost(ipAddress, esPort); - } - - /** - * just a helper class to store also data that is not exported to the user - * - * @author Michael Breu - * - */ - public static class ExtendedGitProject extends GitProject { - private String visibility; - private boolean archived; - private int star_count; - private int open_issues_count; - private int forks_count; - private String description; - private String[] groups; - - /** - * @return the visibility - */ - public String getVisibility() { - return visibility; - } - - /** - * @param visibility the visibility to set - */ - public void setVisibility(String visibility) { - this.visibility = visibility; - } - - /** - * @return the archived - */ - public boolean isArchived() { - return archived; - } - - /** - * @param archived the archived to set - */ - public void setArchived(boolean archived) { - this.archived = archived; - } - - /** - * @return the star_count - */ - public int getStar_count() { - return star_count; - } - - /** - * @param star_count the star_count to set - */ - public void setStar_count(int star_count) { - this.star_count = star_count; - } - - /** - * @return the open_issues_count - */ - public int getOpen_issues_count() { - return open_issues_count; - } - - /** - * @param open_issues_count the open_issues_count to set - */ - public void setOpen_issues_count(int open_issues_count) { - this.open_issues_count = open_issues_count; - } - - /** - * @return the forks_count - */ - public int getForks_count() { - return forks_count; - } - - /** - * @param forks_count the forks_count to set - */ - public void setForks_count(int forks_count) { - this.forks_count = forks_count; - } - - /** - * @return the description - */ - public String getDescription() { - return description; - } - - /** - * @param description the description to set - */ - public void setDescription(String description) { - this.description = description; - } - - public String[] getGroups() { - return groups; - } - - public void setGroups(String[] groups) { - this.groups = groups; - } - - } - - private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ElasticSearchTestConfiguration.class); - private TestESNode testNode; - - public ElasticSearchTestConfiguration() { - } - - public synchronized void startTestNode() throws IOException, NodeValidationException { - - try { - HttpHost hostURL = startTestESContainer(); - - setUpESClientForTestESServer(hostURL); - - setUpMetaDataIndex(hostURL); - setUpContent(hostURL); - LOGGER.info("Started ES Test Node"); - } catch (Throwable t) { - LOGGER.info("ES Test Node crashed: ", t); - stopTestContainer(); - } - } - - private void setUpESClientForTestESServer(HttpHost hostURL) throws IOException { - elasticsearchClient.getLowLevelClient().setNodes(RestClient.builder(hostURL).build().getNodes()); - } - - private void setUpMetaDataIndex(HttpHost hostURL) throws IOException { - - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - - String elURL = hostURL.toURI(); - - try { - restTemplate.delete(elURL + "/_all"); - } catch (Throwable e) { - LOGGER.info("Deletion of previous index failed: {}!", e.getMessage()); - } - - List<String> indices2 = getIndices(hostURL); - - indices2.forEach((s) -> { - LOGGER.info("Found index {}", s); - try { - restTemplate.delete(elURL + "/" + s, String.class); // just in case, delete old index - } catch (RestClientException e) { - LOGGER.info("Deletion of previous index failed: {}!", e.getMessage()); - } - }); - -// GetIndexRequest request2 = new GetIndexRequest(); -// -// GetIndexResponse response = client.indices().get(request2, RequestOptions.DEFAULT); -// String[] indices = response.getIndices(); - - HttpEntity<String> request = new HttpEntity<String>(getMetaDataConfigDefinition(), headers); - - restTemplate.put(elURL + "/metadata?include_type_name=false", request, String.class); - - } - - private List<String> getIndices(HttpHost hostURL) throws IOException, JsonProcessingException, JsonMappingException { - List<String> indices2 = null; - RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(hostURL)); - - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - - RestClient restClient = client.getLowLevelClient(); - Response response2 = null; - try { - response2 = restClient.performRequest(new Request("GET", "/_cat/indices?v&format=json")); - } catch (IOException e) { - LOGGER.warn(e.toString(), e); - } - - // parse the JSON response - List<HashMap<String, String>> list = null; - if (response2 != null) { - ObjectMapper mapper = new ObjectMapper(); - String rawBody = EntityUtils.toString(response2.getEntity()); - TypeReference<List<HashMap<String, String>>> typeRef = new TypeReference<List<HashMap<String, String>>>() { - }; - list = mapper.readValue(rawBody, typeRef); - } - - // get the index names - if (list != null) { - indices2 = list.stream().map(x -> x.get("index")).collect(Collectors.toList()); - } - return indices2; - } - - int contentCount = 0; - - private void setUpContent(HttpHost elURL) throws IOException, URISyntaxException { - URL test = this.getClass().getResource("../../../service/testData"); - File rootData = new File(test.toURI()); - File metaDataTestDir = new File(rootData, "metaData"); - - contentCount = 0; - visitSubdirectories(metaDataTestDir, (File metaDataFile, List<SearchResultDTO> children, String relativePath, - ExtendedGitProject gitProject) -> { - try { - final UserProvidedMetadataDTO userMetaData = parseMetaDataFile(metaDataFile); - - SearchResultDTO toIndex = new SearchResultDTO(); - toIndex.setMetadata(userMetaData); - - final ExerciseId exerciseId = calculateProjectId(relativePath); - - if (gitProject == null) { - gitProject = new ExtendedGitProject(); - - gitProject.setProjectId(Integer.parseInt(exerciseId.getProjectId())); - gitProject.setProject_name("SomeGitProject" + exerciseId.getProjectId()); - gitProject.setVisibility("public"); - - } - - toIndex.setProject(gitProject); - - toIndex.setExerciseId(exerciseId.toString()); - - final MetadataFile file = new MetadataFile(); - file.setFilename(metaDataFile.getName()); - // path currently starts with project id - int slashPos = relativePath.indexOf("/"); - String projectRelativePath = (slashPos < 0) ? metaDataFile.getName() - : (relativePath.substring(slashPos + 1) + "/" + metaDataFile.getName()); - file.setPath(projectRelativePath); - file.setIndexing_date(Instant.now()); - file.setCommit_id("Unused Commit Id"); - file.setChildren(children.stream().map(c -> c.getExerciseId()).collect(Collectors.toList()) - .toArray(new String[] {})); - toIndex.setFile(file); - - toIndex.setExerciseId(exerciseId.toString()); - addContentToIndex(toIndex, exerciseId, elURL); - ElasticSearchTestConfiguration.this.contentCount++; - return Collections.singletonList(toIndex); - } catch (IOException e) { - e.printStackTrace(); - return null; - } - }, "", null /* no initial project */ - ); -// -// -// -// while(true) { -// contentCount++; -// final String content = getContent(contentCount); -// if(content==null) break; -// } - - waitForCleanStartUp(contentCount - 1); - } - - private void addContentToIndex(SearchResultDTO content, ExerciseId id, HttpHost elURL) - throws JsonGenerationException, JsonMappingException, IOException { - ObjectMapper mapper = MetaDataRepository.getSearchResultObjectMapper(); - StringWriter sw = new StringWriter(); - mapper.writeValue(sw, content); - String contentString = sw.toString(); - addContentToIndex(contentString, id.toString(), elURL); - } - - private static final Charset UTF8 = Charset.forName("UTF-8"); - - private void addContentToIndex(String content, String id, HttpHost elPortAndHost) { - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity<String> request = new HttpEntity<String>(content, headers); - String encodedId = URLEncoder.encode(id, UTF8); - encodedId = id.replace("/", "%2F"); - URI uri; - try { - uri = new URI(elPortAndHost.toURI() + "/metadata/_doc/" + encodedId); - restTemplate.put(uri, request); - } catch (URISyntaxException e) { - LOGGER.warn("Cannot add " + id, e); - } - - } - - private ExerciseId calculateProjectId(String relativePath) { - int relativePathPos = relativePath.indexOf("/"); - if (relativePathPos < 0) { - int projectId = Integer.parseInt(relativePath); - return new ExerciseId(projectId + "", null); - } else { - int projectId = Integer.parseInt(relativePath.substring(0, relativePathPos)); - return new ExerciseId(projectId + "", relativePath.substring(relativePathPos + 1)); - } - } - - /** - * parse the mete data file and return a normalized meta data - * - * @param metaDataFile the meta data file - * @return parsed metadata - * @throws JsonParseException - * @throws JsonMappingException - * @throws IOException - */ - private UserProvidedMetadataDTO parseMetaDataFile(File metaDataFile) - throws JsonParseException, JsonMappingException, IOException { - ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - mapper.findAndRegisterModules(); - UserProvidedMetadataDTO result = mapper.readValue(metaDataFile, UserProvidedMetadataDTO.class); - makeUpperCase(result.getProgrammingLanguage()); - return result; - } - - /** - * make all strings in Array uppercase. - * - * @param strings - */ - private void makeUpperCase(String[] strings) { - if (strings == null) - return; - for (int i = 0; i < strings.length; i++) { - strings[i] = strings[i].toUpperCase(); - } - } - - private ExtendedGitProject parseProjectFile(File projectFile) - throws JsonParseException, JsonMappingException, IOException { - ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - mapper.findAndRegisterModules(); - ExtendedGitProject result = mapper.readValue(projectFile, ExtendedGitProject.class); - return result; - } - - /** - * an interface that is invoked on each node of the tree with a metadata - * - * @author Michael Breu - * - * @param <T> the harvested data type - */ - private interface Harvester<T> { - /** - * - * @param f the metaData File - * @param subResults the list of results of the next node level - * @param relativePath the relative path from test root - * @param gitProject the information about the git project. - * @return - */ - List<T> harvest(File f, List<T> subResults, String relativePath, ExtendedGitProject gitProject); - } - - /** - * recursively visits all nodes, collects all children metadata and then calls - * the harvester - * - * @param <T> the type the harvester returns - * @param dir the directory to start harvesting in - * @param harvester the harvester function - * @param relativePath the relative path to dir - * @param gitProject the gitProject that may be collected from root. - * @return - */ - private <T> List<T> visitSubdirectories(File dir, Harvester<T> harvester, String relativePath, - ExtendedGitProject gitProject) { - Assert.state(dir.exists() && dir.isDirectory(), "must be a directory"); - List<T> harvestedMetadata = new ArrayList<T>(); - for (File containedFile : dir.listFiles()) { - if (!containedFile.isDirectory() && containedFile.getName().equals("project.yaml")) { - if (gitProject != null) { - LOGGER.error("A project.yaml should not overwrite an existing project in a subnode! {}", - containedFile.getAbsolutePath()); - } - try { - gitProject = parseProjectFile(containedFile); - } catch (IOException e) { - LOGGER.error("Cannot parse project.yaml for " + containedFile.getAbsolutePath(), e); - } - } - } - for (File containedFiles : dir.listFiles()) { - if (containedFiles.isDirectory()) - harvestedMetadata.addAll(visitSubdirectories(containedFiles, harvester, - (StringUtils.isEmpty(relativePath) ? "" : (relativePath + "/")) + containedFiles.getName(), - gitProject)); - } - for (File containedFiles : dir.listFiles()) { - if (!containedFiles.isDirectory() && containedFiles.getName().equals("metaData.yaml")) { - - harvestedMetadata - .addAll(harvester.harvest(containedFiles, harvestedMetadata, relativePath, gitProject)); - return harvestedMetadata; - } - } - return harvestedMetadata; - } - - /** - * replaces existing metadata by new content - * - * @param content - * @param id - */ - public void updateMetadata(String content, int id) { - String elURL = elasticsearchClient.getLowLevelClient().getNodes().get(0).getHost().toURI(); - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_JSON); - HttpEntity<String> request = new HttpEntity<String>(content, headers); - restTemplate.put(elURL +"/metadata/_doc/" + id, request, String.class); - } - - public String updateMetadata(SearchResultDTO testExercise, int id) - throws JsonGenerationException, JsonMappingException, IOException { - - String elURL = elasticsearchClient.getLowLevelClient().getNodes().get(0).getHost().toURI(); - // first fetch previous content - RestTemplate restTemplate = new RestTemplate(); - String previousContent = restTemplate.getForObject(elURL + "/metadata/_doc/" + id, String.class); - - ObjectMapper objectMapper = new ObjectMapper(); - final JavaTimeModule javaModule = new JavaTimeModule(); - - objectMapper.registerModule(javaModule); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - StringWriter sw = new StringWriter(); - objectMapper.writeValue(sw, testExercise); - final String contentString = sw.toString(); - updateMetadata(contentString, id); - - return previousContent; - } - - /** - * sets the content to a raw json string (containing "_source" attribute). Used - * to write back a changed value from updateMetadata(...). - * - * @param rawInput the json string - * @param id the id to write to - * @throws JsonGenerationException - * @throws JsonMappingException - * @throws IOException - */ - public void resetRawMetadata(String rawInput, int id) - throws JsonGenerationException, JsonMappingException, IOException { - - ObjectMapper objectMapper = new ObjectMapper(); - final JavaTimeModule javaModule = new JavaTimeModule(); - - objectMapper.registerModule(javaModule); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - final JsonNode tree = objectMapper.readTree(rawInput); - final JsonNode source = tree.at("/_source"); - StringWriter sw = new StringWriter(); - objectMapper.writeValue(sw, source); - final String contentString = sw.toString(); - updateMetadata(contentString, id); - - } - - /** - * we have to wait until correct startup of content indexing? - * - * @param minExpectedHits - */ - private void waitForCleanStartUp(int minExpectedHits) { - RestHighLevelClient client = elasticsearchClient; - int tryCount = 0; - while (tryCount < 10) { - tryCount++; - SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); - BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); - SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); - sourceBuilder.query(queryBuilder); - SearchResponse searchResponse; - try { - searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); - if (searchResponse.getHits().getTotalHits().value >= minExpectedHits) { - LOGGER.info("Metadata index is up with {} hits after {} trials", - searchResponse.getHits().getTotalHits(), tryCount); - return; - } else { - LOGGER.warn("Metadata index only {} hits up after {} trials", - searchResponse.getHits().getTotalHits(), tryCount); - } - } catch (IOException e) { - LOGGER.warn("Metadata index startup exception", e); - } - try { - Thread.sleep(1000L); - } catch (InterruptedException e) { - LOGGER.debug("Never mind: {}", e.getMessage()); - } - } - } - - private String getMetaDataConfigDefinition() throws IOException { - InputStream metaDataStream = this.getClass().getResourceAsStream("../testData/es_metadata.schema.json"); - ByteSource byteSource = new ByteSource() { - - @Override - public InputStream openStream() throws IOException { - return metaDataStream; - } - }; - String text = byteSource.asCharSource(StandardCharsets.UTF_8).read(); - return text; - } - - @EventListener - public void onApplicationEvent(ApplicationStartingEvent event) { - try { - startTestNode(); - } catch (IOException | NodeValidationException e) { - LOGGER.error("Cannot startup TestNode", e); - } - } - - @EventListener - public void onApplicationEvent(ContextStartedEvent event) { - try { - startTestNode(); - } catch (IOException | NodeValidationException e) { - LOGGER.error("Cannot startup TestNode", e); - } - } - - @EventListener - public void onApplicationEvent(ContextStoppedEvent event) { - try { - testNode.close(); - } catch (IOException e) { - LOGGER.error("Cannot startup TestNode", e); - } - } - - public static class TestESNode extends Node { - public TestESNode(Settings preparedSettings, Collection<Class<? extends Plugin>> classpathPlugins) { - super(InternalSettingsPreparer.prepareEnvironment(preparedSettings, new HashMap<String, String>(), null, - null), classpathPlugins, true); - } - -// @Override -// protected void registerDerivedNodeNameWithLogger(String nodeName) { -// LogManager.getLogger(nodeName); -// } - } - + static final DockerImageName ELASTICSEARCH_IMAGE = DockerImageName.parse("docker.elastic.co/elasticsearch/elasticsearch:7.17.0"); + + private ElasticsearchContainer esContainer; + + @Autowired + private RestHighLevelClient elasticsearchClient; + + public void stopTestContainer() { + if (esContainer != null && esContainer.isCreated() && esContainer.isRunning()) { + esContainer.stop(); + esContainer.close(); + esContainer = null; + } + } + + private static int containerCounter = 0; + + @SuppressWarnings("resource") + protected HttpHost startTestESContainer() throws IOException { + TestcontainersConfiguration.getInstance().getClientPingTimeout(); + TestcontainersConfiguration.getInstance().updateGlobalConfig(getMetaDataConfigDefinition(), getMetaDataConfigDefinition()); + + final int hostPort = 9200; + + long memSize = 2 * 1024 * 1024 * 1024L; + + Consumer<CreateContainerCmd> memoryCmd = e -> e.getHostConfig().withMemory(memSize); + + WaitStrategy waitStrategy = new HttpWaitStrategy() + .withReadTimeout(Duration.of(10, ChronoUnit.SECONDS)) + .withStartupTimeout(Duration.of(5, ChronoUnit.MINUTES)); + + esContainer = + new ElasticsearchContainer(ELASTICSEARCH_IMAGE) + .withStartupAttempts(200) + .withExposedPorts(hostPort) + .withCreateContainerCmdModifier(memoryCmd) + .waitingFor(waitStrategy) + .withCreateContainerCmdModifier(e -> e.withName("elasticsearchTestContainer" + (containerCounter++))); + + // Start the container. This step might take some time... + esContainer.start(); + + Integer esPort = esContainer.getMappedPort(9200); + + String ipAddress = esContainer.getContainerIpAddress(); + + LOGGER.info("ES port is {}@{}", esPort, ipAddress); + + return new HttpHost(ipAddress, esPort); + } + + /** + * just a helper class to store also data that is not exported to the user + * + * @author Michael Breu + * + */ + public static class ExtendedGitProject extends GitProject { + + private String visibility; + private boolean archived; + private int star_count; + private int open_issues_count; + private int forks_count; + private String description; + private String[] groups; + + /** + * @return the visibility + */ + public String getVisibility() { + return visibility; + } + + /** + * @param visibility the visibility to set + */ + public void setVisibility(String visibility) { + this.visibility = visibility; + } + + /** + * @return the archived + */ + public boolean isArchived() { + return archived; + } + + /** + * @param archived the archived to set + */ + public void setArchived(boolean archived) { + this.archived = archived; + } + + /** + * @return the star_count + */ + public int getStar_count() { + return star_count; + } + + /** + * @param star_count the star_count to set + */ + public void setStar_count(int star_count) { + this.star_count = star_count; + } + + /** + * @return the open_issues_count + */ + public int getOpen_issues_count() { + return open_issues_count; + } + + /** + * @param open_issues_count the open_issues_count to set + */ + public void setOpen_issues_count(int open_issues_count) { + this.open_issues_count = open_issues_count; + } + + /** + * @return the forks_count + */ + public int getForks_count() { + return forks_count; + } + + /** + * @param forks_count the forks_count to set + */ + public void setForks_count(int forks_count) { + this.forks_count = forks_count; + } + + /** + * @return the description + */ + public String getDescription() { + return description; + } + + /** + * @param description the description to set + */ + public void setDescription(String description) { + this.description = description; + } + + public String[] getGroups() { + return groups; + } + + public void setGroups(String[] groups) { + this.groups = groups; + } + } + + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ElasticSearchTestConfiguration.class); + private TestESNode testNode; + + public ElasticSearchTestConfiguration() {} + + public synchronized void startTestNode() throws IOException, NodeValidationException { + try { + HttpHost hostURL = startTestESContainer(); + + setUpESClientForTestESServer(hostURL); + + setUpMetaDataIndex(hostURL); + setUpContent(hostURL); + LOGGER.info("Started ES Test Node"); + } catch (Throwable t) { + LOGGER.info("ES Test Node crashed: ", t); + stopTestContainer(); + } + } + + private void setUpESClientForTestESServer(HttpHost hostURL) throws IOException { + elasticsearchClient.getLowLevelClient().setNodes(RestClient.builder(hostURL).build().getNodes()); + } + + private void setUpMetaDataIndex(HttpHost hostURL) throws IOException { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + String elURL = hostURL.toURI(); + + try { + restTemplate.delete(elURL + "/_all"); + } catch (Throwable e) { + LOGGER.info("Deletion of previous index failed: {}!", e.getMessage()); + } + + List<String> indices2 = getIndices(hostURL); + + indices2.forEach(s -> { + LOGGER.info("Found index {}", s); + try { + restTemplate.delete(elURL + "/" + s, String.class); // just in case, delete old index + } catch (RestClientException e) { + LOGGER.info("Deletion of previous index failed: {}!", e.getMessage()); + } + }); + + // GetIndexRequest request2 = new GetIndexRequest(); + // + // GetIndexResponse response = client.indices().get(request2, RequestOptions.DEFAULT); + // String[] indices = response.getIndices(); + + HttpEntity<String> request = new HttpEntity<String>(getMetaDataConfigDefinition(), headers); + + restTemplate.put(elURL + "/metadata?include_type_name=false", request, String.class); + } + + private List<String> getIndices(HttpHost hostURL) throws IOException, JsonProcessingException, JsonMappingException { + List<String> indices2 = null; + RestHighLevelClient client = new RestHighLevelClient(RestClient.builder(hostURL)); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + + RestClient restClient = client.getLowLevelClient(); + Response response2 = null; + try { + response2 = restClient.performRequest(new Request("GET", "/_cat/indices?v&format=json")); + } catch (IOException e) { + LOGGER.warn(e.toString(), e); + } + + // parse the JSON response + List<HashMap<String, String>> list = null; + if (response2 != null) { + ObjectMapper mapper = new ObjectMapper(); + String rawBody = EntityUtils.toString(response2.getEntity()); + TypeReference<List<HashMap<String, String>>> typeRef = new TypeReference<List<HashMap<String, String>>>() {}; + list = mapper.readValue(rawBody, typeRef); + } + + // get the index names + if (list != null) { + indices2 = list.stream().map(x -> x.get("index")).collect(Collectors.toList()); + } + return indices2; + } + + int contentCount = 0; + + private void setUpContent(HttpHost elURL) throws IOException, URISyntaxException { + URL test = this.getClass().getResource("../../../service/testData"); + File rootData = new File(test.toURI()); + File metaDataTestDir = new File(rootData, "metaData"); + + contentCount = 0; + visitSubdirectories( + metaDataTestDir, + (File metaDataFile, List<SearchResultDTO> children, String relativePath, ExtendedGitProject gitProject) -> { + try { + final UserProvidedMetadataDTO userMetaData = parseMetaDataFile(metaDataFile); + + SearchResultDTO toIndex = new SearchResultDTO(); + toIndex.setMetadata(userMetaData); + + final ExerciseId exerciseId = calculateProjectId(relativePath); + + if (gitProject == null) { + gitProject = new ExtendedGitProject(); + + gitProject.setProjectId(Integer.parseInt(exerciseId.getProjectId())); + gitProject.setProject_name("SomeGitProject" + exerciseId.getProjectId()); + gitProject.setVisibility("public"); + } + + toIndex.setProject(gitProject); + + toIndex.setExerciseId(exerciseId.toString()); + + final MetadataFile file = new MetadataFile(); + file.setFilename(metaDataFile.getName()); + // path currently starts with project id + int slashPos = relativePath.indexOf("/"); + String projectRelativePath = (slashPos < 0) + ? metaDataFile.getName() + : (relativePath.substring(slashPos + 1) + "/" + metaDataFile.getName()); + file.setPath(projectRelativePath); + file.setIndexing_date(Instant.now()); + file.setCommit_id("Unused Commit Id"); + file.setChildren(children.stream().map(c -> c.getExerciseId()).collect(Collectors.toList()).toArray(new String[] {})); + toIndex.setFile(file); + + toIndex.setExerciseId(exerciseId.toString()); + addContentToIndex(toIndex, exerciseId, elURL); + ElasticSearchTestConfiguration.this.contentCount++; + return Collections.singletonList(toIndex); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + }, + "", + null/* no initial project */ + ); + // + // + // + // while(true) { + // contentCount++; + // final String content = getContent(contentCount); + // if(content==null) break; + // } + + waitForCleanStartUp(contentCount - 1); + } + + private void addContentToIndex(SearchResultDTO content, ExerciseId id, HttpHost elURL) + throws JsonGenerationException, JsonMappingException, IOException { + ObjectMapper mapper = MetaDataRepository.getSearchResultObjectMapper(); + StringWriter sw = new StringWriter(); + mapper.writeValue(sw, content); + String contentString = sw.toString(); + addContentToIndex(contentString, id.toString(), elURL); + } + + private static final Charset UTF8 = Charset.forName("UTF-8"); + + private void addContentToIndex(String content, String id, HttpHost elPortAndHost) { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity<String> request = new HttpEntity<String>(content, headers); + String encodedId = URLEncoder.encode(id, UTF8); + encodedId = id.replace("/", "%2F"); + URI uri; + try { + uri = new URI(elPortAndHost.toURI() + "/metadata/_doc/" + encodedId); + restTemplate.put(uri, request); + } catch (URISyntaxException e) { + LOGGER.warn("Cannot add " + id, e); + } + } + + private ExerciseId calculateProjectId(String relativePath) { + int relativePathPos = relativePath.indexOf("/"); + if (relativePathPos < 0) { + int projectId = Integer.parseInt(relativePath); + return new ExerciseId(projectId + "", null); + } else { + int projectId = Integer.parseInt(relativePath.substring(0, relativePathPos)); + return new ExerciseId(projectId + "", relativePath.substring(relativePathPos + 1)); + } + } + + /** + * parse the mete data file and return a normalized meta data + * + * @param metaDataFile the meta data file + * @return parsed metadata + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + private UserProvidedMetadataDTO parseMetaDataFile(File metaDataFile) throws JsonParseException, JsonMappingException, IOException { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + mapper.findAndRegisterModules(); + UserProvidedMetadataDTO result = mapper.readValue(metaDataFile, UserProvidedMetadataDTO.class); + makeUpperCase(result.getProgrammingLanguage()); + return result; + } + + /** + * make all strings in Array uppercase. + * + * @param strings + */ + private void makeUpperCase(String[] strings) { + if (strings == null) return; + for (int i = 0; i < strings.length; i++) { + strings[i] = strings[i].toUpperCase(); + } + } + + private ExtendedGitProject parseProjectFile(File projectFile) throws JsonParseException, JsonMappingException, IOException { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + mapper.findAndRegisterModules(); + ExtendedGitProject result = mapper.readValue(projectFile, ExtendedGitProject.class); + return result; + } + + /** + * an interface that is invoked on each node of the tree with a metadata + * + * @author Michael Breu + * + * @param <T> the harvested data type + */ + private interface Harvester<T> { + /** + * + * @param f the metaData File + * @param subResults the list of results of the next node level + * @param relativePath the relative path from test root + * @param gitProject the information about the git project. + * @return + */ + List<T> harvest(File f, List<T> subResults, String relativePath, ExtendedGitProject gitProject); + } + + /** + * recursively visits all nodes, collects all children metadata and then calls + * the harvester + * + * @param <T> the type the harvester returns + * @param dir the directory to start harvesting in + * @param harvester the harvester function + * @param relativePath the relative path to dir + * @param gitProject the gitProject that may be collected from root. + * @return + */ + private <T> List<T> visitSubdirectories(File dir, Harvester<T> harvester, String relativePath, ExtendedGitProject gitProject) { + Assert.state(dir.exists() && dir.isDirectory(), "must be a directory"); + List<T> harvestedMetadata = new ArrayList<T>(); + for (File containedFile : dir.listFiles()) { + if (!containedFile.isDirectory() && containedFile.getName().equals("project.yaml")) { + if (gitProject != null) { + LOGGER.error( + "A project.yaml should not overwrite an existing project in a subnode! {}", + containedFile.getAbsolutePath() + ); + } + try { + gitProject = parseProjectFile(containedFile); + } catch (IOException e) { + LOGGER.error("Cannot parse project.yaml for " + containedFile.getAbsolutePath(), e); + } + } + } + for (File containedFiles : dir.listFiles()) { + if (containedFiles.isDirectory()) harvestedMetadata.addAll( + visitSubdirectories( + containedFiles, + harvester, + (StringUtils.isEmpty(relativePath) ? "" : (relativePath + "/")) + containedFiles.getName(), + gitProject + ) + ); + } + for (File containedFiles : dir.listFiles()) { + if (!containedFiles.isDirectory() && containedFiles.getName().equals("metaData.yaml")) { + harvestedMetadata.addAll(harvester.harvest(containedFiles, harvestedMetadata, relativePath, gitProject)); + return harvestedMetadata; + } + } + return harvestedMetadata; + } + + /** + * replaces existing metadata by new content + * + * @param content + * @param id + */ + public void updateMetadata(String content, int id) { + String elURL = elasticsearchClient.getLowLevelClient().getNodes().get(0).getHost().toURI(); + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + HttpEntity<String> request = new HttpEntity<String>(content, headers); + restTemplate.put(elURL + "/metadata/_doc/" + id, request, String.class); + } + + public String updateMetadata(SearchResultDTO testExercise, int id) throws JsonGenerationException, JsonMappingException, IOException { + String elURL = elasticsearchClient.getLowLevelClient().getNodes().get(0).getHost().toURI(); + // first fetch previous content + RestTemplate restTemplate = new RestTemplate(); + String previousContent = restTemplate.getForObject(elURL + "/metadata/_doc/" + id, String.class); + + ObjectMapper objectMapper = new ObjectMapper(); + final JavaTimeModule javaModule = new JavaTimeModule(); + + objectMapper.registerModule(javaModule); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + StringWriter sw = new StringWriter(); + objectMapper.writeValue(sw, testExercise); + final String contentString = sw.toString(); + updateMetadata(contentString, id); + + return previousContent; + } + + /** + * sets the content to a raw json string (containing "_source" attribute). Used + * to write back a changed value from updateMetadata(...). + * + * @param rawInput the json string + * @param id the id to write to + * @throws JsonGenerationException + * @throws JsonMappingException + * @throws IOException + */ + public void resetRawMetadata(String rawInput, int id) throws JsonGenerationException, JsonMappingException, IOException { + ObjectMapper objectMapper = new ObjectMapper(); + final JavaTimeModule javaModule = new JavaTimeModule(); + + objectMapper.registerModule(javaModule); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + final JsonNode tree = objectMapper.readTree(rawInput); + final JsonNode source = tree.at("/_source"); + StringWriter sw = new StringWriter(); + objectMapper.writeValue(sw, source); + final String contentString = sw.toString(); + updateMetadata(contentString, id); + } + + /** + * we have to wait until correct startup of content indexing? + * + * @param minExpectedHits + */ + private void waitForCleanStartUp(int minExpectedHits) { + RestHighLevelClient client = elasticsearchClient; + int tryCount = 0; + while (tryCount < 10) { + tryCount++; + SearchRequest searchRequest = new SearchRequest(SearchRepositoryConstants.INDEX_METADATA); + BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); + SearchSourceBuilder sourceBuilder = new SearchSourceBuilder(); + sourceBuilder.query(queryBuilder); + SearchResponse searchResponse; + try { + searchResponse = client.search(searchRequest, RequestOptions.DEFAULT); + if (searchResponse.getHits().getTotalHits().value >= minExpectedHits) { + LOGGER.info("Metadata index is up with {} hits after {} trials", searchResponse.getHits().getTotalHits(), tryCount); + return; + } else { + LOGGER.warn("Metadata index only {} hits up after {} trials", searchResponse.getHits().getTotalHits(), tryCount); + } + } catch (IOException e) { + LOGGER.warn("Metadata index startup exception", e); + } + try { + Thread.sleep(1000L); + } catch (InterruptedException e) { + LOGGER.debug("Never mind: {}", e.getMessage()); + } + } + } + + private String getMetaDataConfigDefinition() throws IOException { + InputStream metaDataStream = this.getClass().getResourceAsStream("../testData/es_metadata.schema.json"); + ByteSource byteSource = new ByteSource() { + @Override + public InputStream openStream() throws IOException { + return metaDataStream; + } + }; + String text = byteSource.asCharSource(StandardCharsets.UTF_8).read(); + return text; + } + + @EventListener + public void onApplicationEvent(ApplicationStartingEvent event) { + try { + startTestNode(); + } catch (IOException | NodeValidationException e) { + LOGGER.error("Cannot startup TestNode", e); + } + } + + @EventListener + public void onApplicationEvent(ContextStartedEvent event) { + try { + startTestNode(); + } catch (IOException | NodeValidationException e) { + LOGGER.error("Cannot startup TestNode", e); + } + } + + @EventListener + public void onApplicationEvent(ContextStoppedEvent event) { + try { + testNode.close(); + } catch (IOException e) { + LOGGER.error("Cannot startup TestNode", e); + } + } + + public static class TestESNode extends Node { + + public TestESNode(Settings preparedSettings, Collection<Class<? extends Plugin>> classpathPlugins) { + super( + InternalSettingsPreparer.prepareEnvironment(preparedSettings, new HashMap<String, String>(), null, null), + classpathPlugins, + true + ); + } + // @Override + // protected void registerDerivedNodeNameWithLogger(String nodeName) { + // LogManager.getLogger(nodeName); + // } + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/security/jwt/JWTFilterTest.java b/src/test/java/at/ac/uibk/gitsearch/security/jwt/JWTFilterTest.java index 1aa906cfdab240ca80fda2cd65e08f65212e788c..c0318eef7a1953452ad353c178c84134bef64765 100644 --- a/src/test/java/at/ac/uibk/gitsearch/security/jwt/JWTFilterTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/security/jwt/JWTFilterTest.java @@ -2,8 +2,12 @@ package at.ac.uibk.gitsearch.security.jwt; import static org.assertj.core.api.Assertions.assertThat; +import at.ac.uibk.gitsearch.management.SecurityMetersService; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import java.util.Collections; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.http.HttpStatus; @@ -14,12 +18,6 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.test.util.ReflectionTestUtils; - -import at.ac.uibk.gitsearch.management.SecurityMetersService; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import io.jsonwebtoken.io.Decoders; -import io.jsonwebtoken.security.Keys; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import tech.jhipster.config.JHipsterProperties; class JWTFilterTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/security/jwt/TokenProviderSecurityMetersTests.java b/src/test/java/at/ac/uibk/gitsearch/security/jwt/TokenProviderSecurityMetersTests.java index c047f2680b1cbc04963bc155e590b05bd1e2c139..479faeac9fddc46d272600cfaee39def0c006375 100644 --- a/src/test/java/at/ac/uibk/gitsearch/security/jwt/TokenProviderSecurityMetersTests.java +++ b/src/test/java/at/ac/uibk/gitsearch/security/jwt/TokenProviderSecurityMetersTests.java @@ -2,11 +2,19 @@ package at.ac.uibk.gitsearch.security.jwt; import static org.assertj.core.api.Assertions.assertThat; +import at.ac.uibk.gitsearch.management.SecurityMetersService; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import java.security.Key; import java.util.ArrayList; import java.util.Collection; import java.util.Date; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -14,16 +22,6 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.test.util.ReflectionTestUtils; - -import at.ac.uibk.gitsearch.management.SecurityMetersService; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.io.Decoders; -import io.jsonwebtoken.security.Keys; -import io.micrometer.core.instrument.Counter; -import io.micrometer.core.instrument.MeterRegistry; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import tech.jhipster.config.JHipsterProperties; class TokenProviderSecurityMetersTests { diff --git a/src/test/java/at/ac/uibk/gitsearch/security/jwt/TokenProviderTest.java b/src/test/java/at/ac/uibk/gitsearch/security/jwt/TokenProviderTest.java index b86c81fe8e1222da3a18154a845907c886ee45b9..60e2df0ae01ee729d059088d0b77e7736dbf4784 100644 --- a/src/test/java/at/ac/uibk/gitsearch/security/jwt/TokenProviderTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/security/jwt/TokenProviderTest.java @@ -2,12 +2,18 @@ package at.ac.uibk.gitsearch.security.jwt; import static org.assertj.core.api.Assertions.assertThat; +import at.ac.uibk.gitsearch.management.SecurityMetersService; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.SignatureAlgorithm; +import io.jsonwebtoken.io.Decoders; +import io.jsonwebtoken.security.Keys; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import java.nio.charset.StandardCharsets; import java.security.Key; import java.util.ArrayList; import java.util.Collection; import java.util.Date; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; @@ -15,14 +21,6 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.test.util.ReflectionTestUtils; - -import at.ac.uibk.gitsearch.management.SecurityMetersService; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import io.jsonwebtoken.Jwts; -import io.jsonwebtoken.SignatureAlgorithm; -import io.jsonwebtoken.io.Decoders; -import io.jsonwebtoken.security.Keys; -import io.micrometer.core.instrument.simple.SimpleMeterRegistry; import tech.jhipster.config.JHipsterProperties; class TokenProviderTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/security/oauth2/GitSearchOAuth2AuthorizationRequestRepositoryIT.java b/src/test/java/at/ac/uibk/gitsearch/security/oauth2/GitSearchOAuth2AuthorizationRequestRepositoryIT.java index 0bd455e35e17ee6ae9a57d88432872c0e0478e26..c0426c52797ce62de4a0500a0a9ed1da93a0c407 100644 --- a/src/test/java/at/ac/uibk/gitsearch/security/oauth2/GitSearchOAuth2AuthorizationRequestRepositoryIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/security/oauth2/GitSearchOAuth2AuthorizationRequestRepositoryIT.java @@ -1,5 +1,6 @@ package at.ac.uibk.gitsearch.security.oauth2; +import at.ac.uibk.gitsearch.GitsearchApp; import org.junit.Assert; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -9,38 +10,37 @@ import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.security.oauth2.core.endpoint.OAuth2AuthorizationRequest; import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames; -import at.ac.uibk.gitsearch.GitsearchApp; - @SpringBootTest(classes = GitsearchApp.class) public class GitSearchOAuth2AuthorizationRequestRepositoryIT { - private static final String TEST_STATE = "JustATestState"; - @Autowired - private GitSearchOAuth2AuthorizationRequestRepository requestRepository; - + private static final String TEST_STATE = "JustATestState"; + + @Autowired + private GitSearchOAuth2AuthorizationRequestRepository requestRepository; + @Test - public void testRepositorySimple() { - MockHttpServletRequest mockedRequest = new MockHttpServletRequest(); - mockedRequest.addParameter(OAuth2ParameterNames.STATE, TEST_STATE); - MockHttpServletResponse mockedResponse = new MockHttpServletResponse(); - - OAuth2AuthorizationRequest oauthRequest = - OAuth2AuthorizationRequest.authorizationCode().state(TEST_STATE) - .authorizationUri("http://unusedHere") - .clientId("someClientId") - .build(); - - requestRepository.saveAuthorizationRequest(oauthRequest, mockedRequest, mockedResponse); - - OAuth2AuthorizationRequest retrievedRequest = requestRepository.loadAuthorizationRequest(mockedRequest); - - Assert.assertEquals(oauthRequest, retrievedRequest); - - OAuth2AuthorizationRequest deletedRequest = requestRepository.removeAuthorizationRequest(mockedRequest); - - Assert.assertEquals(oauthRequest, deletedRequest); - - Assert.assertNull("it should be removed", requestRepository.removeAuthorizationRequest(mockedRequest)); - - } + public void testRepositorySimple() { + MockHttpServletRequest mockedRequest = new MockHttpServletRequest(); + mockedRequest.addParameter(OAuth2ParameterNames.STATE, TEST_STATE); + MockHttpServletResponse mockedResponse = new MockHttpServletResponse(); + + OAuth2AuthorizationRequest oauthRequest = OAuth2AuthorizationRequest + .authorizationCode() + .state(TEST_STATE) + .authorizationUri("http://unusedHere") + .clientId("someClientId") + .build(); + + requestRepository.saveAuthorizationRequest(oauthRequest, mockedRequest, mockedResponse); + + OAuth2AuthorizationRequest retrievedRequest = requestRepository.loadAuthorizationRequest(mockedRequest); + + Assert.assertEquals(oauthRequest, retrievedRequest); + + OAuth2AuthorizationRequest deletedRequest = requestRepository.removeAuthorizationRequest(mockedRequest); + + Assert.assertEquals(oauthRequest, deletedRequest); + + Assert.assertNull("it should be removed", requestRepository.removeAuthorizationRequest(mockedRequest)); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcherTest.java b/src/test/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcherTest.java index cecbd2858e3a899ab880292871a42b655040c905..cb718f49f20558160e6813554ee0b1965e1f4004 100644 --- a/src/test/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcherTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/security/oauth2/UserDetailsFetcherTest.java @@ -1,62 +1,59 @@ package at.ac.uibk.gitsearch.security.oauth2; +import com.google.common.collect.Lists; import java.util.List; - import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.jupiter.api.Test; -import com.google.common.collect.Lists; - class UserDetailsFetcherTest { @Test - void testNormalizationWithRealExample() { - UserDetailsFetcher udf = new UserDetailsFetcher(); - final List<String> realExample = Lists.newArrayList("sharing/university-innsbruck/c-exercises/eidp-21s", - "general1", - "sharing/graz-university-of-technology", - "internal", - "development", - "sharing/university-innsbruck/python/general", - "sharing/university-innsbruck/java", - "sharing/university-klagenfurt", - "sharing/university-salzburg", - "sharing/johannes-kepler-university-linz", - "sharing", - "sharing/danube-university-krems", - "development/sharing", - "sharing/university-innsbruck/python", - "sharing/vienna-university-of-technology", - "ROLE_USER", - "sharing/university-innsbruck/c-exercises", - "sharing/university-innsbruck/modelling", - "sharing/university-innsbruck", - "sharing/johannes-kepler-university-linz/java", - "ROLE_ADMIN", - "sharing/university-innsbruck/java/general"); - MatcherAssert.assertThat(udf.reduceGroups(realExample), Matchers.containsInAnyOrder( - "general1", - "internal", - "development", - "sharing", - "ROLE_USER", - "ROLE_ADMIN" - )); - } + void testNormalizationWithRealExample() { + UserDetailsFetcher udf = new UserDetailsFetcher(); + final List<String> realExample = Lists.newArrayList( + "sharing/university-innsbruck/c-exercises/eidp-21s", + "general1", + "sharing/graz-university-of-technology", + "internal", + "development", + "sharing/university-innsbruck/python/general", + "sharing/university-innsbruck/java", + "sharing/university-klagenfurt", + "sharing/university-salzburg", + "sharing/johannes-kepler-university-linz", + "sharing", + "sharing/danube-university-krems", + "development/sharing", + "sharing/university-innsbruck/python", + "sharing/vienna-university-of-technology", + "ROLE_USER", + "sharing/university-innsbruck/c-exercises", + "sharing/university-innsbruck/modelling", + "sharing/university-innsbruck", + "sharing/johannes-kepler-university-linz/java", + "ROLE_ADMIN", + "sharing/university-innsbruck/java/general" + ); + MatcherAssert.assertThat( + udf.reduceGroups(realExample), + Matchers.containsInAnyOrder("general1", "internal", "development", "sharing", "ROLE_USER", "ROLE_ADMIN") + ); + } @Test - void testNormalizationWithComplexExample() { - UserDetailsFetcher udf = new UserDetailsFetcher(); - final List<String> complexExample = Lists.newArrayList("sharing/university-innsbruck/c-exercises/eidp-21s", - "sharing", - "sharing/university-innsbruck", - "sharing/university-innsbruck/java/general", - "sharing2/university-innsbruck/java/general"); - MatcherAssert.assertThat(udf.reduceGroups(complexExample), Matchers.containsInAnyOrder( - "sharing", - "sharing2/university-innsbruck/java/general" - )); - } - + void testNormalizationWithComplexExample() { + UserDetailsFetcher udf = new UserDetailsFetcher(); + final List<String> complexExample = Lists.newArrayList( + "sharing/university-innsbruck/c-exercises/eidp-21s", + "sharing", + "sharing/university-innsbruck", + "sharing/university-innsbruck/java/general", + "sharing2/university-innsbruck/java/general" + ); + MatcherAssert.assertThat( + udf.reduceGroups(complexExample), + Matchers.containsInAnyOrder("sharing", "sharing2/university-innsbruck/java/general") + ); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/AchievementServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/AchievementServiceIT.java index be2edf807c73e85663c25c45c83448baeecd21da..bc1b610b2cab98371c4b43aea53ac17af3c22f6f 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/AchievementServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/AchievementServiceIT.java @@ -2,9 +2,11 @@ package at.ac.uibk.gitsearch.service; import static org.junit.Assert.assertEquals; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; import java.io.IOException; import java.util.concurrent.TimeUnit; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.elasticsearch.client.RestHighLevelClient; @@ -17,72 +19,67 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.test.context.support.WithMockUser; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; - @SpringBootTest(classes = GitsearchApp.class) @WithMockUser(value = "test", authorities = "sharing") public class AchievementServiceIT { - @SuppressWarnings("unused") - private static final Logger LOGGER = LogManager.getLogger(AchievementServiceIT.class); - - @Autowired - RestHighLevelClient elasticsearchTestClient; - - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } - - @BeforeEach - public void setUpIndex() { - } - - @Autowired - AchievementService achievementService; - - @Autowired - SearchService searchService; - - @Autowired - private StatisticsService statisticsService; - - @Test - public void testSearchUserStatisticsEmpty() throws IOException { - final StatisticsDTO result = achievementService.searchUserStatistics(" "); - assertEquals(Integer.valueOf(0), result.getDownloads()); - assertEquals(Integer.valueOf(0), result.getViews()); - } - - @Test - public void testSearchUserStatisticsValid() throws IOException { - - StatisticsDTO newStats = new StatisticsDTO(); - newStats.setDownloads(1); - newStats.setViews(1); - newStats.setExerciseID("143"); - statisticsService.save(newStats); - - final StatisticsDTO result = achievementService.searchUserStatistics("stefan.podlipnig@tuwien.ac.at"); - assertEquals(Integer.valueOf(1), result.getDownloads()); - assertEquals(Integer.valueOf(1), result.getViews()); - } + + @SuppressWarnings("unused") + private static final Logger LOGGER = LogManager.getLogger(AchievementServiceIT.class); + + @Autowired + RestHighLevelClient elasticsearchTestClient; + + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } + + @BeforeEach + public void setUpIndex() {} + + @Autowired + AchievementService achievementService; + + @Autowired + SearchService searchService; + + @Autowired + private StatisticsService statisticsService; + + @Test + public void testSearchUserStatisticsEmpty() throws IOException { + final StatisticsDTO result = achievementService.searchUserStatistics(" "); + assertEquals(Integer.valueOf(0), result.getDownloads()); + assertEquals(Integer.valueOf(0), result.getViews()); + } + + @Test + public void testSearchUserStatisticsValid() throws IOException { + StatisticsDTO newStats = new StatisticsDTO(); + newStats.setDownloads(1); + newStats.setViews(1); + newStats.setExerciseID("143"); + statisticsService.save(newStats); + + final StatisticsDTO result = achievementService.searchUserStatistics("stefan.podlipnig@tuwien.ac.at"); + assertEquals(Integer.valueOf(1), result.getDownloads()); + assertEquals(Integer.valueOf(1), result.getViews()); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/AuditEventServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/AuditEventServiceIT.java index fb7c37f6fcbd8fb5575a844d1759284daa3fb99b..ced22109ff4073583a2be87a38a1b2846c335934 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/AuditEventServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/AuditEventServiceIT.java @@ -1,18 +1,18 @@ package at.ac.uibk.gitsearch.service; +import static org.assertj.core.api.Assertions.assertThat; + +import at.ac.uibk.gitsearch.GitsearchApp; import at.ac.uibk.gitsearch.domain.PersistentAuditEvent; import at.ac.uibk.gitsearch.repository.PersistenceAuditEventRepository; -import at.ac.uibk.gitsearch.GitsearchApp; -import tech.jhipster.config.JHipsterProperties; +import java.time.Instant; +import java.time.temporal.ChronoUnit; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; -import java.time.Instant; -import java.time.temporal.ChronoUnit; - -import static org.assertj.core.api.Assertions.assertThat; +import tech.jhipster.config.JHipsterProperties; /** * Integration tests for {@link AuditEventService}. @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; @SpringBootTest(classes = GitsearchApp.class) @Transactional public class AuditEventServiceIT { + @Autowired private AuditEventService auditEventService; @@ -43,7 +44,9 @@ public class AuditEventServiceIT { auditEventOld.setAuditEventType("test-type"); auditEventWithinRetention = new PersistentAuditEvent(); - auditEventWithinRetention.setAuditEventDate(Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod() - 1, ChronoUnit.DAYS)); + auditEventWithinRetention.setAuditEventDate( + Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod() - 1, ChronoUnit.DAYS) + ); auditEventWithinRetention.setPrincipal("test-user-retention"); auditEventWithinRetention.setAuditEventType("test-type"); diff --git a/src/test/java/at/ac/uibk/gitsearch/service/EditorialPagesServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/EditorialPagesServiceIT.java index ae80b5a04bfef3158c1db82cd5ab6d798e58d763..0c2b89734c5d0ddb3c0b61d7465db08b7a292b8b 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/EditorialPagesServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/EditorialPagesServiceIT.java @@ -4,6 +4,8 @@ import static org.hamcrest.Matchers.emptyOrNullString; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; import org.gitlab4j.api.GitLabApiException; import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.Test; @@ -11,9 +13,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; - /** * Integration tests for {@link UserWatchListService}. */ @@ -21,14 +20,12 @@ import at.ac.uibk.gitsearch.service.dto.EditorialPageDTO; @Transactional public class EditorialPagesServiceIT { - @Autowired private EditorialPagesService editorialPagesService; @Test public void testSimplePage() throws GitLabApiException { - EditorialPageDTO page = editorialPagesService.getContent("/de/start"); - MatcherAssert.assertThat(page.getContent(), not(is(emptyOrNullString()))); + EditorialPageDTO page = editorialPagesService.getContent("/de/start"); + MatcherAssert.assertThat(page.getContent(), not(is(emptyOrNullString()))); } - - } +} diff --git a/src/test/java/at/ac/uibk/gitsearch/service/ExerciseServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/ExerciseServiceIT.java index 318b96c1e6057c74bf941b363928fdcfb8b8f2d1..395af0a2c414d2f9be0c7104e9a49aa055e67c39 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/ExerciseServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/ExerciseServiceIT.java @@ -5,6 +5,8 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.es.model.ArtemisExerciseInfo; import java.io.File; import java.io.FileWriter; import java.io.IOException; @@ -12,7 +14,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.util.ArrayList; import java.util.List; - import org.apache.commons.io.FileUtils; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.storage.file.FileRepositoryBuilder; @@ -30,9 +31,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.es.model.ArtemisExerciseInfo; - @SpringBootTest(classes = GitsearchApp.class) @RunWith(SpringJUnit4ClassRunner.class) @WithMockUser(value = "test", authorities = "sharing") @@ -97,9 +95,10 @@ public class ExerciseServiceIT { exerciseService.applyExerciseInfoChanges(artemisExerciseInfo, token); - Assert.assertEquals("learningResourceType: \"Artemis\"\n" + "license: \"testLicense\"\n" - + "metadataVersion: \"1\"\n" + "title: \"TestTitle\"", - new String(Files.readAllBytes(metadata.toPath())).strip()); + Assert.assertEquals( + "learningResourceType: \"Artemis\"\n" + "license: \"testLicense\"\n" + "metadataVersion: \"1\"\n" + "title: \"TestTitle\"", + new String(Files.readAllBytes(metadata.toPath())).strip() + ); } @Test @@ -108,11 +107,22 @@ public class ExerciseServiceIT { metadata.getParentFile().mkdirs(); metadata.createNewFile(); FileWriter writer = new FileWriter(metadata, StandardCharsets.UTF_8); - writer.write("{\n" + " \"metadataVersion\": \"1\",\n" + " \"type\": \"programming exercise\",\n" - + " \"title\": \"TestTitle\",\n" + " \"license\": \"testLicense\",\n" + " \"maxPoints\": 100,\n" - + " \"bonusPoints\": 100,\n" + " \"mode\": \"INDIVIDUAL\",\n" + " \"staticCodeAnalysis\": false,\n" - + " \"allowOfflineIDE\": false,\n" + " \"allowOnlineEditor\": false,\n" - + " \"showTestNamesToStudents\": false,\n" + " \"sequentialTestRuns\": false\n" + "}"); + writer.write( + "{\n" + + " \"metadataVersion\": \"1\",\n" + + " \"type\": \"programming exercise\",\n" + + " \"title\": \"TestTitle\",\n" + + " \"license\": \"testLicense\",\n" + + " \"maxPoints\": 100,\n" + + " \"bonusPoints\": 100,\n" + + " \"mode\": \"INDIVIDUAL\",\n" + + " \"staticCodeAnalysis\": false,\n" + + " \"allowOfflineIDE\": false,\n" + + " \"allowOnlineEditor\": false,\n" + + " \"showTestNamesToStudents\": false,\n" + + " \"sequentialTestRuns\": false\n" + + "}" + ); writer.close(); artemisExerciseInfo.setMaxPoints(100f); @@ -128,7 +138,6 @@ public class ExerciseServiceIT { List<String> str = new ArrayList<>(); str.add("artemis"); - artemisExerciseInfo.setFormat(str); Assert.assertEquals(artemisExerciseInfo, exerciseService.getArtemisExerciseInfo(token)); @@ -140,8 +149,14 @@ public class ExerciseServiceIT { metadata.getParentFile().mkdirs(); metadata.createNewFile(); FileWriter writer = new FileWriter(metadata, StandardCharsets.UTF_8); - writer.write("{\n" + " \"metadataVersion\": \"1\",\n" + " \"type\": \"programming exercise\",\n" - + " \"title\": \"TestTitle\",\n" + " \"license\": \"testLicense\"\n" + "}"); + writer.write( + "{\n" + + " \"metadataVersion\": \"1\",\n" + + " \"type\": \"programming exercise\",\n" + + " \"title\": \"TestTitle\",\n" + + " \"license\": \"testLicense\"\n" + + "}" + ); writer.close(); artemisExerciseInfo.setLearningResourceType(null); @@ -149,7 +164,6 @@ public class ExerciseServiceIT { List<String> str = new ArrayList<>(); str.add("artemis"); - artemisExerciseInfo.setFormat(str); Assert.assertEquals(artemisExerciseInfo, exerciseService.getArtemisExerciseInfo(token)); @@ -162,6 +176,5 @@ public class ExerciseServiceIT { Assert.assertTrue(exerciseService.validate(testApiKeyCorrect)); Assert.assertFalse(exerciseService.validate(testApiKeyIncorrect)); - } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/GitLabServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/GitLabServiceIT.java index 2677d38e293fa68caa851c57ab44b19ea644d061..3091b193ecf1f39fd1d03f724bd61894f621f1a6 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/GitLabServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/GitLabServiceIT.java @@ -1,11 +1,11 @@ package at.ac.uibk.gitsearch.service; - +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; - import org.codeability.sharing.plugins.api.search.util.ExerciseId; import org.elasticsearch.node.NodeValidationException; import org.gitlab4j.api.GitLabApiException; @@ -19,62 +19,59 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.util.StreamUtils; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; - @SpringBootTest(classes = GitsearchApp.class) @WithMockUser(value = "test", authorities = "sharing") public class GitLabServiceIT { - - @Autowired - GitlabService gitlabService; - final String publicGitLabProjectId = "318"; - - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } + @Autowired + GitlabService gitlabService; + + final String publicGitLabProjectId = "318"; + + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } + + @Test + public void testGitLabAccess() { + Assert.assertTrue(gitlabService.repositoryExists(publicGitLabProjectId)); + Assert.assertFalse(gitlabService.repositoryExists("XXXX--keineId--XXX")); + } + + @Test + public void testGitLabDownload() throws GitLabApiException, IOException { + final InputStream repositoryZip = gitlabService.getRepositoryZip(publicGitLabProjectId); + // schwacher Test :-( + Assert.assertNotNull(repositoryZip); + } + + @Test + public void getREADMEmd() throws GitLabApiException, IOException { + final InputStream repositoryFile = gitlabService.getRepositoryFile(new ExerciseId("318", null), "README.md"); + Assert.assertNotNull(repositoryFile); - @Test - public void testGitLabAccess( ) { - Assert.assertTrue(gitlabService.repositoryExists(publicGitLabProjectId)); - Assert.assertFalse(gitlabService.repositoryExists("XXXX--keineId--XXX")); - } + ByteArrayOutputStream baos = new ByteArrayOutputStream(); - @Test - public void testGitLabDownload( ) throws GitLabApiException, IOException { - final InputStream repositoryZip = gitlabService.getRepositoryZip(publicGitLabProjectId); - // schwacher Test :-( - Assert.assertNotNull(repositoryZip); - } - - @Test - public void getREADMEmd() throws GitLabApiException, IOException { - final InputStream repositoryFile = gitlabService.getRepositoryFile(new ExerciseId("318", null), "README.md"); - Assert.assertNotNull(repositoryFile); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - - StreamUtils.copy(repositoryFile, baos); - - Assert.assertTrue("At least 50 characters?", baos.size() > 50); - } + StreamUtils.copy(repositoryFile, baos); + Assert.assertTrue("At least 50 characters?", baos.size() > 50); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/InfoMailServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/InfoMailServiceIT.java index 9bf71d166693f6ba8c2a0d84b5a3e1772e3fe596..4619b233bcd38b185ddcaaa635e1db6ad00aa43f 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/InfoMailServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/InfoMailServiceIT.java @@ -6,6 +6,18 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.domain.UserWatchList; +import at.ac.uibk.gitsearch.domain.WatchListEntry; +import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; +import at.ac.uibk.gitsearch.repository.UserRepository; +import at.ac.uibk.gitsearch.repository.UserWatchListRepository; +import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.databind.JsonMappingException; import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; @@ -13,9 +25,7 @@ import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; - import javax.mail.internet.MimeMessage; - import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.elasticsearch.node.NodeValidationException; import org.junit.jupiter.api.AfterAll; @@ -35,20 +45,6 @@ import org.springframework.data.auditing.DateTimeProvider; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.transaction.annotation.Transactional; import org.thymeleaf.spring5.SpringTemplateEngine; - -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.databind.JsonMappingException; - -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.domain.UserWatchList; -import at.ac.uibk.gitsearch.domain.WatchListEntry; -import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; -import at.ac.uibk.gitsearch.repository.UserRepository; -import at.ac.uibk.gitsearch.repository.UserWatchListRepository; -import at.ac.uibk.gitsearch.repository.search.MetaDataRepository; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; import tech.jhipster.config.JHipsterProperties; /** @@ -58,152 +54,153 @@ import tech.jhipster.config.JHipsterProperties; @Transactional public class InfoMailServiceIT { - private static final String DEFAULT_LOGIN = "TestUser1"; + private static final String DEFAULT_LOGIN = "TestUser1"; + + private static final String DEFAULT_EMAIL = "TestUser1@localhost"; + + private static final String DEFAULT_FIRSTNAME = "Test"; + + private static final String DEFAULT_LASTNAME = "User1"; + + private static final String DEFAULT_IMAGEURL = "http://placehold.it/50x50"; + + private static final String DEFAULT_LANGKEY = "en"; + + private static final String TEST_EXERCISE_ID = "1"; + + @Autowired + private JHipsterProperties jHipsterProperties; + + @Autowired + private MessageSource messageSource; - private static final String DEFAULT_EMAIL = "TestUser1@localhost"; + @Autowired + private SpringTemplateEngine templateEngine; - private static final String DEFAULT_FIRSTNAME = "Test"; + @Autowired + private UserRepository userRepository; - private static final String DEFAULT_LASTNAME = "User1"; + @Autowired + private UserService userService; - private static final String DEFAULT_IMAGEURL = "http://placehold.it/50x50"; + @Autowired + private UserWatchListService userWatchListService; - private static final String DEFAULT_LANGKEY = "en"; + @Autowired + private UserWatchListRepository userWatchListRepository; - private static final String TEST_EXERCISE_ID = "1"; + @Autowired + private MetaDataRepository metaDataRepository; - @Autowired - private JHipsterProperties jHipsterProperties; + @Spy + private JavaMailSenderImpl javaMailSender; - @Autowired - private MessageSource messageSource; + @Captor + private ArgumentCaptor<MimeMessage> messageCaptor; - @Autowired - private SpringTemplateEngine templateEngine; + private MailService mailService; - @Autowired - private UserRepository userRepository; - @Autowired - private UserService userService; + @Mock + private DateTimeProvider dateTimeProvider; - @Autowired - private UserWatchListService userWatchListService; - @Autowired - private UserWatchListRepository userWatchListRepository; - @Autowired - private MetaDataRepository metaDataRepository; + private User user; - @Spy - private JavaMailSenderImpl javaMailSender; + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; - @Captor - private ArgumentCaptor<MimeMessage> messageCaptor; + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - private MailService mailService; - @Mock - private DateTimeProvider dateTimeProvider; + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } - private User user; + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + @BeforeEach + public void init() { + AdminUserDTO userDTO = new AdminUserDTO(); + userDTO.setLogin(DEFAULT_LOGIN); - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } + userDTO.setActivated(true); + userDTO.setEmail(DEFAULT_EMAIL); + userDTO.setFirstName(DEFAULT_FIRSTNAME); + userDTO.setLastName(DEFAULT_LASTNAME); + userDTO.setImageUrl(DEFAULT_IMAGEURL); + userDTO.setLangKey(DEFAULT_LANGKEY); + userDTO.setAuthorities(new HashSet<>()); + userDTO.getAuthorities().add("sharing"); - @BeforeEach - public void init() { - AdminUserDTO userDTO = new AdminUserDTO(); - userDTO.setLogin(DEFAULT_LOGIN); + when(dateTimeProvider.getNow()).thenReturn(Optional.of(LocalDateTime.now())); - userDTO.setActivated(true); - userDTO.setEmail(DEFAULT_EMAIL); - userDTO.setFirstName(DEFAULT_FIRSTNAME); - userDTO.setLastName(DEFAULT_LASTNAME); - userDTO.setImageUrl(DEFAULT_IMAGEURL); - userDTO.setLangKey(DEFAULT_LANGKEY); - userDTO.setAuthorities(new HashSet<>()); - userDTO.getAuthorities().add("sharing"); + userDTO.setActivated(false); + user = userService.createUser(userDTO); - when(dateTimeProvider.getNow()).thenReturn(Optional.of(LocalDateTime.now())); + UserWatchList wlDAILY = new UserWatchList("someTestWatchList", CheckFrequency.DAILY, user); - userDTO.setActivated(false); - user = userService.createUser(userDTO); + WatchListEntry wle1 = new WatchListEntry(); + wle1.setExerciseId(TEST_EXERCISE_ID); + wle1.setExerciseName("Unused in this test"); + wlDAILY.getWatchListEntries().add(wle1); - UserWatchList wlDAILY = new UserWatchList("someTestWatchList", CheckFrequency.DAILY, user); + userWatchListRepository.save(wlDAILY); - WatchListEntry wle1 = new WatchListEntry(); - wle1.setExerciseId(TEST_EXERCISE_ID); - wle1.setExerciseName("Unused in this test"); - wlDAILY.getWatchListEntries().add(wle1); + UserWatchList wlMONTHLY = new UserWatchList("someTestWatchList", CheckFrequency.MONTHLY, user); - userWatchListRepository.save(wlDAILY); + WatchListEntry wle2 = new WatchListEntry(); + wle2.setExerciseId(TEST_EXERCISE_ID); + wle2.setExerciseName("Unused in this test"); + wlMONTHLY.getWatchListEntries().add(wle2); - UserWatchList wlMONTHLY = new UserWatchList("someTestWatchList", CheckFrequency.MONTHLY, user); + userWatchListRepository.save(wlMONTHLY); + } - WatchListEntry wle2 = new WatchListEntry(); - wle2.setExerciseId(TEST_EXERCISE_ID); - wle2.setExerciseName("Unused in this test"); - wlMONTHLY.getWatchListEntries().add(wle2); + @BeforeEach + public void setup() { + MockitoAnnotations.openMocks(this); + doNothing().when(javaMailSender).send(any(MimeMessage.class)); + mailService = + new MailService(jHipsterProperties, javaMailSender, messageSource, templateEngine, userRepository, userWatchListService); + } - userWatchListRepository.save(wlMONTHLY); + private String original = null; - } + @BeforeEach + public void setUpChangedExercise() throws JsonGenerationException, JsonMappingException, IOException { + final SearchResultDTO testExercise = metaDataRepository.getExerciseById(TEST_EXERCISE_ID, Optional.empty()); - @BeforeEach - public void setup() { - MockitoAnnotations.openMocks(this); - doNothing().when(javaMailSender).send(any(MimeMessage.class)); - mailService = new MailService(jHipsterProperties, javaMailSender, messageSource, templateEngine, userRepository, - userWatchListService); - } - - private String original = null; - - @BeforeEach - public void setUpChangedExercise() throws JsonGenerationException, JsonMappingException, IOException { - final SearchResultDTO testExercise = metaDataRepository.getExerciseById(TEST_EXERCISE_ID, Optional.empty()); - - testExercise.getProject().setLast_activity_at(Instant.now()); - - original = elasticSearchTestConfiguration.updateMetadata(testExercise, 3); - } - - @Test - @Transactional - public void testSendInfoMail() throws Exception { - - mailService.sendInfoMails(); - verify(javaMailSender).send(messageCaptor.capture()); - List<MimeMessage> messages = messageCaptor.getAllValues(); - assertThat(messages.size()).isEqualTo(1); - - MimeMessage message = messages.get(0); - assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail()); - assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom()); - assertThat(message.getContent().toString()).isNotEmpty(); - assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8"); - } - - @AfterEach - public void resetChangedExercise() throws JsonGenerationException, JsonMappingException, IOException { - elasticSearchTestConfiguration.resetRawMetadata(original, 3); - } - -} \ No newline at end of file + testExercise.getProject().setLast_activity_at(Instant.now()); + + original = elasticSearchTestConfiguration.updateMetadata(testExercise, 3); + } + + @Test + @Transactional + public void testSendInfoMail() throws Exception { + mailService.sendInfoMails(); + verify(javaMailSender).send(messageCaptor.capture()); + List<MimeMessage> messages = messageCaptor.getAllValues(); + assertThat(messages.size()).isEqualTo(1); + + MimeMessage message = messages.get(0); + assertThat(message.getAllRecipients()[0].toString()).isEqualTo(user.getEmail()); + assertThat(message.getFrom()[0].toString()).isEqualTo(jHipsterProperties.getMail().getFrom()); + assertThat(message.getContent().toString()).isNotEmpty(); + assertThat(message.getDataHandler().getContentType()).isEqualTo("text/html;charset=UTF-8"); + } + + @AfterEach + public void resetChangedExercise() throws JsonGenerationException, JsonMappingException, IOException { + elasticSearchTestConfiguration.resetRawMetadata(original, 3); + } +} diff --git a/src/test/java/at/ac/uibk/gitsearch/service/MailServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/MailServiceIT.java index ef39421c7d0d5b4ea6a6d253eb429cdb88bf160a..2f1ca6fd68aa300b45cd9a53a0342e2de76a9c1f 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/MailServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/MailServiceIT.java @@ -8,7 +8,6 @@ import at.ac.uibk.gitsearch.IntegrationTest; import at.ac.uibk.gitsearch.config.Constants; import at.ac.uibk.gitsearch.domain.User; import at.ac.uibk.gitsearch.repository.UserRepository; - import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; @@ -58,7 +57,7 @@ class MailServiceIT { @Autowired private SpringTemplateEngine templateEngine; - + @Autowired private UserRepository userRepository; @@ -73,12 +72,12 @@ class MailServiceIT { private MailService mailService; - @BeforeEach public void setup() { MockitoAnnotations.openMocks(this); doNothing().when(javaMailSender).send(any(MimeMessage.class)); - mailService = new MailService(jHipsterProperties, javaMailSender, messageSource, templateEngine, userRepository, userWatchListService); + mailService = + new MailService(jHipsterProperties, javaMailSender, messageSource, templateEngine, userRepository, userWatchListService); } @Test diff --git a/src/test/java/at/ac/uibk/gitsearch/service/MessageServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/MessageServiceIT.java index edf2c989c35cc0ab8bc61bcd0658a509ba992672..244577c6daac1f85bfbf212fe1bba9b044d7d85a 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/MessageServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/MessageServiceIT.java @@ -1,7 +1,10 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; import java.io.IOException; - import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Assert; @@ -9,31 +12,22 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; - -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; - @SpringBootTest(classes = GitsearchApp.class) public class MessageServiceIT { - - @Autowired - MessageService messageService; - - @Test - public void loadMessages() throws JsonParseException, JsonMappingException, IOException { - - BroadCastMessageDTO[] messages = messageService.getMessages(); - if(messages==null) { - // give it more time (or trigger reload) - messageService.triggerReload(); - messages = messageService.getMessages(); - } - - Assert.assertNotNull("This may fail, due to timing problems", messages); - MatcherAssert.assertThat("This may fail, if there are no messages in gitlab", messages, Matchers.arrayWithSize(2)); - } - + @Autowired + MessageService messageService; + + @Test + public void loadMessages() throws JsonParseException, JsonMappingException, IOException { + BroadCastMessageDTO[] messages = messageService.getMessages(); + if (messages == null) { + // give it more time (or trigger reload) + messageService.triggerReload(); + messages = messageService.getMessages(); + } + + Assert.assertNotNull("This may fail, due to timing problems", messages); + MatcherAssert.assertThat("This may fail, if there are no messages in gitlab", messages, Matchers.arrayWithSize(2)); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/PluginManagerActionIT.java b/src/test/java/at/ac/uibk/gitsearch/service/PluginManagerActionIT.java index ad5e50db8768aee0f8a7744e74b3a2514fbf7b55..e1db0d12427dee98c8ca1ea5dcb45acd30f8c9de 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/PluginManagerActionIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/PluginManagerActionIT.java @@ -1,8 +1,14 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper; +import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper.ActionWrapper; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; import java.io.IOException; import java.io.InputStream; - import org.codeability.sharing.plugins.api.SharingPluginConfig; import org.codeability.sharing.plugins.api.SharingPluginConfig.Action; import org.codeability.sharing.plugins.api.search.SearchResultDTO; @@ -15,69 +21,58 @@ import org.slf4j.LoggerFactory; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.util.FileCopyUtils; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; - -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper; -import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper.ActionWrapper; - @SpringBootTest(classes = GitsearchApp.class) public class PluginManagerActionIT { - private final Logger log = LoggerFactory.getLogger(PluginManagerActionIT.class); - private ConnectorConfigWrapper config; - - @BeforeEach - public void initConfig() { - config = new ConnectorConfigWrapper( - new SharingPluginConfig("TestPlugin", new Action[] { new Action("someId", "someImportURL", - "someActionName", "metadata.learningResourceType=='programming exercise'") }), - "http://localhost:8080/xxx"); - } - - @Test - public void testExpressionFiltersOnMetaData() throws JsonParseException, JsonMappingException, IOException { - - ActionWrapper actionWrapper = config.getActions().get("someId"); - - Assert.assertTrue("metaData 1 should be applicable", - actionWrapper.isApplicable(readTestResults("metaData/1/metaData.yaml"))); - Assert.assertTrue("metaData 272 should be applicable", - actionWrapper.isApplicable(readTestResults("metaData/272/metaData.yaml"))); - Assert.assertFalse("metaData 2 should not be applicable", - actionWrapper.isApplicable(readTestResults("metaData/2/metaData.yaml"))); - - } - - /** - * temporary static test data. - * - * @param infoString just a string to add to testdata description. - * @return - * @throws IOException - * @throws JsonMappingException - * @throws JsonParseException - */ - private SearchResultDTO readTestResults(String testFile) - throws JsonParseException, JsonMappingException, IOException { - ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); - mapper.findAndRegisterModules(); - - log.debug("reading test data from {} ", testFile); - - final String resourceName = "./testData/" + testFile; - final InputStream resourceStream = this.getClass().getResourceAsStream(resourceName); - Assert.assertNotNull("cannot find resource at " + resourceName, resourceStream); - - byte[] fileContent = FileCopyUtils.copyToByteArray(resourceStream); - UserProvidedMetadataDTO metaData = mapper.readValue(fileContent, UserProvidedMetadataDTO.class); - SearchResultDTO result = new SearchResultDTO(); - result.setMetadata(metaData); - return result; - - } - + private final Logger log = LoggerFactory.getLogger(PluginManagerActionIT.class); + private ConnectorConfigWrapper config; + + @BeforeEach + public void initConfig() { + config = + new ConnectorConfigWrapper( + new SharingPluginConfig( + "TestPlugin", + new Action[] { + new Action("someId", "someImportURL", "someActionName", "metadata.learningResourceType=='programming exercise'"), + } + ), + "http://localhost:8080/xxx" + ); + } + + @Test + public void testExpressionFiltersOnMetaData() throws JsonParseException, JsonMappingException, IOException { + ActionWrapper actionWrapper = config.getActions().get("someId"); + + Assert.assertTrue("metaData 1 should be applicable", actionWrapper.isApplicable(readTestResults("metaData/1/metaData.yaml"))); + Assert.assertTrue("metaData 272 should be applicable", actionWrapper.isApplicable(readTestResults("metaData/272/metaData.yaml"))); + Assert.assertFalse("metaData 2 should not be applicable", actionWrapper.isApplicable(readTestResults("metaData/2/metaData.yaml"))); + } + + /** + * temporary static test data. + * + * @param infoString just a string to add to testdata description. + * @return + * @throws IOException + * @throws JsonMappingException + * @throws JsonParseException + */ + private SearchResultDTO readTestResults(String testFile) throws JsonParseException, JsonMappingException, IOException { + ObjectMapper mapper = new ObjectMapper(new YAMLFactory()); + mapper.findAndRegisterModules(); + + log.debug("reading test data from {} ", testFile); + + final String resourceName = "./testData/" + testFile; + final InputStream resourceStream = this.getClass().getResourceAsStream(resourceName); + Assert.assertNotNull("cannot find resource at " + resourceName, resourceStream); + + byte[] fileContent = FileCopyUtils.copyToByteArray(resourceStream); + UserProvidedMetadataDTO metaData = mapper.readValue(fileContent, UserProvidedMetadataDTO.class); + SearchResultDTO result = new SearchResultDTO(); + result.setMetadata(metaData); + return result; + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/SearchServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/SearchServiceIT.java index b4922a978693aba0a3cc3bf573ea42653a88cbb5..80bda04744348cb3403380ecfd661d80e9b5ce2b 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/SearchServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/SearchServiceIT.java @@ -17,6 +17,11 @@ import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import at.ac.uibk.gitsearch.IntegrationTest; +import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper; +import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; import java.io.ByteArrayInputStream; import java.io.IOException; import java.util.ArrayList; @@ -24,9 +29,7 @@ import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; - import javax.ws.rs.NotFoundException; - import org.codeability.sharing.plugins.api.SharingPluginConfig; import org.codeability.sharing.plugins.api.search.SearchInputDTO; import org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO; @@ -51,21 +54,15 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.security.test.context.support.WithMockUser; -import at.ac.uibk.gitsearch.IntegrationTest; -import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.service.PluginManagementService.ConnectorConfigWrapper; -import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; - @IntegrationTest @WithMockUser(value = "test", authorities = "sharing") public class SearchServiceIT { - @Autowired - RestHighLevelClient searchClient; + @Autowired + RestHighLevelClient searchClient; - @MockBean - PluginManagementService pluginManagementService; + @MockBean + PluginManagementService pluginManagementService; @MockBean GitLabRepository gitLabRepository; @@ -73,262 +70,309 @@ public class SearchServiceIT { @MockBean RepositoryApi mockedRepositoryApi; - private static final Logger LOGGER = LoggerFactory.getLogger(SearchServiceIT.class); - - @Autowired - private SearchService searchService; - - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } - - @BeforeEach - public void initMock() { + private static final Logger LOGGER = LoggerFactory.getLogger(SearchServiceIT.class); + + @Autowired + private SearchService searchService; + + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } + + @BeforeEach + public void initMock() { Collection<ConnectorConfigWrapper> mockConfigs = new ArrayList<>(); - mockConfigs.add(new ConnectorConfigWrapper(new SharingPluginConfig("mockedPlugin", new SharingPluginConfig.Action[] { - new SharingPluginConfig.Action("mockedAction", "http://unused/unused-transferURL", "mocked Action", "true") - }), "http://unused/hopefully-unused")); - - mockConfigs.add(new ConnectorConfigWrapper(new SharingPluginConfig("Artemis Sharing Connector", new SharingPluginConfig.Action[] { - new SharingPluginConfig.Action("Import", "http://unused/unused-transferURL", "Export to Artemis", "true") - }), "http://unused/hopefully-unused")); - - when(pluginManagementService.getRegisteredPluginConfigs()).thenReturn(mockConfigs); - } - - @Test - public void testAllSearch() throws Exception { - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null,null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - Assert.assertTrue("At least one hit?", searchResultPage.getSearchResult().size() >= 1); - Assert.assertEquals("We start at 0", 0, searchResultPage.getPageStartIndex()); - LOGGER.info("found {} hits for all", searchResultPage.getHitCount()); - } - - @Test - public void testFullTextSearch() throws Exception { - LOGGER.info("starting testFullTextSearch"); - final String WIEN = "Wien"; - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null,null); - SearchInputDTO searchQuery = new SearchInputDTO(WIEN, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); - org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); - MatcherAssert.assertThat(searchResultPage.getSearchResult(), - everyItem(anyOf(hasProperty("metadata", hasProperty("description", containsString(WIEN))), - hasProperty("metadata", hasProperty("title", containsString(WIEN))) - // hasProperty("keywords", containsString("Wien")) - ))); - - LOGGER.info("exiting testFullTextSearch"); - } - - @Test - public void testSearchByAutor() throws Exception { - final String PODLIPNIG = "Stefan Podlipnig"; - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, PODLIPNIG, null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); - org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); - MatcherAssert.assertThat(searchResultPage.getSearchResult(), everyItem( - hasProperty("metadata", hasProperty("creator", hasItemInArray(hasProperty("name", containsString(PODLIPNIG))))))); - - } - - @Test - @Disabled("Ich brings nicht zum laufen :-(") - public void testProgrammingLanguageSearch() throws Exception { - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO("Java", null, null, null, null,null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - assertNotNull(searchResultPage.getSearchResult()); - assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); - MatcherAssert.assertThat(searchResultPage.getSearchResult(), everyItem( - hasProperty("metadata", hasProperty("programmingLanguage", hasItemInArray(containsStringIgnoringCase("Java")))))); - - } - - @Test - public void testCreatorSearch() throws IOException { - - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, "Podlipnig",null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); - org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); - MatcherAssert.assertThat(searchResultPage.getSearchResult(), everyItem(hasProperty("metadata", - hasProperty("creator", hasItemInArray(hasProperty("name", containsString("Podlipnig"))))))); - - } - - @Test - public void testKeywordSearch() throws IOException { - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "latex", null, null, null,null); - org.codeability.sharing.plugins.api.search.SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); - org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); - MatcherAssert.assertThat(searchResultPage.getSearchResult(), - everyItem(hasProperty("metadata", hasProperty("keyword", hasItemInArray(containsString("latex")))))); - - } - - @Test - public void testFormatSearch() throws IOException { - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null,"latex"); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); - org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); - MatcherAssert.assertThat(searchResultPage.getSearchResult(), - everyItem(hasProperty("metadata", hasProperty("format", hasItemInArray(containsString("latex")))))); - - } - - // does not work with metadata version 0.4 -// @Test -// public void testTypesSearch() throws IOException { -// final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "latex", null, null, null,null); -// searchMetadata.setTypes(Collections.singletonList(ExerciseType.COLLECTION)); -// SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); -// SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); -// -// org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); -// org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); -// assertThat(searchResultPage.getSearchResult(), -// everyItem(hasProperty("metadata", hasProperty("keyword", hasItemInArray(containsString("latex")))))); -// -// } - - @Test - public void testLanguagesSearch() throws IOException { - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "latex", null, null, null,null); - searchMetadata.setNaturalLanguage(List.of("de"));; - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); - org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); - MatcherAssert.assertThat(searchResultPage.getSearchResult(), - everyItem(hasProperty("metadata", hasProperty("language", hasItemInArray(containsString("de")))))); - - } + mockConfigs.add( + new ConnectorConfigWrapper( + new SharingPluginConfig( + "mockedPlugin", + new SharingPluginConfig.Action[] { + new SharingPluginConfig.Action("mockedAction", "http://unused/unused-transferURL", "mocked Action", "true"), + } + ), + "http://unused/hopefully-unused" + ) + ); + + mockConfigs.add( + new ConnectorConfigWrapper( + new SharingPluginConfig( + "Artemis Sharing Connector", + new SharingPluginConfig.Action[] { + new SharingPluginConfig.Action("Import", "http://unused/unused-transferURL", "Export to Artemis", "true"), + } + ), + "http://unused/hopefully-unused" + ) + ); + + when(pluginManagementService.getRegisteredPluginConfigs()).thenReturn(mockConfigs); + } + + @Test + public void testAllSearch() throws Exception { + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null, null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + + Assert.assertTrue("At least one hit?", searchResultPage.getSearchResult().size() >= 1); + Assert.assertEquals("We start at 0", 0, searchResultPage.getPageStartIndex()); + LOGGER.info("found {} hits for all", searchResultPage.getHitCount()); + } + + @Test + public void testFullTextSearch() throws Exception { + LOGGER.info("starting testFullTextSearch"); + final String WIEN = "Wien"; + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null, null); + SearchInputDTO searchQuery = new SearchInputDTO(WIEN, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + + org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + MatcherAssert.assertThat( + searchResultPage.getSearchResult(), + everyItem( + anyOf( + hasProperty("metadata", hasProperty("description", containsString(WIEN))), + hasProperty("metadata", hasProperty("title", containsString(WIEN))) + // hasProperty("keywords", containsString("Wien")) + ) + ) + ); + + LOGGER.info("exiting testFullTextSearch"); + } + + @Test + public void testSearchByAutor() throws Exception { + final String PODLIPNIG = "Stefan Podlipnig"; + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, PODLIPNIG, null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + + org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + MatcherAssert.assertThat( + searchResultPage.getSearchResult(), + everyItem(hasProperty("metadata", hasProperty("creator", hasItemInArray(hasProperty("name", containsString(PODLIPNIG)))))) + ); + } + + @Test + @Disabled("Ich brings nicht zum laufen :-(") + public void testProgrammingLanguageSearch() throws Exception { + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO("Java", null, null, null, null, null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + + assertNotNull(searchResultPage.getSearchResult()); + assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + MatcherAssert.assertThat( + searchResultPage.getSearchResult(), + everyItem(hasProperty("metadata", hasProperty("programmingLanguage", hasItemInArray(containsStringIgnoringCase("Java"))))) + ); + } + + @Test + public void testCreatorSearch() throws IOException { + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, "Podlipnig", null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + + org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + MatcherAssert.assertThat( + searchResultPage.getSearchResult(), + everyItem(hasProperty("metadata", hasProperty("creator", hasItemInArray(hasProperty("name", containsString("Podlipnig")))))) + ); + } + + @Test + public void testKeywordSearch() throws IOException { + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "latex", null, null, null, null); + org.codeability.sharing.plugins.api.search.SearchInputDTO searchQuery = new SearchInputDTO( + null, + searchMetadata, + null, + null, + null, + 0 + ); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + + org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + MatcherAssert.assertThat( + searchResultPage.getSearchResult(), + everyItem(hasProperty("metadata", hasProperty("keyword", hasItemInArray(containsString("latex"))))) + ); + } + + @Test + public void testFormatSearch() throws IOException { + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null, "latex"); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + + org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + MatcherAssert.assertThat( + searchResultPage.getSearchResult(), + everyItem(hasProperty("metadata", hasProperty("format", hasItemInArray(containsString("latex"))))) + ); + } + + // does not work with metadata version 0.4 + // @Test + // public void testTypesSearch() throws IOException { + // final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "latex", null, null, null,null); + // searchMetadata.setTypes(Collections.singletonList(ExerciseType.COLLECTION)); + // SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + // SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + // + // org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + // org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + // assertThat(searchResultPage.getSearchResult(), + // everyItem(hasProperty("metadata", hasProperty("keyword", hasItemInArray(containsString("latex")))))); + // + // } + + @Test + public void testLanguagesSearch() throws IOException { + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "latex", null, null, null, null); + searchMetadata.setNaturalLanguage(List.of("de")); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + + org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + MatcherAssert.assertThat( + searchResultPage.getSearchResult(), + everyItem(hasProperty("metadata", hasProperty("language", hasItemInArray(containsString("de"))))) + ); + } // does not work with metadata version 0.4 -// @Test -// public void testTypesSearchNegative() throws IOException { -// final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "latex", null, null, null,null); -// searchMetadata.setTypes(Collections.singletonList(ExerciseType.OTHER)); -// SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); -// SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); -// -// org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); -// org.junit.Assert.assertTrue("We expect no hit for \"latex\" and ExerciseType.OTHER", searchResultPage.getHitCount() == 0); -// -// } - -// @Test() -// @Ignore() // Test funktioniert momentan nicht? - public void testLicenseSearch() throws IOException { - - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, "MIT", null,null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - - org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); - org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); - MatcherAssert.assertThat(searchResultPage.getSearchResult(), - everyItem(hasProperty("metadata", hasProperty("license", containsString("MIT"))))); - - } - - @Test - public void testKeywordAutocompletion() throws IOException { - final List<AutoCompleteEntry> keywordsAutoComplete = searchService.getKeywordsAutoComplete("Jav", 10); - MatcherAssert.assertThat(keywordsAutoComplete, contains(hasProperty("target", is("Java")))); - } - - @Test - public void testCreatorAutocompletion() throws IOException { - final List<AutoCompleteEntry> creatorAutoComplete = searchService.getCreatorAutoComplete("Pod", 10); - MatcherAssert.assertThat(creatorAutoComplete, contains(hasProperty("target", is("Stefan Podlipnig")))); - final List<AutoCompleteEntry> creatorAutoComplete2 = searchService.getCreatorAutoComplete("Po", 10); - MatcherAssert.assertThat(creatorAutoComplete2, contains(hasProperty("target", is("Stefan Podlipnig")))); - } - - @Test - public void testContributorAutocompletion() throws IOException { - final List<AutoCompleteEntry> contributorAutoComplete = searchService.getContributorAutoComplete("Bast", 10); - MatcherAssert.assertThat(contributorAutoComplete, contains(hasProperty("target", is("Daniel Bastta")))); - } - - @Test - public void testContributorCreatorAutocompletion() throws IOException { - final List<AutoCompleteEntry> contributorAutoComplete = searchService.getContributorCreatorAutoComplete("Bast", 10); - MatcherAssert.assertThat(contributorAutoComplete, contains(hasProperty("target", is("Daniel Bastta")))); - } + // @Test + // public void testTypesSearchNegative() throws IOException { + // final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, "latex", null, null, null,null); + // searchMetadata.setTypes(Collections.singletonList(ExerciseType.OTHER)); + // SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + // SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + // + // org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + // org.junit.Assert.assertTrue("We expect no hit for \"latex\" and ExerciseType.OTHER", searchResultPage.getHitCount() == 0); + // + // } + + // @Test() + // @Ignore() // Test funktioniert momentan nicht? + public void testLicenseSearch() throws IOException { + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, "MIT", null, null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + + org.junit.Assert.assertNotNull(searchResultPage.getSearchResult()); + org.junit.Assert.assertTrue("At least one test hit", searchResultPage.getHitCount() >= 1); + MatcherAssert.assertThat( + searchResultPage.getSearchResult(), + everyItem(hasProperty("metadata", hasProperty("license", containsString("MIT")))) + ); + } + + @Test + public void testKeywordAutocompletion() throws IOException { + final List<AutoCompleteEntry> keywordsAutoComplete = searchService.getKeywordsAutoComplete("Jav", 10); + MatcherAssert.assertThat(keywordsAutoComplete, contains(hasProperty("target", is("Java")))); + } + + @Test + public void testCreatorAutocompletion() throws IOException { + final List<AutoCompleteEntry> creatorAutoComplete = searchService.getCreatorAutoComplete("Pod", 10); + MatcherAssert.assertThat(creatorAutoComplete, contains(hasProperty("target", is("Stefan Podlipnig")))); + final List<AutoCompleteEntry> creatorAutoComplete2 = searchService.getCreatorAutoComplete("Po", 10); + MatcherAssert.assertThat(creatorAutoComplete2, contains(hasProperty("target", is("Stefan Podlipnig")))); + } + + @Test + public void testContributorAutocompletion() throws IOException { + final List<AutoCompleteEntry> contributorAutoComplete = searchService.getContributorAutoComplete("Bast", 10); + MatcherAssert.assertThat(contributorAutoComplete, contains(hasProperty("target", is("Daniel Bastta")))); + } + + @Test + public void testContributorCreatorAutocompletion() throws IOException { + final List<AutoCompleteEntry> contributorAutoComplete = searchService.getContributorCreatorAutoComplete("Bast", 10); + MatcherAssert.assertThat(contributorAutoComplete, contains(hasProperty("target", is("Daniel Bastta")))); + } @SuppressWarnings("unchecked") - @Test + @Test public void testArtemisExportActionFilteringForAuthorizedUser() throws IOException, GitLabApiException { GitLabApi mockedGitLabApi = mock(GitLabApi.class); when(gitLabRepository.getGitLabApi(any(Optional.class))).thenReturn(mockedGitLabApi); doReturn(mockedRepositoryApi).when(mockedGitLabApi).getRepositoryApi(); - doReturn(new ByteArrayInputStream(" ".getBytes())).when(mockedRepositoryApi).getRepositoryArchive(eq(333), anyString(), anyString()); + doReturn(new ByteArrayInputStream(" ".getBytes())) + .when(mockedRepositoryApi) + .getRepositoryArchive(eq(333), anyString(), anyString()); - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null,null); + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null, null); SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); SearchResultsDTO results = searchService.searchResultPage(searchQuery); - Optional<SearchResultDTO> result = results.getSearchResult().stream().filter(entry -> entry.getExerciseId().equals("333")).findFirst(); + Optional<SearchResultDTO> result = results + .getSearchResult() + .stream() + .filter(entry -> entry.getExerciseId().equals("333")) + .findFirst(); if (result.isEmpty()) { throw new NotFoundException("Exercise with publicVisibility and id '333' couldn't be found in the test data"); } - Assertions.assertTrue(result.get().getSupportedActions().stream().anyMatch(action -> action.getPlugin().equals("Artemis Sharing Connector"))); + Assertions.assertTrue( + result.get().getSupportedActions().stream().anyMatch(action -> action.getPlugin().equals("Artemis Sharing Connector")) + ); } @Test @WithMockUser(value = "User without authorities") public void testArtemisExportActionFilteringForUnauthorizedUser() throws IOException { - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null,null); + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null, null); SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); SearchResultsDTO results = searchService.searchResultPage(searchQuery); - Optional<SearchResultDTO> result = results.getSearchResult().stream().filter(entry -> entry.getExerciseId().equals("333")).findFirst(); + Optional<SearchResultDTO> result = results + .getSearchResult() + .stream() + .filter(entry -> entry.getExerciseId().equals("333")) + .findFirst(); if (result.isEmpty()) { throw new NotFoundException("Exercise with publicVisibility and id '333' couldn't be found in the test data"); } - Assertions.assertFalse(result.get().getSupportedActions().stream().anyMatch(action -> action.getPlugin().equals("Artemis Sharing Connector"))); + Assertions.assertFalse( + result.get().getSupportedActions().stream().anyMatch(action -> action.getPlugin().equals("Artemis Sharing Connector")) + ); } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/ShoppingBasketServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/ShoppingBasketServiceIT.java index 7252be655beb3a3a43c66f0d7a64fd5e248254f9..2355c35e2d42599a47cf436a83c61a7ba555361d 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/ShoppingBasketServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/ShoppingBasketServiceIT.java @@ -1,5 +1,9 @@ package at.ac.uibk.gitsearch.service; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketInfoDTO; +import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirectInfoDTO; import java.io.IOException; import java.io.InputStream; import java.util.concurrent.TimeUnit; @@ -7,7 +11,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; - import org.codeability.sharing.plugins.api.ShoppingBasket; import org.codeability.sharing.plugins.api.search.SearchInputDTO; import org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO; @@ -25,100 +28,104 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.security.test.context.support.WithMockUser; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketInfoDTO; -import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirectInfoDTO; - @SpringBootTest(classes = GitsearchApp.class) @WithMockUser(value = "test", authorities = "sharing") public class ShoppingBasketServiceIT { - - private static final String TEST_ZIP_LOCATION = "./testData/junit-quality-tests-exercise-master.zip"; - @Autowired - protected ShoppingBasketService shoppingBasketService; - @Autowired - private SearchService searchService; - - - private static final Logger log = LoggerFactory.getLogger(ShoppingBasketServiceIT.class); - - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } + + private static final String TEST_ZIP_LOCATION = "./testData/junit-quality-tests-exercise-master.zip"; + + @Autowired + protected ShoppingBasketService shoppingBasketService; + + @Autowired + private SearchService searchService; + + private static final Logger log = LoggerFactory.getLogger(ShoppingBasketServiceIT.class); + + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } @Test - public void testSimpleRepackage() throws IOException { - - final InputStream resourceStream = this.getClass().getResourceAsStream(TEST_ZIP_LOCATION); - - Assert.assertNotNull("cannot find resource at " + TEST_ZIP_LOCATION, resourceStream); - final ZipInputStream testZip = new ZipInputStream(resourceStream); - - final InputStream testRepackagedZipIS = shoppingBasketService.rePackageGitLabProjectZip(testZip, "from " + TEST_ZIP_LOCATION, new String[] {}, ""); - - final ZipInputStream testRepackagedZip = new ZipInputStream(testRepackagedZipIS); - - ZipEntry entry = testRepackagedZip.getNextEntry(); - - while(entry!=null) { - log.info("found entry {} (directory: {})", entry.getName(), entry.isDirectory()); - Assert.assertTrue("original folder not chopped off?", !entry.getName().startsWith("junit-quality-tests-exercise-master")); - entry = testRepackagedZip.getNextEntry(); - } - - testRepackagedZip.close(); - } - + public void testSimpleRepackage() throws IOException { + final InputStream resourceStream = this.getClass().getResourceAsStream(TEST_ZIP_LOCATION); + + Assert.assertNotNull("cannot find resource at " + TEST_ZIP_LOCATION, resourceStream); + final ZipInputStream testZip = new ZipInputStream(resourceStream); + + final InputStream testRepackagedZipIS = shoppingBasketService.rePackageGitLabProjectZip( + testZip, + "from " + TEST_ZIP_LOCATION, + new String[] {}, + "" + ); + + final ZipInputStream testRepackagedZip = new ZipInputStream(testRepackagedZipIS); + + ZipEntry entry = testRepackagedZip.getNextEntry(); + + while (entry != null) { + log.info("found entry {} (directory: {})", entry.getName(), entry.isDirectory()); + Assert.assertTrue("original folder not chopped off?", !entry.getName().startsWith("junit-quality-tests-exercise-master")); + entry = testRepackagedZip.getNextEntry(); + } + + testRepackagedZip.close(); + } + @Test - public void testFilteredRepackage() throws IOException { - - final String[] filterOut = new String[] {"solution", "tests"}; - - // first check whether this is good test data - final ZipInputStream originalZip = new ZipInputStream(this.getClass().getResourceAsStream(TEST_ZIP_LOCATION)); - - boolean found = false; - for(ZipEntry entry = originalZip.getNextEntry(); entry != null; entry = originalZip.getNextEntry()) { - found = found || isPathPrefix(filterOut, "junit-quality-tests-exercise-master/", entry); - if (found) break; - } - Assert.assertTrue("test zip should contain entries to filter away?", found); - - final InputStream resourceStream = this.getClass().getResourceAsStream(TEST_ZIP_LOCATION); - - Assert.assertNotNull("cannot find resource at " + TEST_ZIP_LOCATION, resourceStream); - final ZipInputStream testZip = new ZipInputStream(resourceStream); - - final InputStream testRepackagedZipIS = shoppingBasketService.rePackageGitLabProjectZip(testZip, "from " + TEST_ZIP_LOCATION, filterOut, ""); - - final ZipInputStream testRepackagedZip = new ZipInputStream(testRepackagedZipIS); - - for(ZipEntry entry = testRepackagedZip.getNextEntry(); entry != null; entry = testRepackagedZip.getNextEntry()) { - boolean foundPrefix = isPathPrefix(filterOut, "", entry); - Assert.assertFalse("original folder starts with excepted directory?", foundPrefix); - } - - testRepackagedZip.close(); - } + public void testFilteredRepackage() throws IOException { + final String[] filterOut = new String[] { "solution", "tests" }; + + // first check whether this is good test data + final ZipInputStream originalZip = new ZipInputStream(this.getClass().getResourceAsStream(TEST_ZIP_LOCATION)); + + boolean found = false; + for (ZipEntry entry = originalZip.getNextEntry(); entry != null; entry = originalZip.getNextEntry()) { + found = found || isPathPrefix(filterOut, "junit-quality-tests-exercise-master/", entry); + if (found) break; + } + Assert.assertTrue("test zip should contain entries to filter away?", found); + + final InputStream resourceStream = this.getClass().getResourceAsStream(TEST_ZIP_LOCATION); + + Assert.assertNotNull("cannot find resource at " + TEST_ZIP_LOCATION, resourceStream); + final ZipInputStream testZip = new ZipInputStream(resourceStream); + + final InputStream testRepackagedZipIS = shoppingBasketService.rePackageGitLabProjectZip( + testZip, + "from " + TEST_ZIP_LOCATION, + filterOut, + "" + ); + + final ZipInputStream testRepackagedZip = new ZipInputStream(testRepackagedZipIS); + + for (ZipEntry entry = testRepackagedZip.getNextEntry(); entry != null; entry = testRepackagedZip.getNextEntry()) { + boolean foundPrefix = isPathPrefix(filterOut, "", entry); + Assert.assertFalse("original folder starts with excepted directory?", foundPrefix); + } + + testRepackagedZip.close(); + } /** * tests for the path prefix in filterOut @@ -127,69 +134,68 @@ public class ShoppingBasketServiceIT { * @param entry the zip entry * @return true if one of the path prefixes matches */ - private boolean isPathPrefix(final String[] filterOut, String basePrefix, ZipEntry entry) { - boolean found = false; - String fileName = entry.getName(); - if (fileName.startsWith(basePrefix)) - fileName = fileName.substring(basePrefix.length()); - for(String filter: filterOut) { - found = found || fileName.startsWith(filter); // this is slighlty lazy, because we should check for real path - if (found) break; - } - return found; - } - - /** - * tests for subpackages - * @throws IOException - */ + private boolean isPathPrefix(final String[] filterOut, String basePrefix, ZipEntry entry) { + boolean found = false; + String fileName = entry.getName(); + if (fileName.startsWith(basePrefix)) fileName = fileName.substring(basePrefix.length()); + for (String filter : filterOut) { + found = found || fileName.startsWith(filter); // this is slighlty lazy, because we should check for real path + if (found) break; + } + return found; + } + + /** + * tests for subpackages + * @throws IOException + */ @Test - public void testSubRepackage() throws IOException { - - - final InputStream resourceStream = this.getClass().getResourceAsStream(TEST_ZIP_LOCATION); - - Assert.assertNotNull("cannot find resource at " + TEST_ZIP_LOCATION, resourceStream); - final ZipInputStream testZip = new ZipInputStream(resourceStream); - - final InputStream testRepackagedZipIS = shoppingBasketService.rePackageGitLabProjectZip(testZip, "from " + TEST_ZIP_LOCATION, new String[] {}, "exercise"); - - final ZipInputStream testRepackagedZip = new ZipInputStream(testRepackagedZipIS); - - for(ZipEntry entry = testRepackagedZip.getNextEntry(); entry != null; entry = testRepackagedZip.getNextEntry()) { - boolean foundPrefix = isPathPrefix(new String[] {"solution", "tests", "test"}, "", entry); - Assert.assertFalse("original folder starts with excepted directory?", foundPrefix); - } - - testRepackagedZip.close(); - } + public void testSubRepackage() throws IOException { + final InputStream resourceStream = this.getClass().getResourceAsStream(TEST_ZIP_LOCATION); + + Assert.assertNotNull("cannot find resource at " + TEST_ZIP_LOCATION, resourceStream); + final ZipInputStream testZip = new ZipInputStream(resourceStream); + + final InputStream testRepackagedZipIS = shoppingBasketService.rePackageGitLabProjectZip( + testZip, + "from " + TEST_ZIP_LOCATION, + new String[] {}, + "exercise" + ); + + final ZipInputStream testRepackagedZip = new ZipInputStream(testRepackagedZipIS); + + for (ZipEntry entry = testRepackagedZip.getNextEntry(); entry != null; entry = testRepackagedZip.getNextEntry()) { + boolean foundPrefix = isPathPrefix(new String[] { "solution", "tests", "test" }, "", entry); + Assert.assertFalse("original folder starts with excepted directory?", foundPrefix); + } + + testRepackagedZip.close(); + } @Test public void testGetBasket() throws IOException { - - // just load everything from index :-) - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null,null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - Assert.assertTrue("At least one hit?", searchResultPage.getSearchResult().size() >= 1); - - ShoppingBasketInfoDTO sbi = new ShoppingBasketInfoDTO(searchResultPage.getSearchResult().toArray(new SearchResultDTO[] {})); - - ShoppingBasketRedirectInfoDTO redInfo = shoppingBasketService.getRedirectInfo(sbi, "http://unused/unused"); - - Pattern tokenParser = Pattern.compile("/([^/?]*)\\?"); - final Matcher matcher = tokenParser.matcher(redInfo.getRedirectURL()); - Assert.assertTrue(matcher.find()); - String token=matcher.group(1); - final ShoppingBasket basket = shoppingBasketService.getBasket(token); - - int count=0; - for(SearchResultDTO hitResult: searchResultPage.getSearchResult()) { - // we assume same sequence - Assert.assertEquals(basket.exerciseInfo[count].getMetadata().getTitle(), hitResult.getMetadata().getTitle()); - count++; - } + // just load everything from index :-) + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null, null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + Assert.assertTrue("At least one hit?", searchResultPage.getSearchResult().size() >= 1); + + ShoppingBasketInfoDTO sbi = new ShoppingBasketInfoDTO(searchResultPage.getSearchResult().toArray(new SearchResultDTO[] {})); + + ShoppingBasketRedirectInfoDTO redInfo = shoppingBasketService.getRedirectInfo(sbi, "http://unused/unused"); + + Pattern tokenParser = Pattern.compile("/([^/?]*)\\?"); + final Matcher matcher = tokenParser.matcher(redInfo.getRedirectURL()); + Assert.assertTrue(matcher.find()); + String token = matcher.group(1); + final ShoppingBasket basket = shoppingBasketService.getBasket(token); + + int count = 0; + for (SearchResultDTO hitResult : searchResultPage.getSearchResult()) { + // we assume same sequence + Assert.assertEquals(basket.exerciseInfo[count].getMetadata().getTitle(), hitResult.getMetadata().getTitle()); + count++; + } } - - } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/UserServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/UserServiceIT.java index 7bfd3e30d4f96bd38401f7f63d37d2ac89779e64..2d531f5506963b00df4de1051aca82907a4d7e51 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/UserServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/UserServiceIT.java @@ -6,12 +6,15 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import at.ac.uibk.gitsearch.IntegrationTest; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.repository.UserRepository; +import at.ac.uibk.gitsearch.repository.search.UserSearchRepository; import java.time.Instant; import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.List; import java.util.Optional; - import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -20,11 +23,6 @@ import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.data.auditing.AuditingHandler; import org.springframework.data.auditing.DateTimeProvider; import org.springframework.transaction.annotation.Transactional; - -import at.ac.uibk.gitsearch.IntegrationTest; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.repository.UserRepository; -import at.ac.uibk.gitsearch.repository.search.UserSearchRepository; import tech.jhipster.security.RandomUtil; /** diff --git a/src/test/java/at/ac/uibk/gitsearch/service/UserWatchListServiceIT.java b/src/test/java/at/ac/uibk/gitsearch/service/UserWatchListServiceIT.java index 1c733b75893142bf9a5c6524f24e47a1e2955036..371790cfa1ecc6ee1c58b6c76a94135b6c97e1b8 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/UserWatchListServiceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/UserWatchListServiceIT.java @@ -2,6 +2,14 @@ package at.ac.uibk.gitsearch.service; import static org.mockito.Mockito.when; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.domain.UserWatchList; +import at.ac.uibk.gitsearch.domain.WatchListEntry; +import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; +import at.ac.uibk.gitsearch.repository.UserWatchListRepository; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; import java.io.IOException; import java.time.Instant; import java.time.LocalDateTime; @@ -10,7 +18,6 @@ import java.util.HashSet; import java.util.Map; import java.util.Optional; import java.util.concurrent.TimeUnit; - import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.elasticsearch.node.NodeValidationException; import org.junit.jupiter.api.AfterAll; @@ -23,15 +30,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.auditing.DateTimeProvider; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.domain.UserWatchList; -import at.ac.uibk.gitsearch.domain.WatchListEntry; -import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; -import at.ac.uibk.gitsearch.repository.UserWatchListRepository; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; - /** * Integration tests for {@link UserWatchListService}. */ @@ -50,7 +48,7 @@ public class UserWatchListServiceIT { private static final String DEFAULT_IMAGEURL = "http://placehold.it/50x50"; private static final String DEFAULT_LANGKEY = "dummy"; - + private static final String TEST_EXERCISE_ID = "1"; @Autowired @@ -58,37 +56,38 @@ public class UserWatchListServiceIT { @Autowired private UserWatchListService userWatchListService; + @Autowired private UserWatchListRepository userWatchListRepository; - private final static Instant LAST_CHANGE_DATE_OF_EXERCISE3 = Instant.parse("2021-02-17T15:13:27.123Z"); + private static final Instant LAST_CHANGE_DATE_OF_EXERCISE3 = Instant.parse("2021-02-17T15:13:27.123Z"); + @Mock private DateTimeProvider dateTimeProvider; private User user; - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } @BeforeEach public void init() { @@ -105,60 +104,66 @@ public class UserWatchListServiceIT { userDTO.getAuthorities().add("sharing"); when(dateTimeProvider.getNow()).thenReturn(Optional.of(LocalDateTime.now())); - + userDTO.setActivated(false); user = userService.createUser(userDTO); - + UserWatchList wlDAILY = new UserWatchList("someTestWatchList", CheckFrequency.DAILY, user); WatchListEntry wle1 = new WatchListEntry(); - wle1.setExerciseId(TEST_EXERCISE_ID); + wle1.setExerciseId(TEST_EXERCISE_ID); wle1.setExerciseName("Unused in this test"); wlDAILY.getWatchListEntries().add(wle1); - + userWatchListRepository.save(wlDAILY); - + UserWatchList wlMONTHLY = new UserWatchList("someTestWatchList", CheckFrequency.MONTHLY, user); WatchListEntry wle2 = new WatchListEntry(); wle2.setExerciseId(TEST_EXERCISE_ID); wle2.setExerciseName("Unused in this test"); wlMONTHLY.getWatchListEntries().add(wle2); - - userWatchListRepository.save(wlMONTHLY); + userWatchListRepository.save(wlMONTHLY); } - + @Test @Transactional public void testSimpleCheck() { - final Instant since1970 = Instant.ofEpochSecond(0); - final Map<SearchResultDTO, UserWatchList> changesSince1970 = userWatchListService.findChangesSince(since1970, user); - org.junit.Assert.assertTrue("At least one match, because changed since 1970", !changesSince1970.isEmpty()); + final Instant since1970 = Instant.ofEpochSecond(0); + final Map<SearchResultDTO, UserWatchList> changesSince1970 = userWatchListService.findChangesSince(since1970, user); + org.junit.Assert.assertTrue("At least one match, because changed since 1970", !changesSince1970.isEmpty()); } @Test @Transactional public void testNotChangedAfterCheck() { - final Instant justOneHourAfterChange = LAST_CHANGE_DATE_OF_EXERCISE3.plus(1, ChronoUnit.HOURS); - final Map<SearchResultDTO, UserWatchList> changesSinceAnHourLater = userWatchListService.findChangesSince(justOneHourAfterChange, user); - org.junit.Assert.assertTrue("At least one match, because changed an hour before", changesSinceAnHourLater.isEmpty()); + final Instant justOneHourAfterChange = LAST_CHANGE_DATE_OF_EXERCISE3.plus(1, ChronoUnit.HOURS); + final Map<SearchResultDTO, UserWatchList> changesSinceAnHourLater = userWatchListService.findChangesSince( + justOneHourAfterChange, + user + ); + org.junit.Assert.assertTrue("At least one match, because changed an hour before", changesSinceAnHourLater.isEmpty()); } @Test @Transactional public void testChangedBeforeCheck() { - final Instant justOneHourBeforeChange = LAST_CHANGE_DATE_OF_EXERCISE3.minus(1, ChronoUnit.HOURS); - final Map<SearchResultDTO, UserWatchList> changesSinceAnHourBefore = userWatchListService.findChangesSince(justOneHourBeforeChange, user); - org.junit.Assert.assertTrue("At least one match, because changed an hour later", !changesSinceAnHourBefore.isEmpty()); + final Instant justOneHourBeforeChange = LAST_CHANGE_DATE_OF_EXERCISE3.minus(1, ChronoUnit.HOURS); + final Map<SearchResultDTO, UserWatchList> changesSinceAnHourBefore = userWatchListService.findChangesSince( + justOneHourBeforeChange, + user + ); + org.junit.Assert.assertTrue("At least one match, because changed an hour later", !changesSinceAnHourBefore.isEmpty()); } - + @Test @Transactional public void testChangedBeforeCheckFrequency() { - final Map<SearchResultDTO, UserWatchList> allExercisesAreTooOld = userWatchListService.findChangesSince(CheckFrequency.MONTHLY, user); - org.junit.Assert.assertTrue("At least one match, because changed an hour later", allExercisesAreTooOld.isEmpty()); + final Map<SearchResultDTO, UserWatchList> allExercisesAreTooOld = userWatchListService.findChangesSince( + CheckFrequency.MONTHLY, + user + ); + org.junit.Assert.assertTrue("At least one match, because changed an hour later", allExercisesAreTooOld.isEmpty()); } - - - } +} diff --git a/src/test/java/at/ac/uibk/gitsearch/service/dto/SearchResultDTOTest.java b/src/test/java/at/ac/uibk/gitsearch/service/dto/SearchResultDTOTest.java index 16f2199018313f6880744449c28a7bc23d443c51..618d02d60bd8289ca991b7dec15d7afae99cc857 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/dto/SearchResultDTOTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/dto/SearchResultDTOTest.java @@ -1,24 +1,26 @@ package at.ac.uibk.gitsearch.service.dto; -import org.codeability.sharing.plugins.api.search.SearchResultDTO; -import org.junit.Assert; -import org.junit.jupiter.api.Test; - import at.ac.uibk.gitsearch.testingUtilities.PropertiesTester; import nl.jqno.equalsverifier.EqualsVerifier; import nl.jqno.equalsverifier.Warning; +import org.codeability.sharing.plugins.api.search.SearchResultDTO; +import org.junit.Assert; +import org.junit.jupiter.api.Test; public class SearchResultDTOTest { - PropertiesTester propertiesTester = new PropertiesTester(); + PropertiesTester propertiesTester = new PropertiesTester(); @Test public void dtoEqualsVerifier() throws Exception { - propertiesTester.testProperties(SearchResultDTO.class); - SearchResultDTO testSR = new SearchResultDTO(); - SearchResultDTO testSRclone = new SearchResultDTO(testSR); - Assert.assertEquals("clone should be equal", testSR, testSRclone); - EqualsVerifier.forClass(SearchResultDTO.class).suppress(Warning.NONFINAL_FIELDS) - .withIgnoredFields("ranking5", "supportedActions").verify(); + propertiesTester.testProperties(SearchResultDTO.class); + SearchResultDTO testSR = new SearchResultDTO(); + SearchResultDTO testSRclone = new SearchResultDTO(testSR); + Assert.assertEquals("clone should be equal", testSR, testSRclone); + EqualsVerifier + .forClass(SearchResultDTO.class) + .suppress(Warning.NONFINAL_FIELDS) + .withIgnoredFields("ranking5", "supportedActions") + .verify(); } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/dto/StatisticsDTOTest.java b/src/test/java/at/ac/uibk/gitsearch/service/dto/StatisticsDTOTest.java index 82fb8a395be1e8a8d5bd344a084a17a1fc68ad87..a9a0afc70a92b9f94f440776414669d24abc2ee5 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/dto/StatisticsDTOTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/dto/StatisticsDTOTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.service.dto; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + import at.ac.uibk.gitsearch.web.rest.TestUtil; +import org.junit.jupiter.api.Test; public class StatisticsDTOTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/service/dto/UserWatchListDTOTest.java b/src/test/java/at/ac/uibk/gitsearch/service/dto/UserWatchListDTOTest.java index 6fcc80171a6662320db0c18580ff3f5cddeaff52..61230dc4d575e722ba24dbcb6975b1fa74f52964 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/dto/UserWatchListDTOTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/dto/UserWatchListDTOTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.service.dto; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + import at.ac.uibk.gitsearch.web.rest.TestUtil; +import org.junit.jupiter.api.Test; public class UserWatchListDTOTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/service/dto/VariousDTOTest.java b/src/test/java/at/ac/uibk/gitsearch/service/dto/VariousDTOTest.java index 6054f917094ef355db847b6b0b59bd4de1ee724a..ab7756f662d5324f49b63f4d87a961003871a9df 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/dto/VariousDTOTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/dto/VariousDTOTest.java @@ -2,8 +2,12 @@ package at.ac.uibk.gitsearch.service.dto; import static org.junit.Assert.assertEquals; +import at.ac.uibk.gitsearch.properties.ApplicationProperties.DeploymentInfo; +import at.ac.uibk.gitsearch.service.MailService; +import at.ac.uibk.gitsearch.testingUtilities.PropertiesTester; import java.lang.reflect.InvocationTargetException; - +import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.Warning; import org.codeability.sharing.plugins.api.search.SearchResultDTO; import org.codeability.sharing.plugins.api.search.SearchResultDTO.GitProject; import org.codeability.sharing.plugins.api.search.SearchResultsDTO; @@ -12,93 +16,88 @@ import org.codeability.sharing.plugins.api.search.UserProvidedMetadataDTO.Person import org.junit.Assert; import org.junit.jupiter.api.Test; -import at.ac.uibk.gitsearch.properties.ApplicationProperties.DeploymentInfo; -import at.ac.uibk.gitsearch.service.MailService; -import at.ac.uibk.gitsearch.testingUtilities.PropertiesTester; -import nl.jqno.equalsverifier.EqualsVerifier; -import nl.jqno.equalsverifier.Warning; - /** * Integration tests for {@link MailService}. */ public class VariousDTOTest { - PropertiesTester propertiesTester = new PropertiesTester(); - - @Test - public void testUserProvidedMetadataDTO() throws IllegalAccessException, InvocationTargetException { - - - propertiesTester.testProperties(UserProvidedMetadataDTO.class); - UserProvidedMetadataDTO testUPMD = new UserProvidedMetadataDTO(); - UserProvidedMetadataDTO testUPMDclone = new UserProvidedMetadataDTO(testUPMD); - Assert.assertEquals("clone should be equas", testUPMD, testUPMDclone); - EqualsVerifier.forClass(UserProvidedMetadataDTO.class).suppress(Warning.NONFINAL_FIELDS).verify(); - - } - - @Test - public void testMessageDTO() { - MessageDTO mess = new MessageDTO("someMessage"); - assertEquals("someMessage", mess.getMessage()); - propertiesTester.testProperties(MessageDTO.class); - } - - @Test - public void testMetadataUserDTO() { - MetadataUserDTO user = new MetadataUserDTO("name", "affiliation", "abc@def.de"); - assertEquals("name", user.getName()); - assertEquals("affiliation", user.getAffiliation()); - assertEquals("abc@def.de", user.getEmail()); - propertiesTester.testProperties(MetadataUserDTO.class); - } - - @Test - public void testSearchResultsDTO() throws IllegalAccessException, InvocationTargetException { - propertiesTester.testProperties(SearchResultsDTO.class); - propertiesTester.testProperties(SearchResultDTO.class); - propertiesTester.testProperties(Person.class); - propertiesTester.testProperties(GitProject.class); - - // just for test coverage - @SuppressWarnings("unused") - SearchResultsDTO srDTO = new SearchResultsDTO(null, 0, 0); - } + PropertiesTester propertiesTester = new PropertiesTester(); + + @Test + public void testUserProvidedMetadataDTO() throws IllegalAccessException, InvocationTargetException { + propertiesTester.testProperties(UserProvidedMetadataDTO.class); + UserProvidedMetadataDTO testUPMD = new UserProvidedMetadataDTO(); + UserProvidedMetadataDTO testUPMDclone = new UserProvidedMetadataDTO(testUPMD); + Assert.assertEquals("clone should be equas", testUPMD, testUPMDclone); + EqualsVerifier.forClass(UserProvidedMetadataDTO.class).suppress(Warning.NONFINAL_FIELDS).verify(); + } + + @Test + public void testMessageDTO() { + MessageDTO mess = new MessageDTO("someMessage"); + assertEquals("someMessage", mess.getMessage()); + propertiesTester.testProperties(MessageDTO.class); + } + + @Test + public void testMetadataUserDTO() { + MetadataUserDTO user = new MetadataUserDTO("name", "affiliation", "abc@def.de"); + assertEquals("name", user.getName()); + assertEquals("affiliation", user.getAffiliation()); + assertEquals("abc@def.de", user.getEmail()); + propertiesTester.testProperties(MetadataUserDTO.class); + } + + @Test + public void testSearchResultsDTO() throws IllegalAccessException, InvocationTargetException { + propertiesTester.testProperties(SearchResultsDTO.class); + propertiesTester.testProperties(SearchResultDTO.class); + propertiesTester.testProperties(Person.class); + propertiesTester.testProperties(GitProject.class); + + // just for test coverage + @SuppressWarnings("unused") + SearchResultsDTO srDTO = new SearchResultsDTO(null, 0, 0); + } // does not work with metadata version 0.4 -// @Test -// public void testSearchResultsEnums() throws IllegalAccessException, InvocationTargetException { -// for(ExerciseType et: ExerciseType.values()) { -// et.getExternalName(); -// } -// -// for(GitProjectVisibility vis: GitProjectVisibility.values()) { -// vis.getExternalName(); -// } -// } - - // @org.junit.jupiter.api.Test - // public void testSearchInputDTO() throws IllegalAccessException, InvocationTargetException { - // propertiesTester.testProperties(SearchInputDTO.class); - // } - - @org.junit.jupiter.api.Test - public void testDeploymentInfo() throws IllegalAccessException, InvocationTargetException { - propertiesTester.testProperties(DeploymentInfo.class); - } - - @org.junit.jupiter.api.Test - public void testVariousEquals() throws IllegalAccessException, InvocationTargetException { - GitProject p1 = new GitProject(); p1.setProjectId(10); - GitProject p2 = new GitProject(); p2.setProjectId(10); - GitProject p3 = new GitProject(); p3.setProjectId(20); - - Assert.assertEquals(p1, p2); - Assert.assertNotEquals(p1, p3); - EqualsVerifier.forClass(GitProject.class) - .suppress(Warning.NONFINAL_FIELDS) - .withIgnoredFields("project_name", "namespace","main_group", "last_activity_at", "url", "sub_group").verify(); - EqualsVerifier.forClass(Person.class).suppress(Warning.NONFINAL_FIELDS).verify(); - } - + // @Test + // public void testSearchResultsEnums() throws IllegalAccessException, InvocationTargetException { + // for(ExerciseType et: ExerciseType.values()) { + // et.getExternalName(); + // } + // + // for(GitProjectVisibility vis: GitProjectVisibility.values()) { + // vis.getExternalName(); + // } + // } + + // @org.junit.jupiter.api.Test + // public void testSearchInputDTO() throws IllegalAccessException, InvocationTargetException { + // propertiesTester.testProperties(SearchInputDTO.class); + // } + + @org.junit.jupiter.api.Test + public void testDeploymentInfo() throws IllegalAccessException, InvocationTargetException { + propertiesTester.testProperties(DeploymentInfo.class); + } + + @org.junit.jupiter.api.Test + public void testVariousEquals() throws IllegalAccessException, InvocationTargetException { + GitProject p1 = new GitProject(); + p1.setProjectId(10); + GitProject p2 = new GitProject(); + p2.setProjectId(10); + GitProject p3 = new GitProject(); + p3.setProjectId(20); + + Assert.assertEquals(p1, p2); + Assert.assertNotEquals(p1, p3); + EqualsVerifier + .forClass(GitProject.class) + .suppress(Warning.NONFINAL_FIELDS) + .withIgnoredFields("project_name", "namespace", "main_group", "last_activity_at", "url", "sub_group") + .verify(); + EqualsVerifier.forClass(Person.class).suppress(Warning.NONFINAL_FIELDS).verify(); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/dto/WatchListEntryDTOTest.java b/src/test/java/at/ac/uibk/gitsearch/service/dto/WatchListEntryDTOTest.java index a84ab6f79c811c2c117cdcfbcb20aa4316c474a2..2739a770144b03272b4a37b8f0e5071dacc630d2 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/dto/WatchListEntryDTOTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/dto/WatchListEntryDTOTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.service.dto; -import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; + import at.ac.uibk.gitsearch.web.rest.TestUtil; +import org.junit.jupiter.api.Test; public class WatchListEntryDTOTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/service/management/PluginHealthCheckRegistryIT.java b/src/test/java/at/ac/uibk/gitsearch/service/management/PluginHealthCheckRegistryIT.java index dca22999d2ee95e280b957992ff8e929f02c6b96..ca4a87199b86c2fca3fff742461121ed43ac8083 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/management/PluginHealthCheckRegistryIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/management/PluginHealthCheckRegistryIT.java @@ -3,6 +3,8 @@ package at.ac.uibk.gitsearch.service.management; import static org.hamcrest.CoreMatchers.anyOf; import static org.hamcrest.CoreMatchers.is; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; import org.hamcrest.MatcherAssert; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -12,30 +14,26 @@ import org.springframework.boot.actuate.health.HealthIndicator; import org.springframework.boot.actuate.health.Status; import org.springframework.boot.test.context.SpringBootTest; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.properties.ApplicationProperties; - @SpringBootTest(classes = GitsearchApp.class) public class PluginHealthCheckRegistryIT { - - @Autowired - private ApplicationProperties applicationProperties; - @Autowired - private HealthContributorRegistry healthContributorRegistry; + @Autowired + private ApplicationProperties applicationProperties; + + @Autowired + private HealthContributorRegistry healthContributorRegistry; - @Test - public void testHealth() { - healthContributorRegistry.forEach( - contributor -> { - if(applicationProperties.getRegisteredConnectors().stream().anyMatch(c -> c.getUrl().equals(contributor.getName()))) { - Health h = ((HealthIndicator) contributor.getContributor()).health(); - MatcherAssert.assertThat("Health for " + contributor.getName() + " should be either be up or down, but was " + h.getStatus(), - h.getStatus(), anyOf(is(Status.UP), is(Status.DOWN))); - } - } - ); - } - - + @Test + public void testHealth() { + healthContributorRegistry.forEach(contributor -> { + if (applicationProperties.getRegisteredConnectors().stream().anyMatch(c -> c.getUrl().equals(contributor.getName()))) { + Health h = ((HealthIndicator) contributor.getContributor()).health(); + MatcherAssert.assertThat( + "Health for " + contributor.getName() + " should be either be up or down, but was " + h.getStatus(), + h.getStatus(), + anyOf(is(Status.UP), is(Status.DOWN)) + ); + } + }); + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/service/mapper/StatisticsMapperTest.java b/src/test/java/at/ac/uibk/gitsearch/service/mapper/StatisticsMapperTest.java index e280711016c5471c1b40e6bf241287231d0ddf82..b3e24e5251d37d89e1b87edd25f18c093968f466 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/mapper/StatisticsMapperTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/mapper/StatisticsMapperTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.service.mapper; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; public class StatisticsMapperTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/service/mapper/UserWatchListMapperTest.java b/src/test/java/at/ac/uibk/gitsearch/service/mapper/UserWatchListMapperTest.java index 0ff5d2eefed5611cc4063ad2d8bd91a5bf536cf7..ead158b1e87a03362fc2c46eaacfe4c1a09998d0 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/mapper/UserWatchListMapperTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/mapper/UserWatchListMapperTest.java @@ -1,8 +1,9 @@ package at.ac.uibk.gitsearch.service.mapper; +import static org.assertj.core.api.Assertions.assertThat; + import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import static org.assertj.core.api.Assertions.assertThat; public class UserWatchListMapperTest { diff --git a/src/test/java/at/ac/uibk/gitsearch/service/mapper/WatchListEntryMapperTest.java b/src/test/java/at/ac/uibk/gitsearch/service/mapper/WatchListEntryMapperTest.java index 70581e51654156b8b3b288cfaced30c087d6fb98..6cc6e4ac4a6aedbcceb0880c09a44b5f46620097 100644 --- a/src/test/java/at/ac/uibk/gitsearch/service/mapper/WatchListEntryMapperTest.java +++ b/src/test/java/at/ac/uibk/gitsearch/service/mapper/WatchListEntryMapperTest.java @@ -1,16 +1,14 @@ package at.ac.uibk.gitsearch.service.mapper; +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - import at.ac.uibk.gitsearch.domain.User; import at.ac.uibk.gitsearch.domain.UserWatchList; import at.ac.uibk.gitsearch.domain.WatchListEntry; import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; - -import static org.assertj.core.api.Assertions.assertThat; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; public class WatchListEntryMapperTest { @@ -27,24 +25,27 @@ public class WatchListEntryMapperTest { assertThat(watchListEntryMapper.fromId(id).getId()).isEqualTo(id); assertThat(watchListEntryMapper.fromId(null)).isNull(); } - + @Test public void testWatchlistIdMapping() { - final long wlId = 25L; - final long wleId = 13L; - UserWatchList wl = new UserWatchList(); - wl.setId(wlId); wl.setName("Just testing"); wl.setUser(new User()); - - WatchListEntry wle = new WatchListEntry(); - - wle.setId(wleId); wle.setExerciseId("unusedExerciseId"); wle.setExerciseName("Test Exercise Name"); wle.setWatchlist(wl); - - - final WatchListEntryDTO wlAsDTO = watchListEntryMapper.toDto(wle); - assertEquals(wlAsDTO.getId(), wle.getId()); - assertEquals(wlAsDTO.getExerciseId(), wle.getExerciseId()); - assertEquals(wlAsDTO.getExerciseName(), wle.getExerciseName()); - assertEquals(wlAsDTO.getWatchlistId(), wle.getWatchlist().getId()); + final long wlId = 25L; + final long wleId = 13L; + UserWatchList wl = new UserWatchList(); + wl.setId(wlId); + wl.setName("Just testing"); + wl.setUser(new User()); + + WatchListEntry wle = new WatchListEntry(); + + wle.setId(wleId); + wle.setExerciseId("unusedExerciseId"); + wle.setExerciseName("Test Exercise Name"); + wle.setWatchlist(wl); + + final WatchListEntryDTO wlAsDTO = watchListEntryMapper.toDto(wle); + assertEquals(wlAsDTO.getId(), wle.getId()); + assertEquals(wlAsDTO.getExerciseId(), wle.getExerciseId()); + assertEquals(wlAsDTO.getExerciseName(), wle.getExerciseName()); + assertEquals(wlAsDTO.getWatchlistId(), wle.getWatchlist().getId()); } - } diff --git a/src/test/java/at/ac/uibk/gitsearch/testingUtilities/PropertiesTester.java b/src/test/java/at/ac/uibk/gitsearch/testingUtilities/PropertiesTester.java index 2481b2605cafd1006ac07a79bb47b55a2f104b70..6e4132836ff1c3766d0815b18e9754682b7b80a2 100644 --- a/src/test/java/at/ac/uibk/gitsearch/testingUtilities/PropertiesTester.java +++ b/src/test/java/at/ac/uibk/gitsearch/testingUtilities/PropertiesTester.java @@ -12,7 +12,6 @@ import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.junit.Assert; @@ -25,151 +24,157 @@ import org.springframework.stereotype.Controller; */ @Controller public class PropertiesTester { - - private static final Logger LOGGER = LogManager.getLogger(PropertiesTester.class); - - /** - * - * @param beanClass the class to test - * @param setterExceptions the names of setters that should not be tested. - */ - public void testProperties(Class<?> beanClass, String... setterExceptions) { - // first try to instantiate bean; - Object bean = null; - try { - bean = beanClass.getConstructor().newInstance(); - } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException e) { - LOGGER.info("Cannot instantiate " + beanClass.getCanonicalName(), e); - return; - } - testSetters(beanClass, bean, setterExceptions); - } - /** - * just tests all setters on bean - * @param beanClass - * @param bean - * @param setterExceptions - */ -public void testSetters(Class<?> beanClass, Object bean, String... setterExceptions) { - final Method[] methods = beanClass.getMethods(); - for(Method method: methods) { - if(method.getName().startsWith("set")) { - if(!Arrays.stream(setterExceptions).anyMatch(noTest -> method.getName().equals(noTest))) - testSetter(beanClass, bean, method); - } - } - - // finally test toString - String stringRepresentation = bean.toString(); - Assert.assertNotNull(stringRepresentation); -} - - public void testSetter(Class<?> beanClass, Object bean, Method setter) { - if(setter.getParameterCount()!=1) { - return; - } - Parameter p = setter.getParameters()[0]; - - String propertyName = setter.getName().substring(3); - Class<?> type = p.getType(); - - Method getter = null; - Object property = null; - if(Boolean.class.equals(type) || boolean.class.equals(type) ) { - try { - property = Boolean.TRUE; - getter = beanClass.getMethod("is"+propertyName); - } catch (NoSuchMethodException | SecurityException e) { - try { - getter = beanClass.getMethod("get"+propertyName); - } catch (NoSuchMethodException | SecurityException ex) { - LOGGER.info("Cannot find getter (neither is... nor get... for " + beanClass.getCanonicalName() + "." + setter.getName(), ex); - return; - } - } - } else { - try { - getter = beanClass.getMethod("get" + propertyName); - if(Integer.class.isAssignableFrom(type) || "int".equals(type.getName())) { - property = Integer.valueOf(2343234); - } - else if(Long.class.isAssignableFrom(type) || "long".equals(type.getName())) { - property = Long.valueOf(12321332343234L); - } - else if(Byte.class.isAssignableFrom(type) || "byte".equals(type.getName())) { - property = Byte.valueOf((byte)22); - } - else if(String.class.isAssignableFrom(type)) { - property = "xyzzy"; - } - else if(byte[].class.isAssignableFrom(type)) { - property = new byte[]{3,4}; + private static final Logger LOGGER = LogManager.getLogger(PropertiesTester.class); + + /** + * + * @param beanClass the class to test + * @param setterExceptions the names of setters that should not be tested. + */ + public void testProperties(Class<?> beanClass, String... setterExceptions) { + // first try to instantiate bean; + Object bean = null; + try { + bean = beanClass.getConstructor().newInstance(); + } catch ( + InstantiationException + | IllegalAccessException + | IllegalArgumentException + | InvocationTargetException + | NoSuchMethodException + | SecurityException e + ) { + LOGGER.info("Cannot instantiate " + beanClass.getCanonicalName(), e); + return; } - else if(type.isArray()) { - property = Array.newInstance(type.getComponentType(), 5); + testSetters(beanClass, bean, setterExceptions); + } + /** + * just tests all setters on bean + * @param beanClass + * @param bean + * @param setterExceptions + */ + public void testSetters(Class<?> beanClass, Object bean, String... setterExceptions) { + final Method[] methods = beanClass.getMethods(); + for (Method method : methods) { + if (method.getName().startsWith("set")) { + if (!Arrays.stream(setterExceptions).anyMatch(noTest -> method.getName().equals(noTest))) testSetter( + beanClass, + bean, + method + ); + } } - else if(Timestamp.class.isAssignableFrom(type)) { - property = new Timestamp(System.currentTimeMillis()); - } else if(Date.class.isAssignableFrom(type)) { - property = new Date(); - } else if(List.class.isAssignableFrom(type)) { - property = new ArrayList<>(); - } else if(Enum.class.isAssignableFrom(type)) { - Object o; - try { - o = type.getMethod("values").invoke(type); - if( o.getClass().isArray() && Array.getLength(o)>=0) { - property = Array.get(o, 0); - } else { - LOGGER.warn("Cannot get first element of enumeration {}", type.getName()); - property = null; - } - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - LOGGER.info("Cannot instantiate Enum for " + type.getCanonicalName() + "." + setter.getName(), e); - property = null; - } - } else if(Set.class.isAssignableFrom(type)) { - property = Collections.emptySet(); - } else if (Instant.class.isAssignableFrom(type)) { - property = Instant.now(); - } else if (Float.class.isAssignableFrom(type)) { - property = Float.valueOf(1.33f); - - } else if (Double.class.isAssignableFrom(type)) { - property = Double.valueOf(1.77777d); - } - else if(type.isInterface()) { - LOGGER.info("Cannot instantiate interface {} in {} for class {}", type.getName(), setter.getName(), bean.getClass().getName()); + + // finally test toString + String stringRepresentation = bean.toString(); + Assert.assertNotNull(stringRepresentation); + } + + public void testSetter(Class<?> beanClass, Object bean, Method setter) { + if (setter.getParameterCount() != 1) { + return; } - else { - try { - property = type.getConstructor().newInstance(); - } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - LOGGER.info("Cannot instantiate Property for " + beanClass.getCanonicalName() + "." + setter.getName(), e); - property = null; - } + Parameter p = setter.getParameters()[0]; + + String propertyName = setter.getName().substring(3); + Class<?> type = p.getType(); + + Method getter = null; + Object property = null; + if (Boolean.class.equals(type) || boolean.class.equals(type)) { + try { + property = Boolean.TRUE; + getter = beanClass.getMethod("is" + propertyName); + } catch (NoSuchMethodException | SecurityException e) { + try { + getter = beanClass.getMethod("get" + propertyName); + } catch (NoSuchMethodException | SecurityException ex) { + LOGGER.info( + "Cannot find getter (neither is... nor get... for " + beanClass.getCanonicalName() + "." + setter.getName(), + ex + ); + return; + } + } + } else { + try { + getter = beanClass.getMethod("get" + propertyName); + if (Integer.class.isAssignableFrom(type) || "int".equals(type.getName())) { + property = Integer.valueOf(2343234); + } else if (Long.class.isAssignableFrom(type) || "long".equals(type.getName())) { + property = Long.valueOf(12321332343234L); + } else if (Byte.class.isAssignableFrom(type) || "byte".equals(type.getName())) { + property = Byte.valueOf((byte) 22); + } else if (String.class.isAssignableFrom(type)) { + property = "xyzzy"; + } else if (byte[].class.isAssignableFrom(type)) { + property = new byte[] { 3, 4 }; + } else if (type.isArray()) { + property = Array.newInstance(type.getComponentType(), 5); + } else if (Timestamp.class.isAssignableFrom(type)) { + property = new Timestamp(System.currentTimeMillis()); + } else if (Date.class.isAssignableFrom(type)) { + property = new Date(); + } else if (List.class.isAssignableFrom(type)) { + property = new ArrayList<>(); + } else if (Enum.class.isAssignableFrom(type)) { + Object o; + try { + o = type.getMethod("values").invoke(type); + if (o.getClass().isArray() && Array.getLength(o) >= 0) { + property = Array.get(o, 0); + } else { + LOGGER.warn("Cannot get first element of enumeration {}", type.getName()); + property = null; + } + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + LOGGER.info("Cannot instantiate Enum for " + type.getCanonicalName() + "." + setter.getName(), e); + property = null; + } + } else if (Set.class.isAssignableFrom(type)) { + property = Collections.emptySet(); + } else if (Instant.class.isAssignableFrom(type)) { + property = Instant.now(); + } else if (Float.class.isAssignableFrom(type)) { + property = Float.valueOf(1.33f); + } else if (Double.class.isAssignableFrom(type)) { + property = Double.valueOf(1.77777d); + } else if (type.isInterface()) { + LOGGER.info( + "Cannot instantiate interface {} in {} for class {}", + type.getName(), + setter.getName(), + bean.getClass().getName() + ); + } else { + try { + property = type.getConstructor().newInstance(); + } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + LOGGER.info("Cannot instantiate Property for " + beanClass.getCanonicalName() + "." + setter.getName(), e); + property = null; + } + } + } catch (NoSuchMethodException | SecurityException e) { + LOGGER.info("Cannot find getter for " + beanClass.getCanonicalName() + "." + setter.getName(), e); + return; + } + + if (getter == null) { + // not getter found + return; + } + try { + setter.invoke(bean, property); + Object result = getter.invoke(bean); + Assert.assertEquals("Testing " + setter.getName() + " of " + beanClass.getCanonicalName(), property, result); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + LOGGER.info("Cannot invoke ..." + beanClass.getCanonicalName() + "." + setter.getName(), e); + return; + } } - } catch (NoSuchMethodException | SecurityException e) { - LOGGER.info("Cannot find getter for " + beanClass.getCanonicalName() + "." + setter.getName(), e); - return; - } - - if(getter==null) { - // not getter found - return; - } - try { - setter.invoke(bean, property); - Object result = getter.invoke(bean); - Assert.assertEquals("Testing " + setter.getName() + " of " + beanClass.getCanonicalName(), property, result); - } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { - LOGGER.info("Cannot invoke ..." + beanClass.getCanonicalName() + "." + setter.getName(), e); - return; - } } - - } - } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/AccountResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/AccountResourceIT.java index 8b9f7b9c9b21d65c39bf5cccb43abcfd6d07fb22..6c10d08278674ab776521f591e5d4129d5291125 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/AccountResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/AccountResourceIT.java @@ -9,12 +9,22 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.IntegrationTest; +import at.ac.uibk.gitsearch.config.Constants; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.repository.AuthorityRepository; +import at.ac.uibk.gitsearch.repository.UserRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.service.UserService; +import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; +import at.ac.uibk.gitsearch.service.dto.PasswordChangeDTO; +import at.ac.uibk.gitsearch.web.rest.vm.KeyAndPasswordVM; +import at.ac.uibk.gitsearch.web.rest.vm.ManagedUserVM; import java.time.Instant; import java.util.Collections; import java.util.HashSet; import java.util.Optional; import java.util.Set; - import org.apache.commons.lang3.RandomStringUtils; import org.junit.Ignore; import org.junit.jupiter.api.Disabled; @@ -27,18 +37,6 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.IntegrationTest; -import at.ac.uibk.gitsearch.config.Constants; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.repository.AuthorityRepository; -import at.ac.uibk.gitsearch.repository.UserRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.service.UserService; -import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; -import at.ac.uibk.gitsearch.service.dto.PasswordChangeDTO; -import at.ac.uibk.gitsearch.web.rest.vm.KeyAndPasswordVM; -import at.ac.uibk.gitsearch.web.rest.vm.ManagedUserVM; - /** * Integration tests for the {@link AccountResource} REST controller. */ @@ -139,8 +137,12 @@ class AccountResourceIT { assertThat(userRepository.findOneByLogin("test-register-valid")).isEmpty(); restAccountMockMvc - .perform(post("/api/register").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(validUser)) - .with(csrf().asHeader())) + .perform( + post("/api/register") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(validUser)) + .with(csrf().asHeader()) + ) .andExpect(status().isCreated()); assertThat(userRepository.findOneByLogin("test-register-valid")).isPresent(); @@ -162,15 +164,19 @@ class AccountResourceIT { invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); restAccountMockMvc - .perform(post("/api/register").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(invalidUser)) - .with(csrf().asHeader())) + .perform( + post("/api/register") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(invalidUser)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); Optional<User> user = userRepository.findOneByEmailIgnoreCase("funky@example.com"); assertThat(user).isEmpty(); } - @Test() + @Test @Disabled("Self registration is not enabled") @Transactional void testRegisterInvalidEmail() throws Exception { @@ -186,8 +192,12 @@ class AccountResourceIT { invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); restAccountMockMvc - .perform(post("/api/register").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(invalidUser)) - .with(csrf().asHeader())) + .perform( + post("/api/register") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(invalidUser)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); Optional<User> user = userRepository.findOneByLogin("bob"); @@ -210,8 +220,12 @@ class AccountResourceIT { invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); restAccountMockMvc - .perform(post("/api/register").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(invalidUser)) - .with(csrf().asHeader())) + .perform( + post("/api/register") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(invalidUser)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); Optional<User> user = userRepository.findOneByLogin("bob"); @@ -234,8 +248,12 @@ class AccountResourceIT { invalidUser.setAuthorities(Collections.singleton(AuthoritiesConstants.USER)); restAccountMockMvc - .perform(post("/api/register").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(invalidUser)) - .with(csrf().asHeader())) + .perform( + post("/api/register") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(invalidUser)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); Optional<User> user = userRepository.findOneByLogin("bob"); @@ -274,8 +292,12 @@ class AccountResourceIT { // First user restAccountMockMvc - .perform(post("/api/register").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(firstUser)) - .with(csrf().asHeader())) + .perform( + post("/api/register") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(firstUser)) + .with(csrf().asHeader()) + ) .andExpect(status().isCreated()); // Second (non activated) user @@ -311,8 +333,12 @@ class AccountResourceIT { // Register first user restAccountMockMvc - .perform(post("/api/register").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(firstUser)) - .with(csrf().asHeader())) + .perform( + post("/api/register") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(firstUser)) + .with(csrf().asHeader()) + ) .andExpect(status().isCreated()); Optional<User> testUser1 = userRepository.findOneByLogin("test-register-duplicate-email"); @@ -390,8 +416,12 @@ class AccountResourceIT { validUser.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); restAccountMockMvc - .perform(post("/api/register").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(validUser)) - .with(csrf().asHeader())) + .perform( + post("/api/register") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(validUser)) + .with(csrf().asHeader()) + ) .andExpect(status().isCreated()); Optional<User> userDup = userRepository.findOneWithAuthoritiesByLogin("badguy"); @@ -448,8 +478,12 @@ class AccountResourceIT { userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); restAccountMockMvc - .perform(post("/api/account").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(userDTO)) - .with(csrf().asHeader())) + .perform( + post("/api/account") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userDTO)) + .with(csrf().asHeader()) + ) .andExpect(status().isOk()); User updatedUser = userRepository.findOneWithAuthoritiesByLogin(user.getLogin()).orElse(null); @@ -486,9 +520,12 @@ class AccountResourceIT { userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); restAccountMockMvc - .perform(post("/api/account").contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userDTO)) - .with(csrf().asHeader())) + .perform( + post("/api/account") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userDTO)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); assertThat(userRepository.findOneByEmailIgnoreCase("invalid email")).isNotPresent(); @@ -524,7 +561,12 @@ class AccountResourceIT { userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); restAccountMockMvc - .perform(post("/api/account").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(userDTO)).with(csrf().asHeader())) + .perform( + post("/api/account") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userDTO)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); User updatedUser = userRepository.findOneByLogin("save-existing-email").orElse(null); @@ -553,8 +595,12 @@ class AccountResourceIT { userDTO.setAuthorities(Collections.singleton(AuthoritiesConstants.ADMIN)); restAccountMockMvc - .perform(post("/api/account").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(userDTO)) - .with(csrf().asHeader())) + .perform( + post("/api/account") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userDTO)) + .with(csrf().asHeader()) + ) .andExpect(status().isOk()); User updatedUser = userRepository.findOneByLogin("save-existing-email-and-login").orElse(null); @@ -577,7 +623,7 @@ class AccountResourceIT { post("/api/account/change-password") .contentType(MediaType.APPLICATION_JSON) .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO("1" + currentPassword, "new password"))) - .with(csrf().asHeader()) + .with(csrf().asHeader()) ) .andExpect(status().isBadRequest()); @@ -602,7 +648,7 @@ class AccountResourceIT { post("/api/account/change-password") .contentType(MediaType.APPLICATION_JSON) .content(TestUtil.convertObjectToJsonBytes(new PasswordChangeDTO(currentPassword, "new password"))) - .with(csrf().asHeader()) + .with(csrf().asHeader()) ) .andExpect(status().isOk()); @@ -697,8 +743,7 @@ class AccountResourceIT { userRepository.saveAndFlush(user); restAccountMockMvc - .perform(post("/api/account/reset-password/init").content("password-reset@example.com") - .with(csrf().asHeader())) + .perform(post("/api/account/reset-password/init").content("password-reset@example.com").with(csrf().asHeader())) .andExpect(status().isOk()); } @@ -713,16 +758,14 @@ class AccountResourceIT { userRepository.saveAndFlush(user); restAccountMockMvc - .perform(post("/api/account/reset-password/init").content("password-reset-upper-case@EXAMPLE.COM") - .with(csrf().asHeader())) + .perform(post("/api/account/reset-password/init").content("password-reset-upper-case@EXAMPLE.COM").with(csrf().asHeader())) .andExpect(status().isOk()); } @Test void testRequestPasswordResetWrongEmail() throws Exception { restAccountMockMvc - .perform(post("/api/account/reset-password/init").content("password-reset-wrong-email@example.com") - .with(csrf().asHeader())) + .perform(post("/api/account/reset-password/init").content("password-reset-wrong-email@example.com").with(csrf().asHeader())) .andExpect(status().isOk()); } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/ApplicationInfoResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/ApplicationInfoResourceIT.java index d5f32c023872e2e131352b5ffe164f8f7dba9ea9..6b3f16f18ffa6470a85047eb6c060cdb7443a196 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/ApplicationInfoResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/ApplicationInfoResourceIT.java @@ -6,6 +6,9 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.properties.ApplicationProperties; +import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; import org.junit.jupiter.api.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -15,49 +18,48 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.properties.ApplicationProperties; -import at.ac.uibk.gitsearch.service.dto.BroadCastMessageDTO; - /** * Integration tests for the {@link UserResource} REST controller. */ @AutoConfigureMockMvc @SpringBootTest(classes = GitsearchApp.class) public class ApplicationInfoResourceIT { - - private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationInfoResourceIT.class); + + private static final Logger LOGGER = LoggerFactory.getLogger(ApplicationInfoResourceIT.class); @Autowired private MockMvc restMockMvc; - - @Test public void testGetDeploymentInfo() throws Exception { - restMockMvc.perform(get("/api/applicationInfo/deploymentInfo") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(TestUtil.testResult(ApplicationProperties.DeploymentInfo.class, r -> { - assertEquals("This may fail, if config changes", r.getCommitId(), "Test Commit Id"); - assertEquals("This may fail, if config changes", r.getBranch(), "Test Branch"); - })); + restMockMvc + .perform(get("/api/applicationInfo/deploymentInfo").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect( + TestUtil.testResult( + ApplicationProperties.DeploymentInfo.class, + r -> { + assertEquals("This may fail, if config changes", r.getCommitId(), "Test Commit Id"); + assertEquals("This may fail, if config changes", r.getBranch(), "Test Branch"); + } + ) + ); } @Test public void testGetBroadCastMessages() throws Exception { - restMockMvc.perform(get("/api/applicationInfo/broadcastMessages") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(TestUtil.testResult(BroadCastMessageDTO[].class, r -> { - LOGGER.info("There are currently {} messages", r.length); - })); + restMockMvc + .perform(get("/api/applicationInfo/broadcastMessages").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect( + TestUtil.testResult( + BroadCastMessageDTO[].class, + r -> { + LOGGER.info("There are currently {} messages", r.length); + } + ) + ); } - - - } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/AuditResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/AuditResourceIT.java index 00fdc6521b58f60f39e44fe6d2421900b893ae0b..b634d4febd8eeca39141a923b778c6e28d66bcae 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/AuditResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/AuditResourceIT.java @@ -8,8 +8,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.domain.PersistentAuditEvent; +import at.ac.uibk.gitsearch.repository.PersistenceAuditEventRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; import java.time.Instant; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -20,11 +23,6 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.domain.PersistentAuditEvent; -import at.ac.uibk.gitsearch.repository.PersistenceAuditEventRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; - /** * Integration tests for the {@link AuditResource} REST controller. */ @@ -62,7 +60,8 @@ public class AuditResourceIT { auditEventRepository.save(auditEvent); // Get all the audits - restAuditMockMvc.perform(get("/management/audits")) + restAuditMockMvc + .perform(get("/management/audits")) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].principal").value(hasItem(SAMPLE_PRINCIPAL))); @@ -74,7 +73,8 @@ public class AuditResourceIT { auditEventRepository.save(auditEvent); // Get the audit - restAuditMockMvc.perform(get("/management/audits/{id}", auditEvent.getId())) + restAuditMockMvc + .perform(get("/management/audits/{id}", auditEvent.getId())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.principal").value(SAMPLE_PRINCIPAL)); @@ -90,7 +90,8 @@ public class AuditResourceIT { String toDate = SAMPLE_TIMESTAMP.plusSeconds(SECONDS_PER_DAY).toString().substring(0, 10); // Get the audit - restAuditMockMvc.perform(get("/management/audits?fromDate="+fromDate+"&toDate="+toDate)) + restAuditMockMvc + .perform(get("/management/audits?fromDate=" + fromDate + "&toDate=" + toDate)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].principal").value(hasItem(SAMPLE_PRINCIPAL))); @@ -102,11 +103,12 @@ public class AuditResourceIT { auditEventRepository.save(auditEvent); // Generate dates for selecting audits by date, making sure the period will not contain the sample audit - String fromDate = SAMPLE_TIMESTAMP.minusSeconds(2*SECONDS_PER_DAY).toString().substring(0, 10); + String fromDate = SAMPLE_TIMESTAMP.minusSeconds(2 * SECONDS_PER_DAY).toString().substring(0, 10); String toDate = SAMPLE_TIMESTAMP.minusSeconds(SECONDS_PER_DAY).toString().substring(0, 10); // Query audits but expect no results - restAuditMockMvc.perform(get("/management/audits?fromDate=" + fromDate + "&toDate=" + toDate)) + restAuditMockMvc + .perform(get("/management/audits?fromDate=" + fromDate + "&toDate=" + toDate)) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(header().string("X-Total-Count", "0")); @@ -115,8 +117,7 @@ public class AuditResourceIT { @Test public void getNonExistingAudit() throws Exception { // Get the audit - restAuditMockMvc.perform(get("/management/audits/{id}", Long.MAX_VALUE)) - .andExpect(status().isNotFound()); + restAuditMockMvc.perform(get("/management/audits/{id}", Long.MAX_VALUE)).andExpect(status().isNotFound()); } @Test diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/ExerciseResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/ExerciseResourceIT.java index 0cdbab85b018b18a188e2e3367da6a45694a6b53..4dcea0bd2d486422a2990aa23d42ac98256ae874 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/ExerciseResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/ExerciseResourceIT.java @@ -7,9 +7,11 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; import java.io.IOException; import java.util.concurrent.TimeUnit; - import org.elasticsearch.node.NodeValidationException; import org.junit.Assert; import org.junit.jupiter.api.AfterAll; @@ -24,10 +26,6 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.ResultMatcher; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; - /** * Integration tests for the {@link ExerciseResource} REST controller. */ @@ -36,151 +34,164 @@ import at.ac.uibk.gitsearch.security.AuthoritiesConstants; @SpringBootTest(classes = GitsearchApp.class) public class ExerciseResourceIT { - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } - @Autowired - private MockMvc restExerciseMockMvc; + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } + + @Autowired + private MockMvc restExerciseMockMvc; @Test public void getREADME() throws Exception { - String exerciseId = "318"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exerciseFile/"+exerciseId).param("filePath", "README.md") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) -// .andDo(print()) + String exerciseId = "318"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform( + get("/api/exerciseFile/" + exerciseId) + .param("filePath", "README.md") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + // .andDo(print()) .andExpect(status().is2xxSuccessful()) .andExpect(StreamResultMatcher.expectOctetStream()) .andExpect(StreamResultMatcher.expectMinimumSize(50)); - } - @Test public void getExercisemd() throws Exception { - String exerciseId = "318"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exerciseFile/"+exerciseId).param("filePath", "exercise.md") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) - .andExpect(status().is2xxSuccessful()) + String exerciseId = "318"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform( + get("/api/exerciseFile/" + exerciseId) + .param("filePath", "exercise.md") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().is2xxSuccessful()) .andExpect(StreamResultMatcher.expectOctetStream()) .andExpect(StreamResultMatcher.expectMinimumSize(50)); - } - + @Test public void getNestedPath() throws Exception { - String exerciseId = "318"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exerciseFile/"+exerciseId).param("filePath", "solution/src/at/ac/uibk/qe/artemis/iotest/HelloWorld.java") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) - .andExpect(status().is2xxSuccessful()) + String exerciseId = "318"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform( + get("/api/exerciseFile/" + exerciseId) + .param("filePath", "solution/src/at/ac/uibk/qe/artemis/iotest/HelloWorld.java") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().is2xxSuccessful()) .andExpect(StreamResultMatcher.expectOctetStream()) .andExpect(StreamResultMatcher.expectMinimumSize(50)); } @Test public void getSplitPath() throws Exception { - String exerciseId = "318:solution/src/at"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exerciseFile/"+exerciseId).param("filePath", "ac/uibk/qe/artemis/iotest/HelloWorld.java") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) - .andExpect(status().is2xxSuccessful()) + String exerciseId = "318:solution/src/at"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform( + get("/api/exerciseFile/" + exerciseId) + .param("filePath", "ac/uibk/qe/artemis/iotest/HelloWorld.java") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().is2xxSuccessful()) .andExpect(StreamResultMatcher.expectOctetStream()) .andExpect(StreamResultMatcher.expectMinimumSize(50)); } - + @Test public void testNotFound() throws Exception { - String exerciseId = "1"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exerciseFile/"+exerciseId).param("filePath", "fileDoesNotExist.md") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) - .andExpect(status().isNotFound()); - + String exerciseId = "1"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform( + get("/api/exerciseFile/" + exerciseId) + .param("filePath", "fileDoesNotExist.md") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) + .andExpect(status().isNotFound()); } - + public static class StreamResultMatcher { - - public static ResultMatcher expectMinimumSize(int size) { - return result -> { - final byte[] bytes = result.getResponse().getContentAsByteArray(); - Assert.assertTrue("minimum size should be " + size + ", but was " + bytes.length, - bytes.length >= size); - }; - } - - public static ResultMatcher expectOctetStream() { - return result -> { - Assert.assertEquals("Expected octet stream", MediaType.APPLICATION_OCTET_STREAM.toString(), result.getResponse().getContentType()); - }; - } + + public static ResultMatcher expectMinimumSize(int size) { + return result -> { + final byte[] bytes = result.getResponse().getContentAsByteArray(); + Assert.assertTrue("minimum size should be " + size + ", but was " + bytes.length, bytes.length >= size); + }; + } + + public static ResultMatcher expectOctetStream() { + return result -> { + Assert.assertEquals( + "Expected octet stream", + MediaType.APPLICATION_OCTET_STREAM.toString(), + result.getResponse().getContentType() + ); + }; + } } - + @Test public void getExerciseById1() throws Exception { - String exerciseId = "1"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exercise/"+exerciseId) - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) + String exerciseId = "1"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform(get("/api/exercise/" + exerciseId).with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)) + .andDo(print()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.project.project_id").value(exerciseId)); } @Test public void getExerciseBySubId() throws Exception { - String exerciseId = "318:solution/src/at"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exercise/"+exerciseId) - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) + String exerciseId = "318:solution/src/at"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform(get("/api/exercise/" + exerciseId).with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)) + .andDo(print()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.project.project_id").value("318")); } - + @Test public void getExerciseByNotFound1() throws Exception { - String exerciseId = "318:solution/src/atX"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exercise/"+exerciseId) - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) - .andExpect(status().isNotFound()); + String exerciseId = "318:solution/src/atX"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform(get("/api/exercise/" + exerciseId).with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)) + .andDo(print()) + .andExpect(status().isNotFound()); } @Test public void getExerciseByNotFound2() throws Exception { - String exerciseId = "xxx271:solution/src/atX"; // warning: this depends on the sequence in the current search index :-( - restExerciseMockMvc.perform(get("/api/exercise/"+exerciseId) - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) - .andExpect(status().isNotFound()); + String exerciseId = "xxx271:solution/src/atX"; // warning: this depends on the sequence in the current search index :-( + restExerciseMockMvc + .perform(get("/api/exercise/" + exerciseId).with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)) + .andDo(print()) + .andExpect(status().isNotFound()); } } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/LikesResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/LikesResourceIT.java index 7d8208bcf97daf9e36185c4fe8ce37c5ae86762d..29c7a488661799b6a11cdfcdddaa5493e2d1094c 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/LikesResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/LikesResourceIT.java @@ -14,12 +14,18 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.domain.Likes; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.repository.LikesRepository; +import at.ac.uibk.gitsearch.repository.UserRepository; +import at.ac.uibk.gitsearch.repository.search.LikesSearchRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.service.LikesService; import java.time.LocalDate; import java.time.ZoneId; import java.util.List; - import javax.persistence.EntityManager; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -33,22 +39,13 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.domain.Likes; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.repository.LikesRepository; -import at.ac.uibk.gitsearch.repository.UserRepository; -import at.ac.uibk.gitsearch.repository.search.LikesSearchRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.service.LikesService; - /** * Integration tests for the {@link LikesResource} REST controller. */ @SpringBootTest(classes = GitsearchApp.class) @ExtendWith(MockitoExtension.class) @AutoConfigureMockMvc -@WithMockUser(value = "user", authorities = {"sharing", AuthoritiesConstants.ADMIN}) +@WithMockUser(value = "user", authorities = { "sharing", AuthoritiesConstants.ADMIN }) public class LikesResourceIT { private static final LocalDate DEFAULT_DATE = LocalDate.ofEpochDay(0L); @@ -61,8 +58,9 @@ public class LikesResourceIT { private static final String DEFAULT_EXERCISE_ID = "1"; private static final String UPDATED_EXERCISE_ID = "2"; + @SuppressWarnings("unused") - private static final String SMALLER_EXERCISE_ID = "0"; + private static final String SMALLER_EXERCISE_ID = "0"; @Autowired private LikesRepository likesRepository; @@ -81,6 +79,7 @@ public class LikesResourceIT { @Autowired private UserRepository userRepo; + @Autowired private EntityManager em; @@ -121,8 +120,14 @@ public class LikesResourceIT { public void createLikes() throws Exception { int databaseSizeBeforeCreate = likesRepository.findAll().size(); // Create the Likes - restLikesMockMvc.perform(post("/api/likes").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(likes))).andExpect(status().isCreated()); + restLikesMockMvc + .perform( + post("/api/likes") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(likes)) + ) + .andExpect(status().isCreated()); // Validate the Likes in the database List<Likes> likesList = likesRepository.findAll(); @@ -131,7 +136,6 @@ public class LikesResourceIT { assertThat(testLikes.getDate()).isEqualTo(DEFAULT_DATE); assertThat(testLikes.getUserID()).isEqualTo(DEFAULT_USER_ID); assertThat(testLikes.getExerciseID()).isEqualTo(DEFAULT_EXERCISE_ID); - // Validate the Likes in Elasticsearch // we do not store likes in ES! //verify(mockLikesSearchRepository, times(1)).save(testLikes); @@ -146,8 +150,14 @@ public class LikesResourceIT { likes.setId(1L); // An entity with an existing ID cannot be created, so this API call must fail - restLikesMockMvc.perform(post("/api/likes").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(likes))).andExpect(status().isBadRequest()); + restLikesMockMvc + .perform( + post("/api/likes") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(likes)) + ) + .andExpect(status().isBadRequest()); // Validate the Likes in the database List<Likes> likesList = likesRepository.findAll(); @@ -166,8 +176,14 @@ public class LikesResourceIT { // Create the Likes, which fails. - restLikesMockMvc.perform(post("/api/likes").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(likes))).andExpect(status().isBadRequest()); + restLikesMockMvc + .perform( + post("/api/likes") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(likes)) + ) + .andExpect(status().isBadRequest()); List<Likes> likesList = likesRepository.findAll(); assertThat(likesList).hasSize(databaseSizeBeforeTest); @@ -182,8 +198,14 @@ public class LikesResourceIT { // Create the Likes, which fails. - restLikesMockMvc.perform(post("/api/likes").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(likes))).andExpect(status().isBadRequest()); + restLikesMockMvc + .perform( + post("/api/likes") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(likes)) + ) + .andExpect(status().isBadRequest()); List<Likes> likesList = likesRepository.findAll(); assertThat(likesList).hasSize(databaseSizeBeforeTest); @@ -198,8 +220,14 @@ public class LikesResourceIT { // Create the Likes, which fails. - restLikesMockMvc.perform(post("/api/likes").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(likes))).andExpect(status().isBadRequest()); + restLikesMockMvc + .perform( + post("/api/likes") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(likes)) + ) + .andExpect(status().isBadRequest()); List<Likes> likesList = likesRepository.findAll(); assertThat(likesList).hasSize(databaseSizeBeforeTest); @@ -212,12 +240,14 @@ public class LikesResourceIT { likesRepository.saveAndFlush(likes); // Get all the likesList - restLikesMockMvc.perform(get("/api/likes?sort=id,desc")).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.[*].id").value(hasItem(likes.getId().intValue()))) - .andExpect(jsonPath("$.[*].date").value(hasItem(DEFAULT_DATE.toString()))) - .andExpect(jsonPath("$.[*].userID").value(hasItem(DEFAULT_USER_ID))) - .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); + restLikesMockMvc + .perform(get("/api/likes?sort=id,desc")) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.[*].id").value(hasItem(likes.getId().intValue()))) + .andExpect(jsonPath("$.[*].date").value(hasItem(DEFAULT_DATE.toString()))) + .andExpect(jsonPath("$.[*].userID").value(hasItem(DEFAULT_USER_ID))) + .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); } @Test @@ -227,12 +257,14 @@ public class LikesResourceIT { likesRepository.saveAndFlush(likes); // Get the likes - restLikesMockMvc.perform(get("/api/likes/{id}", likes.getId())).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.id").value(likes.getId().intValue())) - .andExpect(jsonPath("$.date").value(DEFAULT_DATE.toString())) - .andExpect(jsonPath("$.userID").value(DEFAULT_USER_ID)) - .andExpect(jsonPath("$.exerciseID").value(DEFAULT_EXERCISE_ID)); + restLikesMockMvc + .perform(get("/api/likes/{id}", likes.getId())) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.id").value(likes.getId().intValue())) + .andExpect(jsonPath("$.date").value(DEFAULT_DATE.toString())) + .andExpect(jsonPath("$.userID").value(DEFAULT_USER_ID)) + .andExpect(jsonPath("$.exerciseID").value(DEFAULT_EXERCISE_ID)); } @Test @@ -250,8 +282,7 @@ public class LikesResourceIT { @Test @Transactional public void testLikeWorkflowWithAuthorities() throws Exception { - - List<User> userList = userRepo.findAll(); + List<User> userList = userRepo.findAll(); // Initialize the database likesRepository.saveAndFlush(likes); @@ -261,31 +292,47 @@ public class LikesResourceIT { //user likes a project - restLikesMockMvc.perform(put("/api/likes/likeExercise").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(newLike))).andExpect(status().isOk()); + restLikesMockMvc + .perform( + put("/api/likes/likeExercise") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(newLike)) + ) + .andExpect(status().isOk()); assertEquals(1, likesRepository.findNumberOfLikesByExerciseID("1000/abc/bd")); //like again and nothing should happen - restLikesMockMvc.perform(put("/api/likes/likeExercise").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(newLike))).andExpect(status().isOk()); - - - restLikesMockMvc.perform(get("/api/likes/numberOfLikes/{exerciseID}", "1000/abc/bd").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()); + restLikesMockMvc + .perform( + put("/api/likes/likeExercise") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(newLike)) + ) + .andExpect(status().isOk()); + + restLikesMockMvc + .perform( + get("/api/likes/numberOfLikes/{exerciseID}", "1000/abc/bd").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()); assertEquals(1, likesRepository.findNumberOfLikesByExerciseID("1000/abc/bd")); - //unlike project + //unlike project - restLikesMockMvc.perform(delete("/api/likes/unlikeExercise/{exerciseID}", "1000/abc/bd").with(csrf().asHeader()).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isNoContent()); + restLikesMockMvc + .perform( + delete("/api/likes/unlikeExercise/{exerciseID}", "1000/abc/bd").with(csrf().asHeader()).accept(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isNoContent()); assertEquals(0, likesRepository.findNumberOfLikesByExerciseID("1000/abc/bd")); - } - @Test @Transactional @WithMockUser(authorities = AuthoritiesConstants.ADMIN) @@ -299,16 +346,30 @@ public class LikesResourceIT { //user likes a project - restLikesMockMvc.perform(put("/api/likes/likeExercise").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(newLike))).andExpect(status().isOk()); - - - MvcResult result = restLikesMockMvc.perform(get("/api/likes/hasLiked/{exerciseID}", "1000/abc/bd").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn(); + restLikesMockMvc + .perform( + put("/api/likes/likeExercise") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(newLike)) + ) + .andExpect(status().isOk()); + + MvcResult result = restLikesMockMvc + .perform(get("/api/likes/hasLiked/{exerciseID}", "1000/abc/bd").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andReturn(); String content = result.getResponse().getContentAsString(); assertEquals("true", content); - result = restLikesMockMvc.perform(get("/api/likes/hasLiked/{exerciseID}", "imaginary").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn(); + result = + restLikesMockMvc + .perform( + get("/api/likes/hasLiked/{exerciseID}", "imaginary").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andReturn(); content = result.getResponse().getContentAsString(); assertEquals("false", content); @@ -326,19 +387,21 @@ public class LikesResourceIT { //user likes a project and nothing should happen - restLikesMockMvc.perform(put("/api/likes/likeExercise").contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(newLike))).andExpect(status().isForbidden()); + restLikesMockMvc + .perform( + put("/api/likes/likeExercise").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(newLike)) + ) + .andExpect(status().isForbidden()); assertEquals(0, likesRepository.findNumberOfLikesByExerciseID("1000")); + //unlike project - //unlike project - - restLikesMockMvc.perform(delete("/api/likes/unlikeExercise/{exerciseID}", "1000").accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isForbidden()); + restLikesMockMvc + .perform(delete("/api/likes/unlikeExercise/{exerciseID}", "1000").accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isForbidden()); assertEquals(0, likesRepository.findNumberOfLikesByExerciseID("1000")); - } @Test @@ -573,29 +636,40 @@ public class LikesResourceIT { * Executes the search, and checks that the default entity is returned. */ private void defaultLikesShouldBeFound(String filter) throws Exception { - restLikesMockMvc.perform(get("/api/likes?sort=id,desc&" + filter)).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.[*].id").value(hasItem(likes.getId().intValue()))) - .andExpect(jsonPath("$.[*].date").value(hasItem(DEFAULT_DATE.toString()))) - .andExpect(jsonPath("$.[*].userID").value(hasItem(DEFAULT_USER_ID))) - .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); + restLikesMockMvc + .perform(get("/api/likes?sort=id,desc&" + filter)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.[*].id").value(hasItem(likes.getId().intValue()))) + .andExpect(jsonPath("$.[*].date").value(hasItem(DEFAULT_DATE.toString()))) + .andExpect(jsonPath("$.[*].userID").value(hasItem(DEFAULT_USER_ID))) + .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); // Check, that the count call also returns 1 - restLikesMockMvc.perform(get("/api/likes/count?sort=id,desc&" + filter)).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)).andExpect(content().string("1")); + restLikesMockMvc + .perform(get("/api/likes/count?sort=id,desc&" + filter)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(content().string("1")); } /** * Executes the search, and checks that the default entity is not returned. */ private void defaultLikesShouldNotBeFound(String filter) throws Exception { - restLikesMockMvc.perform(get("/api/likes?sort=id,desc&" + filter)).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)).andExpect(jsonPath("$").isArray()) - .andExpect(jsonPath("$").isEmpty()); + restLikesMockMvc + .perform(get("/api/likes?sort=id,desc&" + filter)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$").isArray()) + .andExpect(jsonPath("$").isEmpty()); // Check, that the count call also returns 0 - restLikesMockMvc.perform(get("/api/likes/count?sort=id,desc&" + filter)).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)).andExpect(content().string("0")); + restLikesMockMvc + .perform(get("/api/likes/count?sort=id,desc&" + filter)) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(content().string("0")); } @Test @@ -620,8 +694,14 @@ public class LikesResourceIT { em.detach(updatedLikes); updatedLikes.date(UPDATED_DATE).userID(UPDATED_USER_ID).exerciseID(UPDATED_EXERCISE_ID); - restLikesMockMvc.perform(put("/api/likes").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(updatedLikes))).andExpect(status().isOk()); + restLikesMockMvc + .perform( + put("/api/likes") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(updatedLikes)) + ) + .andExpect(status().isOk()); // Validate the Likes in the database List<Likes> likesList = likesRepository.findAll(); @@ -630,11 +710,10 @@ public class LikesResourceIT { assertThat(testLikes.getDate()).isEqualTo(UPDATED_DATE); assertThat(testLikes.getUserID()).isEqualTo(UPDATED_USER_ID); assertThat(testLikes.getExerciseID()).isEqualTo(UPDATED_EXERCISE_ID); - // Validate the Likes in Elasticsearch // We do not use Elasticsearch for saving Likes Entities -// verify(mockLikesSearchRepository, times(2)).save(testLikes); + // verify(mockLikesSearchRepository, times(2)).save(testLikes); } @Test @@ -643,8 +722,14 @@ public class LikesResourceIT { int databaseSizeBeforeUpdate = likesRepository.findAll().size(); // If the entity doesn't have an ID, it will throw BadRequestAlertException - restLikesMockMvc.perform(put("/api/likes").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(likes))).andExpect(status().isBadRequest()); + restLikesMockMvc + .perform( + put("/api/likes") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(likes)) + ) + .andExpect(status().isBadRequest()); // Validate the Likes in the database List<Likes> likesList = likesRepository.findAll(); @@ -663,34 +748,32 @@ public class LikesResourceIT { int databaseSizeBeforeDelete = likesRepository.findAll().size(); // Delete the likes - restLikesMockMvc.perform( - delete("/api/likes/{id}", likes.getId()).with(csrf().asHeader()).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isNoContent()); + restLikesMockMvc + .perform(delete("/api/likes/{id}", likes.getId()).with(csrf().asHeader()).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isNoContent()); // Validate the database contains one less item List<Likes> likesList = likesRepository.findAll(); assertThat(likesList).hasSize(databaseSizeBeforeDelete - 1); - // Validate the Likes in Elasticsearch // We do not use Elasticsearch for saving Likes Entities - // verify(mockLikesSearchRepository, times(1)).deleteById(likes.getId()); - } - -// @Test -// @Transactional -// public void searchLikes() throws Exception { -// // Configure the mock search repository -// // Initialize the database -// likesService.save(likes); -// when(mockLikesSearchRepository.search(queryStringQuery("id:" + likes.getId()))) -// .thenReturn(Collections.singletonList(likes)); -// -// // Search the likes -// restLikesMockMvc.perform(get("/api/_search/likes?query=id:" + likes.getId())).andExpect(status().isOk()) -// .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) -// .andExpect(jsonPath("$.[*].id").value(hasItem(likes.getId().intValue()))) -// .andExpect(jsonPath("$.[*].date").value(hasItem(DEFAULT_DATE.toString()))) -// .andExpect(jsonPath("$.[*].userID").value(hasItem(DEFAULT_USER_ID))) -// .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); -// } + // verify(mockLikesSearchRepository, times(1)).deleteById(likes.getId()); + } + // @Test + // @Transactional + // public void searchLikes() throws Exception { + // // Configure the mock search repository + // // Initialize the database + // likesService.save(likes); + // when(mockLikesSearchRepository.search(queryStringQuery("id:" + likes.getId()))) + // .thenReturn(Collections.singletonList(likes)); + // + // // Search the likes + // restLikesMockMvc.perform(get("/api/_search/likes?query=id:" + likes.getId())).andExpect(status().isOk()) + // .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + // .andExpect(jsonPath("$.[*].id").value(hasItem(likes.getId().intValue()))) + // .andExpect(jsonPath("$.[*].date").value(hasItem(DEFAULT_DATE.toString()))) + // .andExpect(jsonPath("$.[*].userID").value(hasItem(DEFAULT_USER_ID))) + // .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); + // } } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/OAuth2ConfigResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/OAuth2ConfigResourceIT.java index 30e8f3662382d2044fb287771063fb1381be1b93..e3cb01edd12b595d6e84c483c8ccafdb8e527876 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/OAuth2ConfigResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/OAuth2ConfigResourceIT.java @@ -8,6 +8,10 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.service.dto.OAuth2ConfigDTO; +import nl.jqno.equalsverifier.EqualsVerifier; +import nl.jqno.equalsverifier.Warning; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -15,11 +19,6 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.service.dto.OAuth2ConfigDTO; -import nl.jqno.equalsverifier.EqualsVerifier; -import nl.jqno.equalsverifier.Warning; - /** * Integration tests for the {@link UserResource} REST controller. */ @@ -30,45 +29,46 @@ public class OAuth2ConfigResourceIT { @Autowired private MockMvc restMockMvc; - - @Test public void testGetOAuth2Configs() throws Exception { - restMockMvc.perform(get("/oauth2Config/allConfigs") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(TestUtil.testResult(OAuth2ConfigDTO[].class, r -> { - assertTrue("At least one entry", r.length > 0); - for(OAuth2ConfigDTO config: r) - try { - testGetOAuth2Config(config); - } catch (Exception e) { - fail("Exception " + e.getMessage() + " not expected!"); - } - - - - })); + restMockMvc + .perform(get("/oauth2Config/allConfigs").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect( + TestUtil.testResult( + OAuth2ConfigDTO[].class, + r -> { + assertTrue("At least one entry", r.length > 0); + for (OAuth2ConfigDTO config : r) try { + testGetOAuth2Config(config); + } catch (Exception e) { + fail("Exception " + e.getMessage() + " not expected!"); + } + } + ) + ); } public void testGetOAuth2Config(OAuth2ConfigDTO config) throws Exception { - restMockMvc.perform(get("/oauth2Config//config/"+ config.getRegistrationId()) - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) - .andExpect(status().isOk()) - .andExpect(TestUtil.testResult(OAuth2ConfigDTO.class, r -> { - assertEquals("Should be the same configs", config, r); - })); + restMockMvc + .perform( + get("/oauth2Config//config/" + config.getRegistrationId()).with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + .andExpect(status().isOk()) + .andExpect( + TestUtil.testResult( + OAuth2ConfigDTO.class, + r -> { + assertEquals("Should be the same configs", config, r); + } + ) + ); } - + @Test public void testEqualsOnOAuth2ConfigDTO() { - EqualsVerifier.forClass(OAuth2ConfigDTO.class).suppress(Warning.NONFINAL_FIELDS).verify(); + EqualsVerifier.forClass(OAuth2ConfigDTO.class).suppress(Warning.NONFINAL_FIELDS).verify(); } - - - } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/PluginInterfaceResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/PluginInterfaceResourceIT.java index 54d5ae934030e60881380c9fa031de913024847a..011bbf82305ea34c4540dc3ee894b558f9d131dc 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/PluginInterfaceResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/PluginInterfaceResourceIT.java @@ -6,9 +6,15 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.service.SearchService; +import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketInfoDTO; +import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirectInfoDTO; +import at.ac.uibk.gitsearch.web.rest.PluginInterfaceResource.SearchResultsDTOMapper; import java.io.IOException; import java.util.concurrent.TimeUnit; - import org.codeability.sharing.plugins.api.UserPrincipal; import org.codeability.sharing.plugins.api.search.SearchInputDTO; import org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO; @@ -29,14 +35,6 @@ import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.service.SearchService; -import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketInfoDTO; -import at.ac.uibk.gitsearch.service.ShoppingBasketService.ShoppingBasketRedirectInfoDTO; -import at.ac.uibk.gitsearch.web.rest.PluginInterfaceResource.SearchResultsDTOMapper; - /** * Integration tests for the {@link PluginInterfaceResource} REST controller. */ @@ -44,116 +42,162 @@ import at.ac.uibk.gitsearch.web.rest.PluginInterfaceResource.SearchResultsDTOMap @SpringBootTest(classes = GitsearchApp.class) public class PluginInterfaceResourceIT { - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } - + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } + @Value("${testing.testUser.name}") - private String userTestName; + private String userTestName; + @Value("${testing.testUser.gitLabToken}") - private String userTestToken; + private String userTestToken; + @Autowired private MockMvc restPluginInterfaceMockMvc; - + @Autowired private SearchService searchService; - - @Test @WithMockUser(authorities = AuthoritiesConstants.USER) public void testGetRedirectURL() throws Exception { - // just load everything from index :-) - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null,null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); - Assert.assertTrue("At least one hit?", searchResultPage.getSearchResult().size() >= 1); - - ShoppingBasketInfoDTO sbi = new ShoppingBasketInfoDTO(searchResultPage.getSearchResult().toArray(new SearchResultDTO[] {})); - - - restPluginInterfaceMockMvc.perform(post("/api//pluginIF/getPluginRedirectInfos") - .content(TestUtil.convertObjectToJsonBytes(sbi)) - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) + // just load everything from index :-) + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null, null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO searchResultPage = searchService.searchResultPage(searchQuery); + Assert.assertTrue("At least one hit?", searchResultPage.getSearchResult().size() >= 1); + + ShoppingBasketInfoDTO sbi = new ShoppingBasketInfoDTO(searchResultPage.getSearchResult().toArray(new SearchResultDTO[] {})); + + restPluginInterfaceMockMvc + .perform( + post("/api//pluginIF/getPluginRedirectInfos") + .content(TestUtil.convertObjectToJsonBytes(sbi)) + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) .andExpect(status().is2xxSuccessful()) - .andExpect(TestUtil.testResult(ShoppingBasketRedirectInfoDTO.class, - result -> { - String redirectURL = result.getRedirectURL(); - assertTrue(redirectURL.contains("returnURL=")); - assertTrue(redirectURL.contains("apiBaseURL=")); - // further checks would be nice - })); + .andExpect( + TestUtil.testResult( + ShoppingBasketRedirectInfoDTO.class, + result -> { + String redirectURL = result.getRedirectURL(); + assertTrue(redirectURL.contains("returnURL=")); + assertTrue(redirectURL.contains("apiBaseURL=")); + // further checks would be nice + } + ) + ); } - + @Test public void testSearchPageDetails() throws Exception { - - // searches for all :-) - - final org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO searchMetadata = new org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO(null, null, null, null, null, null); - final org.codeability.sharing.plugins.api.search.SearchInputDTO searchQuery = new org.codeability.sharing.plugins.api.search.SearchInputDTO(null, searchMetadata, null, null, null, 0); - - // This test may fail, if token is expired! - final SearchRequestDTO searchRequest = new SearchRequestDTO(new UserPrincipal(userTestName, userTestToken), searchQuery); - - - restPluginInterfaceMockMvc.perform(post("/api/pluginIF/v0.1/page-details") - .content(TestUtil.convertObjectToJsonBytes(searchRequest)) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) + // searches for all :-) + + final org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO searchMetadata = new org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO( + null, + null, + null, + null, + null, + null + ); + final org.codeability.sharing.plugins.api.search.SearchInputDTO searchQuery = new org.codeability.sharing.plugins.api.search.SearchInputDTO( + null, + searchMetadata, + null, + null, + null, + 0 + ); + + // This test may fail, if token is expired! + final SearchRequestDTO searchRequest = new SearchRequestDTO(new UserPrincipal(userTestName, userTestToken), searchQuery); + + restPluginInterfaceMockMvc + .perform( + post("/api/pluginIF/v0.1/page-details") + .content(TestUtil.convertObjectToJsonBytes(searchRequest)) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) .andExpect(status().is2xxSuccessful()) - .andExpect(TestUtil.testResult(org.codeability.sharing.plugins.api.search.SearchResultsDTO.class, - result -> { - // not really a good test :-( - assertTrue("At least three results", result.getSearchResult().size() >= 3); - })); + .andExpect( + TestUtil.testResult( + org.codeability.sharing.plugins.api.search.SearchResultsDTO.class, + result -> { + // not really a good test :-( + assertTrue("At least three results", result.getSearchResult().size() >= 3); + } + ) + ); } @Test public void testSearchPageDetailsWithInvalidToken() throws Exception { - - // searches for all :-) - - final org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO searchMetadata = new org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO(null, null, null, null, null, null); - final org.codeability.sharing.plugins.api.search.SearchInputDTO searchQuery = new org.codeability.sharing.plugins.api.search.SearchInputDTO(null, searchMetadata, null, null, null, 0); - - // This test may fail, if token is expired! - final SearchRequestDTO searchRequest = new SearchRequestDTO(new UserPrincipal("Michael Breu (with invalid Testtoken)", "XXXXX"), searchQuery); - - - restPluginInterfaceMockMvc.perform(post("/api/pluginIF/v0.1/page-details") - .content(TestUtil.convertObjectToJsonBytes(searchRequest)) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(print()) + // searches for all :-) + + final org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO searchMetadata = new org.codeability.sharing.plugins.api.search.SearchInputMetadataDTO( + null, + null, + null, + null, + null, + null + ); + final org.codeability.sharing.plugins.api.search.SearchInputDTO searchQuery = new org.codeability.sharing.plugins.api.search.SearchInputDTO( + null, + searchMetadata, + null, + null, + null, + 0 + ); + + // This test may fail, if token is expired! + final SearchRequestDTO searchRequest = new SearchRequestDTO( + new UserPrincipal("Michael Breu (with invalid Testtoken)", "XXXXX"), + searchQuery + ); + + restPluginInterfaceMockMvc + .perform( + post("/api/pluginIF/v0.1/page-details") + .content(TestUtil.convertObjectToJsonBytes(searchRequest)) + .contentType(MediaType.APPLICATION_JSON) + ) + .andDo(print()) .andExpect(status().is2xxSuccessful()) - .andExpect(TestUtil.testResult(org.codeability.sharing.plugins.api.search.SearchResultsDTO.class, - result -> { - // not really a good test :-( - assertTrue("Currently some public result", result.getSearchResult().size() >= 3); -// result.getSearchResult().forEach(r -> r.getProject()..getNamespace()); - })); + .andExpect( + TestUtil.testResult( + org.codeability.sharing.plugins.api.search.SearchResultsDTO.class, + result -> { + // not really a good test :-( + assertTrue("Currently some public result", result.getSearchResult().size() >= 3); + // result.getSearchResult().forEach(r -> r.getProject()..getNamespace()); + } + ) + ); } - /** * just a simple test of the results mapper @@ -161,24 +205,23 @@ public class PluginInterfaceResourceIT { @Test @WithMockUser(authorities = AuthoritiesConstants.USER) public void testSearchResultsMapper() throws IOException { - final SearchResultsDTOMapper resultsMapper = SearchResultsDTOMapper.INSTANCE; - - // just load everything from index :-) - final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null,null); - SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); - SearchResultsDTO results = searchService.searchResultPage(searchQuery); - Assert.assertTrue("At least one hit?", results.getSearchResult().size() >= 1); - - org.codeability.sharing.plugins.api.search.SearchResultsDTO mappedResults = resultsMapper.searchResultsToPlugin(results); - - // punktuelle Tests - Assert.assertEquals(results.getPageStartIndex(), mappedResults.getPageStartIndex()); - Assert.assertEquals(results.getHitCount(), mappedResults.getHitCount()); - Assert.assertEquals(results.getSearchResult().size(), mappedResults.getSearchResult().size()); - Assert.assertEquals(results.getSearchResult().get(0).getFile().getIndexing_date(), mappedResults.getSearchResult().get(0).getFile().getIndexing_date()); + final SearchResultsDTOMapper resultsMapper = SearchResultsDTOMapper.INSTANCE; + + // just load everything from index :-) + final SearchInputMetadataDTO searchMetadata = new SearchInputMetadataDTO(null, null, null, null, null, null); + SearchInputDTO searchQuery = new SearchInputDTO(null, searchMetadata, null, null, null, 0); + SearchResultsDTO results = searchService.searchResultPage(searchQuery); + Assert.assertTrue("At least one hit?", results.getSearchResult().size() >= 1); + + org.codeability.sharing.plugins.api.search.SearchResultsDTO mappedResults = resultsMapper.searchResultsToPlugin(results); + + // punktuelle Tests + Assert.assertEquals(results.getPageStartIndex(), mappedResults.getPageStartIndex()); + Assert.assertEquals(results.getHitCount(), mappedResults.getHitCount()); + Assert.assertEquals(results.getSearchResult().size(), mappedResults.getSearchResult().size()); + Assert.assertEquals( + results.getSearchResult().get(0).getFile().getIndexing_date(), + mappedResults.getSearchResult().get(0).getFile().getIndexing_date() + ); } - - - - } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/PublicUserResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/PublicUserResourceIT.java index 14bca5e6908dad229b3c356d7d0bac5ec7374f72..51ceeacdbdf114295a9ec11ab11484b3c079d95b 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/PublicUserResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/PublicUserResourceIT.java @@ -41,7 +41,7 @@ class PublicUserResourceIT { * @see at.ac.uibk.gitsearch.repository.search.UserSearchRepositoryMockConfiguration */ @SuppressWarnings("unused") - @Autowired + @Autowired private UserSearchRepository mockUserSearchRepository; @Autowired @@ -74,8 +74,7 @@ class PublicUserResourceIT { // Get all the users restUserMockMvc - .perform(get("/api/users?sort=id,desc").accept(MediaType.APPLICATION_JSON) - .with(csrf().asHeader())) + .perform(get("/api/users?sort=id,desc").accept(MediaType.APPLICATION_JSON).with(csrf().asHeader())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].login").value(hasItem(DEFAULT_LOGIN))) diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/SavedSearchesResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/SavedSearchesResourceIT.java index 4afa8fb02f17904a7c6868338548abeae0dfd006..e552daa1c72fb82fcffb3906a5affa138c564ffb 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/SavedSearchesResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/SavedSearchesResourceIT.java @@ -15,13 +15,18 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.IntegrationTest; +import at.ac.uibk.gitsearch.domain.SavedSearches; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.repository.SavedSearchesRepository; +import at.ac.uibk.gitsearch.repository.search.SavedSearchesSearchRepository; +import at.ac.uibk.gitsearch.service.dto.SavedSearchesDTO; +import at.ac.uibk.gitsearch.service.mapper.SavedSearchesMapper; import java.util.Collections; import java.util.List; import java.util.Random; import java.util.concurrent.atomic.AtomicLong; - import javax.persistence.EntityManager; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -35,14 +40,6 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.IntegrationTest; -import at.ac.uibk.gitsearch.domain.SavedSearches; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.repository.SavedSearchesRepository; -import at.ac.uibk.gitsearch.repository.search.SavedSearchesSearchRepository; -import at.ac.uibk.gitsearch.service.dto.SavedSearchesDTO; -import at.ac.uibk.gitsearch.service.mapper.SavedSearchesMapper; - /** * Integration tests for the {@link SavedSearchesResource} REST controller. */ @@ -132,8 +129,10 @@ class SavedSearchesResourceIT { SavedSearchesDTO savedSearchesDTO = savedSearchesMapper.toDto(savedSearches); restSavedSearchesMockMvc .perform( - post(ENTITY_API_URL).contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) + post(ENTITY_API_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) + .with(csrf().asHeader()) ) .andExpect(status().isCreated()); @@ -160,8 +159,11 @@ class SavedSearchesResourceIT { // An entity with an existing ID cannot be created, so this API call must fail restSavedSearchesMockMvc .perform( - post(ENTITY_API_URL).contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) ) + post(ENTITY_API_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); // Validate the SavedSearches in the database @@ -184,8 +186,11 @@ class SavedSearchesResourceIT { restSavedSearchesMockMvc .perform( - post(ENTITY_API_URL).contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) ) + post(ENTITY_API_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); List<SavedSearches> savedSearchesList = savedSearchesRepository.findAll(); @@ -204,8 +209,10 @@ class SavedSearchesResourceIT { restSavedSearchesMockMvc .perform( - post(ENTITY_API_URL).contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) + post(ENTITY_API_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) + .with(csrf().asHeader()) ) .andExpect(status().isBadRequest()); @@ -272,7 +279,8 @@ class SavedSearchesResourceIT { put(ENTITY_API_URL_ID, savedSearchesDTO.getId()) .contentType(MediaType.APPLICATION_JSON) .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) ) + .with(csrf().asHeader()) + ) .andExpect(status().isOk()); // Validate the SavedSearches in the database @@ -301,7 +309,8 @@ class SavedSearchesResourceIT { put(ENTITY_API_URL_ID, savedSearchesDTO.getId()) .contentType(MediaType.APPLICATION_JSON) .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) ) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); // Validate the SavedSearches in the database @@ -327,7 +336,8 @@ class SavedSearchesResourceIT { put(ENTITY_API_URL_ID, count.incrementAndGet()) .contentType(MediaType.APPLICATION_JSON) .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) ) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); // Validate the SavedSearches in the database @@ -350,8 +360,10 @@ class SavedSearchesResourceIT { // If url ID doesn't match entity ID, it will throw BadRequestAlertException restSavedSearchesMockMvc .perform( - put(ENTITY_API_URL).contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) + put(ENTITY_API_URL) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) + .with(csrf().asHeader()) ) .andExpect(status().isMethodNotAllowed()); @@ -382,7 +394,8 @@ class SavedSearchesResourceIT { patch(ENTITY_API_URL_ID, partialUpdatedSavedSearches.getId()) .contentType("application/merge-patch+json") .content(TestUtil.convertObjectToJsonBytes(partialUpdatedSavedSearches)) - .with(csrf().asHeader()) ) + .with(csrf().asHeader()) + ) .andExpect(status().isOk()); // Validate the SavedSearches in the database @@ -412,7 +425,8 @@ class SavedSearchesResourceIT { patch(ENTITY_API_URL_ID, partialUpdatedSavedSearches.getId()) .contentType("application/merge-patch+json") .content(TestUtil.convertObjectToJsonBytes(partialUpdatedSavedSearches)) - .with(csrf().asHeader()) ) + .with(csrf().asHeader()) + ) .andExpect(status().isOk()); // Validate the SavedSearches in the database @@ -438,7 +452,8 @@ class SavedSearchesResourceIT { patch(ENTITY_API_URL_ID, savedSearchesDTO.getId()) .contentType("application/merge-patch+json") .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) ) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); // Validate the SavedSearches in the database @@ -464,7 +479,8 @@ class SavedSearchesResourceIT { patch(ENTITY_API_URL_ID, count.incrementAndGet()) .contentType("application/merge-patch+json") .content(TestUtil.convertObjectToJsonBytes(savedSearchesDTO)) - .with(csrf().asHeader()) ) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); // Validate the SavedSearches in the database diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/SearchResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/SearchResourceIT.java index 8ccb218e6184e4f00949c8b36f8109ccc958dfd6..6d5aff504892c743b3549311341cf744e1fd2a38 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/SearchResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/SearchResourceIT.java @@ -8,9 +8,13 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; +import at.ac.uibk.gitsearch.web.rest.ExerciseResourceIT.StreamResultMatcher; import java.io.IOException; import java.util.concurrent.TimeUnit; - import org.elasticsearch.node.NodeValidationException; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; @@ -25,92 +29,114 @@ import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.service.dto.AutoCompleteEntry; -import at.ac.uibk.gitsearch.web.rest.ExerciseResourceIT.StreamResultMatcher; - /** * Integration tests for the {@link UserResource} REST controller. */ @AutoConfigureMockMvc -@WithMockUser(authorities = {AuthoritiesConstants.USER, "sharing"}) +@WithMockUser(authorities = { AuthoritiesConstants.USER, "sharing" }) @SpringBootTest(classes = GitsearchApp.class) public class SearchResourceIT { - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - @Autowired - private MockMvc restSearchMockMvc; + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } + @Autowired + private MockMvc restSearchMockMvc; @Test public void testKeywordsAutoComplete() throws Exception { - restSearchMockMvc.perform(get("/api/search/keywordsAutoComplete").param("keyWordPrefix", "Jav") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + restSearchMockMvc + .perform( + get("/api/search/keywordsAutoComplete") + .param("keyWordPrefix", "Jav") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) - .andExpect(TestUtil.testResult(AutoCompleteEntry[].class, r -> { - MatcherAssert.assertThat(r, Matchers.arrayContaining(hasProperty("target", is("Java")))); - })); + .andExpect( + TestUtil.testResult( + AutoCompleteEntry[].class, + r -> { + MatcherAssert.assertThat(r, Matchers.arrayContaining(hasProperty("target", is("Java")))); + } + ) + ); } - + @Test public void testCreatorContributorAutoComplete() throws Exception { - restSearchMockMvc.perform(get("/api/search/contributorCreatorAutoComplete").param("contributorPrefix", "Pod") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + restSearchMockMvc + .perform( + get("/api/search/contributorCreatorAutoComplete") + .param("contributorPrefix", "Pod") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) - .andExpect(TestUtil.testResult(AutoCompleteEntry[].class, r -> { - MatcherAssert.assertThat(r, Matchers.hasItemInArray(hasProperty("target", is("Stefan Podlipnig")))); - })); + .andExpect( + TestUtil.testResult( + AutoCompleteEntry[].class, + r -> { + MatcherAssert.assertThat(r, Matchers.hasItemInArray(hasProperty("target", is("Stefan Podlipnig")))); + } + ) + ); } @Test public void testProgrammingLanguageAutocompletion() throws Exception { - restSearchMockMvc.perform(get("/api/search/programmingLanguageAutoComplete").param("programmingLanguagePrefix", "Ja") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) - .andExpect(content().contentType(MediaType.APPLICATION_JSON)) + restSearchMockMvc + .perform( + get("/api/search/programmingLanguageAutoComplete") + .param("programmingLanguagePrefix", "Ja") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) - .andExpect(TestUtil.testResult(AutoCompleteEntry[].class, r -> { - MatcherAssert.assertThat(r, Matchers.hasItemInArray(hasProperty("target", is("JAVA")))); - })); + .andExpect( + TestUtil.testResult( + AutoCompleteEntry[].class, + r -> { + MatcherAssert.assertThat(r, Matchers.hasItemInArray(hasProperty("target", is("JAVA")))); + } + ) + ); } @Test public void getREADME() throws Exception { -// String exerciseId = "272"; // warning: this depends on the sequence in the current search index :-( -// restSearchMockMvc.perform(post("/api/exerciseFiles/"+exerciseId) - String exerciseId = "318"; // warning: this depends on the sequence in the current search index :-( - restSearchMockMvc.perform(post("/api/programming-exercises/"+exerciseId+"/export-programming-exercise") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) -// .andDo(print()) + // String exerciseId = "272"; // warning: this depends on the sequence in the current search index :-( + // restSearchMockMvc.perform(post("/api/exerciseFiles/"+exerciseId) + String exerciseId = "318"; // warning: this depends on the sequence in the current search index :-( + restSearchMockMvc + .perform( + post("/api/programming-exercises/" + exerciseId + "/export-programming-exercise") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + // .andDo(print()) .andExpect(status().is2xxSuccessful()) .andExpect(StreamResultMatcher.expectOctetStream()) .andExpect(StreamResultMatcher.expectMinimumSize(500)); diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/StatisticsResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/StatisticsResourceIT.java index c0cbbbc627dc8cbfda65d159e45d99811ce97f3b..482b266dd931b839de9863cf37ce35d443f4f003 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/StatisticsResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/StatisticsResourceIT.java @@ -14,13 +14,20 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.domain.Statistics; +import at.ac.uibk.gitsearch.repository.StatisticsRepository; +import at.ac.uibk.gitsearch.repository.search.StatisticsSearchRepository; +import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.service.StatisticsService; +import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; +import at.ac.uibk.gitsearch.service.mapper.StatisticsMapper; import java.io.IOException; import java.util.List; import java.util.Optional; import java.util.concurrent.TimeUnit; - import javax.persistence.EntityManager; - import org.elasticsearch.node.NodeValidationException; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeEach; @@ -38,16 +45,6 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.domain.Statistics; -import at.ac.uibk.gitsearch.repository.StatisticsRepository; -import at.ac.uibk.gitsearch.repository.search.StatisticsSearchRepository; -import at.ac.uibk.gitsearch.repository.search.testESService.ElasticSearchTestConfiguration; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.service.StatisticsService; -import at.ac.uibk.gitsearch.service.dto.StatisticsDTO; -import at.ac.uibk.gitsearch.service.mapper.StatisticsMapper; - /** * Integration tests for the {@link StatisticsResource} REST controller. */ @@ -65,7 +62,7 @@ public class StatisticsResourceIT { private static final String DEFAULT_EXERCISE_ID = "1"; private static final String UPDATED_EXERCISE_ID = "2"; - + final String publicGitLabProjectId = "3"; @Autowired @@ -94,27 +91,27 @@ public class StatisticsResourceIT { private Statistics statistics; - @Autowired - ElasticSearchTestConfiguration elasticSearchTestConfiguration; - - static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; - - @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration - @Timeout(value = 2, unit = TimeUnit.MINUTES) - public void setUpESServer() throws IOException, NodeValidationException { - if(staticElasticSearchTestConfiguration == null) { - elasticSearchTestConfiguration.startTestNode(); - staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; - } - } - - @AfterAll - public static void shutDownESServer() { - if(staticElasticSearchTestConfiguration!=null) { - staticElasticSearchTestConfiguration.stopTestContainer(); - staticElasticSearchTestConfiguration = null; - } - } + @Autowired + ElasticSearchTestConfiguration elasticSearchTestConfiguration; + + static ElasticSearchTestConfiguration staticElasticSearchTestConfiguration; + + @BeforeEach // must be started as BeforeEach, in order to autowire the ElasticSearchTestConfiguration + @Timeout(value = 2, unit = TimeUnit.MINUTES) + public void setUpESServer() throws IOException, NodeValidationException { + if (staticElasticSearchTestConfiguration == null) { + elasticSearchTestConfiguration.startTestNode(); + staticElasticSearchTestConfiguration = elasticSearchTestConfiguration; + } + } + + @AfterAll + public static void shutDownESServer() { + if (staticElasticSearchTestConfiguration != null) { + staticElasticSearchTestConfiguration.stopTestContainer(); + staticElasticSearchTestConfiguration = null; + } + } /** * Create an entity for this test. @@ -123,8 +120,7 @@ public class StatisticsResourceIT { * they test an entity which requires the current entity. */ public static Statistics createEntity(EntityManager em) { - Statistics statistics = new Statistics().views(DEFAULT_VIEWS).downloads(DEFAULT_DOWNLOADS) - .exerciseID(DEFAULT_EXERCISE_ID); + Statistics statistics = new Statistics().views(DEFAULT_VIEWS).downloads(DEFAULT_DOWNLOADS).exerciseID(DEFAULT_EXERCISE_ID); return statistics; } @@ -135,8 +131,7 @@ public class StatisticsResourceIT { * they test an entity which requires the current entity. */ public static Statistics createUpdatedEntity(EntityManager em) { - Statistics statistics = new Statistics().views(UPDATED_VIEWS).downloads(UPDATED_DOWNLOADS) - .exerciseID(UPDATED_EXERCISE_ID); + Statistics statistics = new Statistics().views(UPDATED_VIEWS).downloads(UPDATED_DOWNLOADS).exerciseID(UPDATED_EXERCISE_ID); return statistics; } @@ -152,9 +147,14 @@ public class StatisticsResourceIT { int databaseSizeBeforeCreate = statisticsRepository.findAll().size(); // Create the Statistics StatisticsDTO statisticsDTO = statisticsMapper.toDto(statistics); - restStatisticsMockMvc.perform(post("/api/statistics").with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(statisticsDTO))) - .andExpect(status().isCreated()); + restStatisticsMockMvc + .perform( + post("/api/statistics") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(statisticsDTO)) + ) + .andExpect(status().isCreated()); // Validate the Statistics in the database List<Statistics> statisticsList = statisticsRepository.findAll(); @@ -179,9 +179,14 @@ public class StatisticsResourceIT { StatisticsDTO statisticsDTO = statisticsMapper.toDto(statistics); // An entity with an existing ID cannot be created, so this API call must fail - restStatisticsMockMvc.perform(post("/api/statistics").with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(statisticsDTO))) - .andExpect(status().isBadRequest()); + restStatisticsMockMvc + .perform( + post("/api/statistics") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(statisticsDTO)) + ) + .andExpect(status().isBadRequest()); // Validate the Statistics in the database List<Statistics> statisticsList = statisticsRepository.findAll(); @@ -191,7 +196,6 @@ public class StatisticsResourceIT { verify(mockStatisticsSearchRepository, times(0)).save(statistics); } - @Test @Transactional @WithMockUser(authorities = AuthoritiesConstants.ADMIN) @@ -200,12 +204,14 @@ public class StatisticsResourceIT { statisticsRepository.saveAndFlush(statistics); // Get all the statisticsList - restStatisticsMockMvc.perform(get("/api/statistics?sort=id,desc").with(csrf().asHeader())).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.[*].id").value(hasItem(statistics.getId().intValue()))) - .andExpect(jsonPath("$.[*].views").value(hasItem(DEFAULT_VIEWS))) - .andExpect(jsonPath("$.[*].downloads").value(hasItem((int)(long)DEFAULT_DOWNLOADS))) - .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); + restStatisticsMockMvc + .perform(get("/api/statistics?sort=id,desc").with(csrf().asHeader())) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.[*].id").value(hasItem(statistics.getId().intValue()))) + .andExpect(jsonPath("$.[*].views").value(hasItem(DEFAULT_VIEWS))) + .andExpect(jsonPath("$.[*].downloads").value(hasItem((int) (long) DEFAULT_DOWNLOADS))) + .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); } @Test @@ -216,12 +222,14 @@ public class StatisticsResourceIT { statisticsRepository.saveAndFlush(statistics); // Get the statistics - restStatisticsMockMvc.perform(get("/api/statistics/{id}", statistics.getId()).with(csrf().asHeader())).andExpect(status().isOk()) - .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) - .andExpect(jsonPath("$.id").value(statistics.getId().intValue())) - .andExpect(jsonPath("$.views").value(DEFAULT_VIEWS)) - .andExpect(jsonPath("$.downloads").value(DEFAULT_DOWNLOADS)) - .andExpect(jsonPath("$.exerciseID").value(DEFAULT_EXERCISE_ID)); + restStatisticsMockMvc + .perform(get("/api/statistics/{id}", statistics.getId()).with(csrf().asHeader())) + .andExpect(status().isOk()) + .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + .andExpect(jsonPath("$.id").value(statistics.getId().intValue())) + .andExpect(jsonPath("$.views").value(DEFAULT_VIEWS)) + .andExpect(jsonPath("$.downloads").value(DEFAULT_DOWNLOADS)) + .andExpect(jsonPath("$.exerciseID").value(DEFAULT_EXERCISE_ID)); } @Test @@ -233,10 +241,8 @@ public class StatisticsResourceIT { // Get the statistics restStatisticsMockMvc.perform(get("/user/achievements").with(csrf().asHeader())).andExpect(status().isOk()); - } - @Test @Transactional @WithMockUser(authorities = AuthoritiesConstants.ADMIN) @@ -262,8 +268,14 @@ public class StatisticsResourceIT { updatedStatistics.views(UPDATED_VIEWS).downloads(UPDATED_DOWNLOADS).exerciseID(UPDATED_EXERCISE_ID); StatisticsDTO statisticsDTO = statisticsMapper.toDto(updatedStatistics); - restStatisticsMockMvc.perform(put("/api/statistics").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(statisticsDTO))).andExpect(status().isOk()); + restStatisticsMockMvc + .perform( + put("/api/statistics") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(statisticsDTO)) + ) + .andExpect(status().isOk()); // Validate the Statistics in the database List<Statistics> statisticsList = statisticsRepository.findAll(); @@ -287,8 +299,14 @@ public class StatisticsResourceIT { StatisticsDTO statisticsDTO = statisticsMapper.toDto(statistics); // If the entity doesn't have an ID, it will throw BadRequestAlertException - restStatisticsMockMvc.perform(put("/api/statistics").with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(statisticsDTO))).andExpect(status().isBadRequest()); + restStatisticsMockMvc + .perform( + put("/api/statistics") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(statisticsDTO)) + ) + .andExpect(status().isBadRequest()); // Validate the Statistics in the database List<Statistics> statisticsList = statisticsRepository.findAll(); @@ -309,8 +327,8 @@ public class StatisticsResourceIT { // Delete the statistics restStatisticsMockMvc - .perform(delete("/api/statistics/{id}", statistics.getId()).with(csrf().asHeader()).accept(MediaType.APPLICATION_JSON)) - .andExpect(status().isNoContent()); + .perform(delete("/api/statistics/{id}", statistics.getId()).with(csrf().asHeader()).accept(MediaType.APPLICATION_JSON)) + .andExpect(status().isNoContent()); // Validate the database contains one less item List<Statistics> statisticsList = statisticsRepository.findAll(); @@ -320,31 +338,29 @@ public class StatisticsResourceIT { verify(mockStatisticsSearchRepository, times(1)).deleteById(statistics.getId()); } -// @Test -// @Transactional -// @WithMockUser(authorities = AuthoritiesConstants.ADMIN) -// public void searchStatistics() throws Exception { -// // Configure the mock search repository -// // Initialize the database -// statisticsRepository.saveAndFlush(statistics); -// when(mockStatisticsSearchRepository.search(queryStringQuery("id:" + statistics.getId()), PageRequest.of(0, 20))) -// .thenReturn(new PageImpl<>(Collections.singletonList(statistics), PageRequest.of(0, 1), 1)); -// -// // Search the statistics -// restStatisticsMockMvc.perform(get("/api/_search/statistics?query=id:" + statistics.getId()).with(csrf().asHeader())) -// .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) -// .andExpect(jsonPath("$.[*].id").value(hasItem(statistics.getId().intValue()))) -// .andExpect(jsonPath("$.[*].views").value(hasItem(DEFAULT_VIEWS))) -// .andExpect(jsonPath("$.[*].downloads").value(hasItem(DEFAULT_DOWNLOADS))) -// .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); -// } + // @Test + // @Transactional + // @WithMockUser(authorities = AuthoritiesConstants.ADMIN) + // public void searchStatistics() throws Exception { + // // Configure the mock search repository + // // Initialize the database + // statisticsRepository.saveAndFlush(statistics); + // when(mockStatisticsSearchRepository.search(queryStringQuery("id:" + statistics.getId()), PageRequest.of(0, 20))) + // .thenReturn(new PageImpl<>(Collections.singletonList(statistics), PageRequest.of(0, 1), 1)); + // + // // Search the statistics + // restStatisticsMockMvc.perform(get("/api/_search/statistics?query=id:" + statistics.getId()).with(csrf().asHeader())) + // .andExpect(status().isOk()).andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + // .andExpect(jsonPath("$.[*].id").value(hasItem(statistics.getId().intValue()))) + // .andExpect(jsonPath("$.[*].views").value(hasItem(DEFAULT_VIEWS))) + // .andExpect(jsonPath("$.[*].downloads").value(hasItem(DEFAULT_DOWNLOADS))) + // .andExpect(jsonPath("$.[*].exerciseID").value(hasItem(DEFAULT_EXERCISE_ID))); + // } @Test @Transactional @WithMockUser(authorities = AuthoritiesConstants.ADMIN) public void getStatisticsByExerciseId() throws Exception { - - // Get the statistics and see if it coincides with the mock stats statisticsRepository.deleteAll(); @@ -357,29 +373,23 @@ public class StatisticsResourceIT { restStatisticsMockMvc.perform(get("/api/statistics/exercise/{id}", "143").with(csrf().asHeader())).andExpect(status().isOk()); assertEquals(statisticsService.findOneByExerciseID("143").get().getViews(), 2); - //Test the search for an id which does not exist - assertEquals(Optional.empty(),statisticsService.findOneByExerciseID("notThere")); - + assertEquals(Optional.empty(), statisticsService.findOneByExerciseID("notThere")); } - @ParameterizedTest - @ValueSource(strings = {"3:with/path"}) + @ValueSource(strings = { "3:with/path" }) @Transactional @WithMockUser(authorities = AuthoritiesConstants.ADMIN) public void createStatisticsByExerciseIdNotFoundWithES(String exerciseId) throws Exception { // Initialize the database statisticsRepository.saveAndFlush(statistics); - restStatisticsMockMvc.perform(get("/api/statistics/exercise/{id}", exerciseId).with(csrf().asHeader())).andExpect(status().isNotFound()); - - + restStatisticsMockMvc + .perform(get("/api/statistics/exercise/{id}", exerciseId).with(csrf().asHeader())) + .andExpect(status().isNotFound()); + // Get the statistics and see if it is found - assertEquals(Optional.empty(),statisticsService.findOneByExerciseID(exerciseId)); + assertEquals(Optional.empty(), statisticsService.findOneByExerciseID(exerciseId)); } - - - - } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/TestUtil.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/TestUtil.java index 4ccc4dfca27d1884726db9b779f5187a43be9567..60be533a4f8e86cb741f321740e7c9813f986f02 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/TestUtil.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/TestUtil.java @@ -12,7 +12,6 @@ import java.time.ZonedDateTime; import java.time.format.DateTimeParseException; import java.util.List; import java.util.function.Consumer; - import javax.persistence.EntityManager; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; @@ -215,16 +214,15 @@ public final class TestUtil { * @param tester a set of tests (as a Consumer object) * @return the result matcher */ - public static <T> ResultMatcher testResult(Class<T> c, Consumer<T> tester) { - return new ResultMatcher() { - - @Override - public void match(MvcResult result) throws Exception { - ObjectMapper objectMapper = new ObjectMapper(); - objectMapper.registerModule(new JavaTimeModule()); - T jsonStructure = objectMapper.readValue(result.getResponse().getContentAsString(), c); - tester.accept(jsonStructure); - } - }; - } + public static <T> ResultMatcher testResult(Class<T> c, Consumer<T> tester) { + return new ResultMatcher() { + @Override + public void match(MvcResult result) throws Exception { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.registerModule(new JavaTimeModule()); + T jsonStructure = objectMapper.readValue(result.getResponse().getContentAsString(), c); + tester.accept(jsonStructure); + } + }; + } } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/UserJWTControllerIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/UserJWTControllerIT.java index 477a3d16628a3b7ab6163baa7df7a9f86488e9c9..279926f0d9b4241c002abd0ffc601fbb35a8ccee 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/UserJWTControllerIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/UserJWTControllerIT.java @@ -53,8 +53,12 @@ class UserJWTControllerIT { login.setUsername("user-jwt-controller"); login.setPassword("test"); mockMvc - .perform(post("/api/authenticate").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(login) - ).with(csrf().asHeader())) + .perform( + post("/api/authenticate") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(login)) + .with(csrf().asHeader()) + ) .andExpect(status().isOk()) .andExpect(jsonPath("$.id_token").isString()) .andExpect(jsonPath("$.id_token").isNotEmpty()) @@ -79,9 +83,11 @@ class UserJWTControllerIT { login.setRememberMe(true); mockMvc .perform( - post("/api/authenticate").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(login)) - .with(csrf().asHeader()) - ) + post("/api/authenticate") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(login)) + .with(csrf().asHeader()) + ) .andExpect(status().isOk()) .andExpect(jsonPath("$.id_token").isString()) .andExpect(jsonPath("$.id_token").isNotEmpty()) @@ -96,8 +102,11 @@ class UserJWTControllerIT { login.setPassword("wrong password"); mockMvc .perform( - post("/api/authenticate").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(login)) - .with(csrf().asHeader())) + post("/api/authenticate") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(login)) + .with(csrf().asHeader()) + ) .andExpect(status().isUnauthorized()) .andExpect(jsonPath("$.id_token").doesNotExist()) .andExpect(header().doesNotExist("Authorization")); diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/UserResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/UserResourceIT.java index fbbd863052abf2dc3e7c9814ac86073f795b0491..2d06f80b25e2f8ada7ac477233f09210d1b78668 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/UserResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/UserResourceIT.java @@ -11,15 +11,22 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.IntegrationTest; +import at.ac.uibk.gitsearch.domain.Authority; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.repository.UserRepository; +import at.ac.uibk.gitsearch.repository.search.UserSearchRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; +import at.ac.uibk.gitsearch.service.mapper.UserMapper; +import at.ac.uibk.gitsearch.web.rest.vm.ManagedUserVM; import java.time.Instant; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.function.Consumer; - import javax.persistence.EntityManager; - import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -31,16 +38,6 @@ import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.IntegrationTest; -import at.ac.uibk.gitsearch.domain.Authority; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.repository.UserRepository; -import at.ac.uibk.gitsearch.repository.search.UserSearchRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.service.dto.AdminUserDTO; -import at.ac.uibk.gitsearch.service.mapper.UserMapper; -import at.ac.uibk.gitsearch.web.rest.vm.ManagedUserVM; - /** * Integration tests for the {@link UserResource} REST controller. */ @@ -156,8 +153,10 @@ class UserResourceIT { restUserMockMvc .perform( - post("/api/admin/users").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(managedUserVM)) - .with(csrf().asHeader()) + post("/api/admin/users") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM)) + .with(csrf().asHeader()) ) .andExpect(status().isCreated()); @@ -194,8 +193,10 @@ class UserResourceIT { // An entity with an existing ID cannot be created, so this API call must fail restUserMockMvc .perform( - post("/api/admin/users").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(managedUserVM)) - .with(csrf().asHeader()) + post("/api/admin/users") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM)) + .with(csrf().asHeader()) ) .andExpect(status().isBadRequest()); @@ -225,8 +226,10 @@ class UserResourceIT { // Create the User restUserMockMvc .perform( - post("/api/admin/users").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(managedUserVM)) - .with(csrf().asHeader()) + post("/api/admin/users") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM)) + .with(csrf().asHeader()) ) .andExpect(status().isBadRequest()); @@ -256,8 +259,11 @@ class UserResourceIT { // Create the User restUserMockMvc .perform( - post("/api/admin/users").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(managedUserVM)) - .with(csrf().asHeader()) ) + post("/api/admin/users") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM)) + .with(csrf().asHeader()) + ) .andExpect(status().isBadRequest()); // Validate the User in the database @@ -342,8 +348,10 @@ class UserResourceIT { restUserMockMvc .perform( - put("/api/admin/users").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(managedUserVM)) - .with(csrf().asHeader()) + put("/api/admin/users") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM)) + .with(csrf().asHeader()) ) .andExpect(status().isOk()); @@ -387,8 +395,10 @@ class UserResourceIT { restUserMockMvc .perform( - put("/api/admin/users").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(managedUserVM)) - .with(csrf().asHeader()) + put("/api/admin/users") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM)) + .with(csrf().asHeader()) ) .andExpect(status().isOk()); @@ -445,8 +455,10 @@ class UserResourceIT { restUserMockMvc .perform( - put("/api/admin/users").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(managedUserVM)) - .with(csrf().asHeader()) + put("/api/admin/users") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM)) + .with(csrf().asHeader()) ) .andExpect(status().isBadRequest()); } @@ -491,8 +503,10 @@ class UserResourceIT { restUserMockMvc .perform( - put("/api/admin/users").contentType(MediaType.APPLICATION_JSON).content(TestUtil.convertObjectToJsonBytes(managedUserVM)) - .with(csrf().asHeader()) + put("/api/admin/users") + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(managedUserVM)) + .with(csrf().asHeader()) ) .andExpect(status().isBadRequest()); } @@ -506,8 +520,7 @@ class UserResourceIT { // Delete the user restUserMockMvc - .perform(delete("/api/admin/users/{login}", user.getLogin()).accept(MediaType.APPLICATION_JSON) - .with(csrf().asHeader())) + .perform(delete("/api/admin/users/{login}", user.getLogin()).accept(MediaType.APPLICATION_JSON).with(csrf().asHeader())) .andExpect(status().isNoContent()); assertThat(cacheManager.getCache(UserRepository.USERS_BY_LOGIN_CACHE).get(user.getLogin())).isNull(); diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/UserWatchListResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/UserWatchListResourceIT.java index 207155da33922c67d94dda42ec8a3c9f7a514c56..4065d1fd3f428e5bdc5d65666eef224924d78587 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/UserWatchListResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/UserWatchListResourceIT.java @@ -11,10 +11,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.domain.User; +import at.ac.uibk.gitsearch.domain.UserWatchList; +import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; +import at.ac.uibk.gitsearch.repository.UserWatchListRepository; +import at.ac.uibk.gitsearch.security.AuthoritiesConstants; +import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; +import at.ac.uibk.gitsearch.service.mapper.UserWatchListMapper; import java.util.List; - import javax.persistence.EntityManager; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -28,14 +34,6 @@ import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequ import org.springframework.test.web.servlet.MockMvc; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.domain.User; -import at.ac.uibk.gitsearch.domain.UserWatchList; -import at.ac.uibk.gitsearch.domain.enumeration.CheckFrequency; -import at.ac.uibk.gitsearch.repository.UserWatchListRepository; -import at.ac.uibk.gitsearch.security.AuthoritiesConstants; -import at.ac.uibk.gitsearch.service.dto.UserWatchListDTO; -import at.ac.uibk.gitsearch.service.mapper.UserWatchListMapper; /** * Integration tests for the {@link UserWatchListResource} REST controller. */ @@ -72,9 +70,7 @@ public class UserWatchListResourceIT { * if they test an entity which requires the current entity. */ public static UserWatchList createEntity(EntityManager em) { - UserWatchList userWatchList = new UserWatchList() - .name(DEFAULT_NAME) - .checkFrequency(DEFAULT_CHECK_FREQUENCY); + UserWatchList userWatchList = new UserWatchList().name(DEFAULT_NAME).checkFrequency(DEFAULT_CHECK_FREQUENCY); // Add required entity User user = UserResourceIT.createEntity(em); em.persist(user); @@ -82,6 +78,7 @@ public class UserWatchListResourceIT { userWatchList.setUser(user); return userWatchList; } + /** * Create an updated entity for this test. * @@ -89,9 +86,7 @@ public class UserWatchListResourceIT { * if they test an entity which requires the current entity. */ public static UserWatchList createUpdatedEntity(EntityManager em) { - UserWatchList userWatchList = new UserWatchList() - .name(UPDATED_NAME) - .checkFrequency(UPDATED_CHECK_FREQUENCY); + UserWatchList userWatchList = new UserWatchList().name(UPDATED_NAME).checkFrequency(UPDATED_CHECK_FREQUENCY); // Add required entity User user = UserResourceIT.createEntity(em); em.persist(user); @@ -111,10 +106,13 @@ public class UserWatchListResourceIT { int databaseSizeBeforeCreate = userWatchListRepository.findAll().size(); // Create the UserWatchList UserWatchListDTO userWatchListDTO = userWatchListMapper.toDto(userWatchList); - restUserWatchListMockMvc.perform(post("/api/user-watch-lists") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO))) + restUserWatchListMockMvc + .perform( + post("/api/user-watch-lists") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO)) + ) .andExpect(status().isCreated()); // Validate the UserWatchList in the database @@ -123,7 +121,6 @@ public class UserWatchListResourceIT { UserWatchList testUserWatchList = userWatchListList.get(userWatchListList.size() - 1); assertThat(testUserWatchList.getName()).isEqualTo(DEFAULT_NAME); assertThat(testUserWatchList.getCheckFrequency()).isEqualTo(DEFAULT_CHECK_FREQUENCY); - } @Test @@ -136,19 +133,20 @@ public class UserWatchListResourceIT { UserWatchListDTO userWatchListDTO = userWatchListMapper.toDto(userWatchList); // An entity with an existing ID cannot be created, so this API call must fail - restUserWatchListMockMvc.perform(post("/api/user-watch-lists") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO))) + restUserWatchListMockMvc + .perform( + post("/api/user-watch-lists") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO)) + ) .andExpect(status().isBadRequest()); // Validate the UserWatchList in the database List<UserWatchList> userWatchListList = userWatchListRepository.findAll(); assertThat(userWatchListList).hasSize(databaseSizeBeforeCreate); - } - @Test @Transactional public void checkNameIsRequired() throws Exception { @@ -159,11 +157,13 @@ public class UserWatchListResourceIT { // Create the UserWatchList, which fails. UserWatchListDTO userWatchListDTO = userWatchListMapper.toDto(userWatchList); - - restUserWatchListMockMvc.perform(post("/api/user-watch-lists") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO))) + restUserWatchListMockMvc + .perform( + post("/api/user-watch-lists") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO)) + ) .andExpect(status().isBadRequest()); List<UserWatchList> userWatchListList = userWatchListRepository.findAll(); @@ -180,11 +180,13 @@ public class UserWatchListResourceIT { // Create the UserWatchList, which fails. UserWatchListDTO userWatchListDTO = userWatchListMapper.toDto(userWatchList); - - restUserWatchListMockMvc.perform(post("/api/user-watch-lists") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO))) + restUserWatchListMockMvc + .perform( + post("/api/user-watch-lists") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO)) + ) .andExpect(status().isBadRequest()); List<UserWatchList> userWatchListList = userWatchListRepository.findAll(); @@ -198,14 +200,15 @@ public class UserWatchListResourceIT { userWatchListRepository.saveAndFlush(userWatchList); // Get all the userWatchListList - restUserWatchListMockMvc.perform(get("/api/user-watch-lists?sort=id,desc")) + restUserWatchListMockMvc + .perform(get("/api/user-watch-lists?sort=id,desc")) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].id").value(hasItem(userWatchList.getId().intValue()))) .andExpect(jsonPath("$.[*].name").value(hasItem(DEFAULT_NAME))) .andExpect(jsonPath("$.[*].checkFrequency").value(hasItem(DEFAULT_CHECK_FREQUENCY.toString()))); } - + @Test @Transactional public void getUserWatchList() throws Exception { @@ -213,7 +216,8 @@ public class UserWatchListResourceIT { userWatchListRepository.saveAndFlush(userWatchList); // Get the userWatchList - restUserWatchListMockMvc.perform(get("/api/user-watch-lists/{id}", userWatchList.getId())) + restUserWatchListMockMvc + .perform(get("/api/user-watch-lists/{id}", userWatchList.getId())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.id").value(userWatchList.getId().intValue())) @@ -221,7 +225,6 @@ public class UserWatchListResourceIT { .andExpect(jsonPath("$.checkFrequency").value(DEFAULT_CHECK_FREQUENCY.toString())); } - @Test @Transactional public void getUserWatchListsByIdFiltering() throws Exception { @@ -240,7 +243,6 @@ public class UserWatchListResourceIT { defaultUserWatchListShouldNotBeFound("id.lessThan=" + id); } - @Test @Transactional public void getAllUserWatchListsByNameIsEqualToSomething() throws Exception { @@ -292,7 +294,8 @@ public class UserWatchListResourceIT { // Get all the userWatchListList where name is null defaultUserWatchListShouldNotBeFound("name.specified=false"); } - @Test + + @Test @Transactional public void getAllUserWatchListsByNameContainsSomething() throws Exception { // Initialize the database @@ -318,7 +321,6 @@ public class UserWatchListResourceIT { defaultUserWatchListShouldBeFound("name.doesNotContain=" + UPDATED_NAME); } - @Test @Transactional public void getAllUserWatchListsByCheckFrequencyIsEqualToSomething() throws Exception { @@ -390,9 +392,8 @@ public class UserWatchListResourceIT { * Executes the search, and checks that the default entity is returned. */ private void defaultUserWatchListShouldBeFound(String filter) throws Exception { - restUserWatchListMockMvc.perform(get("/api/user-watch-lists?sort=id,desc&" + filter) - .with(csrf().asHeader()) - ) + restUserWatchListMockMvc + .perform(get("/api/user-watch-lists?sort=id,desc&" + filter).with(csrf().asHeader())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].id").value(hasItem(userWatchList.getId().intValue()))) @@ -400,9 +401,8 @@ public class UserWatchListResourceIT { .andExpect(jsonPath("$.[*].checkFrequency").value(hasItem(DEFAULT_CHECK_FREQUENCY.toString()))); // Check, that the count call also returns 1 - restUserWatchListMockMvc.perform(get("/api/user-watch-lists/count?sort=id,desc&" + filter) - .with(csrf().asHeader()) - ) + restUserWatchListMockMvc + .perform(get("/api/user-watch-lists/count?sort=id,desc&" + filter).with(csrf().asHeader())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().string("1")); @@ -412,18 +412,16 @@ public class UserWatchListResourceIT { * Executes the search, and checks that the default entity is not returned. */ private void defaultUserWatchListShouldNotBeFound(String filter) throws Exception { - restUserWatchListMockMvc.perform(get("/api/user-watch-lists?sort=id,desc&" + filter) .with(csrf().asHeader()) - .with(csrf().asHeader()) - ) + restUserWatchListMockMvc + .perform(get("/api/user-watch-lists?sort=id,desc&" + filter).with(csrf().asHeader()).with(csrf().asHeader())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$").isArray()) .andExpect(jsonPath("$").isEmpty()); // Check, that the count call also returns 0 - restUserWatchListMockMvc.perform(get("/api/user-watch-lists/count?sort=id,desc&" + filter) - .with(csrf().asHeader()) -) + restUserWatchListMockMvc + .perform(get("/api/user-watch-lists/count?sort=id,desc&" + filter).with(csrf().asHeader())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(content().string("0")); @@ -433,8 +431,7 @@ public class UserWatchListResourceIT { @Transactional public void getNonExistingUserWatchList() throws Exception { // Get the userWatchList - restUserWatchListMockMvc.perform(get("/api/user-watch-lists/{id}", Long.MAX_VALUE)) - .andExpect(status().isNotFound()); + restUserWatchListMockMvc.perform(get("/api/user-watch-lists/{id}", Long.MAX_VALUE)).andExpect(status().isNotFound()); } @Test @@ -449,15 +446,16 @@ public class UserWatchListResourceIT { UserWatchList updatedUserWatchList = userWatchListRepository.findById(userWatchList.getId()).get(); // Disconnect from session so that the updates on updatedUserWatchList are not directly saved in db em.detach(updatedUserWatchList); - updatedUserWatchList - .name(UPDATED_NAME) - .checkFrequency(UPDATED_CHECK_FREQUENCY); + updatedUserWatchList.name(UPDATED_NAME).checkFrequency(UPDATED_CHECK_FREQUENCY); UserWatchListDTO userWatchListDTO = userWatchListMapper.toDto(updatedUserWatchList); - restUserWatchListMockMvc.perform(put("/api/user-watch-lists") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO))) + restUserWatchListMockMvc + .perform( + put("/api/user-watch-lists") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO)) + ) .andExpect(status().isOk()); // Validate the UserWatchList in the database @@ -479,10 +477,13 @@ public class UserWatchListResourceIT { userWatchListDTO.setId(Long.MAX_VALUE); // If the entity doesn't have an ID, it will throw BadRequestAlertException - restUserWatchListMockMvc.perform(put("/api/user-watch-lists") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO))) + restUserWatchListMockMvc + .perform( + put("/api/user-watch-lists") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO)) + ) .andExpect(status().isBadRequest()); // Validate the UserWatchList in the database @@ -500,10 +501,13 @@ public class UserWatchListResourceIT { userWatchListDTO.setId(null); // If the entity doesn't have an ID, it will throw BadRequestAlertException - restUserWatchListMockMvc.perform(put("/api/user-watch-lists") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO))) + restUserWatchListMockMvc + .perform( + put("/api/user-watch-lists") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO)) + ) .andExpect(status().isBadRequest()); // Validate the UserWatchList in the database @@ -520,35 +524,36 @@ public class UserWatchListResourceIT { int databaseSizeBeforeDelete = userWatchListRepository.findAll().size(); // Delete the userWatchList - restUserWatchListMockMvc.perform(delete("/api/user-watch-lists/{id}", userWatchList.getId()) - .with(csrf().asHeader()) - .accept(MediaType.APPLICATION_JSON)) + restUserWatchListMockMvc + .perform(delete("/api/user-watch-lists/{id}", userWatchList.getId()).with(csrf().asHeader()).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNoContent()); // Validate the database contains one less item List<UserWatchList> userWatchListList = userWatchListRepository.findAll(); assertThat(userWatchListList).hasSize(databaseSizeBeforeDelete - 1); } - + @Test @Transactional public void createUserWatchListForCurrentUser() throws Exception { - final UserWatchListDTO userWatchListDTO = userWatchListMapper.toDto(userWatchList); + final UserWatchListDTO userWatchListDTO = userWatchListMapper.toDto(userWatchList); - int databaseSizeBeforeCreate = userWatchListRepository.findAll().size(); + int databaseSizeBeforeCreate = userWatchListRepository.findAll().size(); // Delete the userWatchList - restUserWatchListMockMvc.perform(post("/api/currentuser-watch-lists", userWatchListDTO) - .with(SecurityMockMvcRequestPostProcessors.user(userWatchList.getUser().getLogin())) - .with(csrf().asHeader()) - .accept(MediaType.APPLICATION_JSON) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO))) - .andExpect(status().isCreated()); + restUserWatchListMockMvc + .perform( + post("/api/currentuser-watch-lists", userWatchListDTO) + .with(SecurityMockMvcRequestPostProcessors.user(userWatchList.getUser().getLogin())) + .with(csrf().asHeader()) + .accept(MediaType.APPLICATION_JSON) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(userWatchListDTO)) + ) + .andExpect(status().isCreated()); // Validate the database contains this watchlist List<UserWatchList> userWatchListList = userWatchListRepository.findAll(); - + assertThat(userWatchListList).hasSize(databaseSizeBeforeCreate + 1); } - } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/WatchListEntryResourceIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/WatchListEntryResourceIT.java index 4e6a8d11426165daa5bfda035e7d3c13b6a7bfa9..ce4ab5411d90d3a6c8734ed533db507ed9cb26ea 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/WatchListEntryResourceIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/WatchListEntryResourceIT.java @@ -14,10 +14,16 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.GitsearchApp; +import at.ac.uibk.gitsearch.domain.UserWatchList; +import at.ac.uibk.gitsearch.domain.WatchListEntry; +import at.ac.uibk.gitsearch.repository.WatchListEntryRepository; +import at.ac.uibk.gitsearch.repository.search.WatchListEntrySearchRepository; +import at.ac.uibk.gitsearch.service.WatchListEntryService; +import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; +import at.ac.uibk.gitsearch.service.mapper.WatchListEntryMapper; import java.util.List; - import javax.persistence.EntityManager; - import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -31,15 +37,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.MvcResult; import org.springframework.transaction.annotation.Transactional; -import at.ac.uibk.gitsearch.GitsearchApp; -import at.ac.uibk.gitsearch.domain.UserWatchList; -import at.ac.uibk.gitsearch.domain.WatchListEntry; -import at.ac.uibk.gitsearch.repository.WatchListEntryRepository; -import at.ac.uibk.gitsearch.repository.search.WatchListEntrySearchRepository; -import at.ac.uibk.gitsearch.service.WatchListEntryService; -import at.ac.uibk.gitsearch.service.dto.WatchListEntryDTO; -import at.ac.uibk.gitsearch.service.mapper.WatchListEntryMapper; - /** * Integration tests for the {@link WatchListEntryResource} REST controller. */ @@ -62,7 +59,7 @@ public class WatchListEntryResourceIT { private WatchListEntryMapper watchListEntryMapper; @SuppressWarnings("unused") - @Autowired + @Autowired private WatchListEntryService watchListEntryService; /** @@ -88,9 +85,7 @@ public class WatchListEntryResourceIT { * if they test an entity which requires the current entity. */ public static WatchListEntry createEntity(EntityManager em) { - WatchListEntry watchListEntry = new WatchListEntry() - .exerciseId(DEFAULT_EXERCISE_ID) - .exerciseName(DEFAULT_EXERCISE_NAME); + WatchListEntry watchListEntry = new WatchListEntry().exerciseId(DEFAULT_EXERCISE_ID).exerciseName(DEFAULT_EXERCISE_NAME); // Add required entity UserWatchList userWatchList; if (TestUtil.findAll(em, UserWatchList.class).isEmpty()) { @@ -103,6 +98,7 @@ public class WatchListEntryResourceIT { watchListEntry.setWatchlist(userWatchList); return watchListEntry; } + /** * Create an updated entity for this test. * @@ -110,9 +106,7 @@ public class WatchListEntryResourceIT { * if they test an entity which requires the current entity. */ public static WatchListEntry createUpdatedEntity(EntityManager em) { - WatchListEntry watchListEntry = new WatchListEntry() - .exerciseId(UPDATED_EXERCISE_ID) - .exerciseName(UPDATED_EXERCISE_NAME); + WatchListEntry watchListEntry = new WatchListEntry().exerciseId(UPDATED_EXERCISE_ID).exerciseName(UPDATED_EXERCISE_NAME); // Add required entity UserWatchList userWatchList; if (TestUtil.findAll(em, UserWatchList.class).isEmpty()) { @@ -137,10 +131,13 @@ public class WatchListEntryResourceIT { int databaseSizeBeforeCreate = watchListEntryRepository.findAll().size(); // Create the WatchListEntry WatchListEntryDTO watchListEntryDTO = watchListEntryMapper.toDto(watchListEntry); - restWatchListEntryMockMvc.perform(post("/api/watch-list-entries") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO))) + restWatchListEntryMockMvc + .perform( + post("/api/watch-list-entries") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO)) + ) .andExpect(status().isCreated()); // Validate the WatchListEntry in the database @@ -164,10 +161,13 @@ public class WatchListEntryResourceIT { WatchListEntryDTO watchListEntryDTO = watchListEntryMapper.toDto(watchListEntry); // An entity with an existing ID cannot be created, so this API call must fail - restWatchListEntryMockMvc.perform(post("/api/watch-list-entries") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO))) + restWatchListEntryMockMvc + .perform( + post("/api/watch-list-entries") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO)) + ) .andExpect(status().isBadRequest()); // Validate the WatchListEntry in the database @@ -178,7 +178,6 @@ public class WatchListEntryResourceIT { verify(mockWatchListEntrySearchRepository, times(0)).save(watchListEntry); } - @Test @Transactional public void checkExerciseIdIsRequired() throws Exception { @@ -189,11 +188,13 @@ public class WatchListEntryResourceIT { // Create the WatchListEntry, which fails. WatchListEntryDTO watchListEntryDTO = watchListEntryMapper.toDto(watchListEntry); - - restWatchListEntryMockMvc.perform(post("/api/watch-list-entries") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO))) + restWatchListEntryMockMvc + .perform( + post("/api/watch-list-entries") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO)) + ) .andExpect(status().isBadRequest()); List<WatchListEntry> watchListEntryList = watchListEntryRepository.findAll(); @@ -207,14 +208,15 @@ public class WatchListEntryResourceIT { watchListEntryRepository.saveAndFlush(watchListEntry); // Get all the watchListEntryList - restWatchListEntryMockMvc.perform(get("/api/watch-list-entries?sort=id,desc")) + restWatchListEntryMockMvc + .perform(get("/api/watch-list-entries?sort=id,desc")) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.[*].id").value(hasItem(watchListEntry.getId().intValue()))) .andExpect(jsonPath("$.[*].exerciseId").value(hasItem(DEFAULT_EXERCISE_ID))) .andExpect(jsonPath("$.[*].exerciseName").value(hasItem(DEFAULT_EXERCISE_NAME))); } - + @Test @Transactional public void getWatchListEntry() throws Exception { @@ -222,7 +224,8 @@ public class WatchListEntryResourceIT { watchListEntryRepository.saveAndFlush(watchListEntry); // Get the watchListEntry - restWatchListEntryMockMvc.perform(get("/api/watch-list-entries/{id}", watchListEntry.getId())) + restWatchListEntryMockMvc + .perform(get("/api/watch-list-entries/{id}", watchListEntry.getId())) .andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) .andExpect(jsonPath("$.id").value(watchListEntry.getId().intValue())) @@ -235,21 +238,26 @@ public class WatchListEntryResourceIT { public void getNumberOfWatchListEntriesForExerciseID() throws Exception { // Initialize the database watchListEntryRepository.saveAndFlush(watchListEntry); - + // Get the watchListEntry - MvcResult result = restWatchListEntryMockMvc.perform(get("/api/statistics/numberOfWatchlistEntries/{exerciseId}", DEFAULT_EXERCISE_ID).with(csrf().asHeader()).contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk()).andReturn(); + MvcResult result = restWatchListEntryMockMvc + .perform( + get("/api/statistics/numberOfWatchlistEntries/{exerciseId}", DEFAULT_EXERCISE_ID) + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) + .andExpect(status().isOk()) + .andReturn(); String content = result.getResponse().getContentAsString(); assertEquals(1, Integer.valueOf(content)); - } @Test @Transactional public void getNonExistingWatchListEntry() throws Exception { // Get the watchListEntry - restWatchListEntryMockMvc.perform(get("/api/watch-list-entries/{id}", Long.MAX_VALUE)) - .andExpect(status().isNotFound()); + restWatchListEntryMockMvc.perform(get("/api/watch-list-entries/{id}", Long.MAX_VALUE)).andExpect(status().isNotFound()); } @Test @@ -264,15 +272,16 @@ public class WatchListEntryResourceIT { WatchListEntry updatedWatchListEntry = watchListEntryRepository.findById(watchListEntry.getId()).get(); // Disconnect from session so that the updates on updatedWatchListEntry are not directly saved in db em.detach(updatedWatchListEntry); - updatedWatchListEntry - .exerciseId(UPDATED_EXERCISE_ID) - .exerciseName(UPDATED_EXERCISE_NAME); + updatedWatchListEntry.exerciseId(UPDATED_EXERCISE_ID).exerciseName(UPDATED_EXERCISE_NAME); WatchListEntryDTO watchListEntryDTO = watchListEntryMapper.toDto(updatedWatchListEntry); - restWatchListEntryMockMvc.perform(put("/api/watch-list-entries") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO))) + restWatchListEntryMockMvc + .perform( + put("/api/watch-list-entries") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO)) + ) .andExpect(status().isOk()); // Validate the WatchListEntry in the database @@ -295,10 +304,13 @@ public class WatchListEntryResourceIT { WatchListEntryDTO watchListEntryDTO = watchListEntryMapper.toDto(watchListEntry); // If the entity doesn't have an ID, it will throw BadRequestAlertException - restWatchListEntryMockMvc.perform(put("/api/watch-list-entries") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO))) + restWatchListEntryMockMvc + .perform( + put("/api/watch-list-entries") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + .content(TestUtil.convertObjectToJsonBytes(watchListEntryDTO)) + ) .andExpect(status().isBadRequest()); // Validate the WatchListEntry in the database @@ -318,9 +330,10 @@ public class WatchListEntryResourceIT { int databaseSizeBeforeDelete = watchListEntryRepository.findAll().size(); // Delete the watchListEntry - restWatchListEntryMockMvc.perform(delete("/api/watch-list-entries/{id}", watchListEntry.getId()) - .with(csrf().asHeader()) - .accept(MediaType.APPLICATION_JSON)) + restWatchListEntryMockMvc + .perform( + delete("/api/watch-list-entries/{id}", watchListEntry.getId()).with(csrf().asHeader()).accept(MediaType.APPLICATION_JSON) + ) .andExpect(status().isNoContent()); // Validate the database contains one less item @@ -330,22 +343,21 @@ public class WatchListEntryResourceIT { // Validate the WatchListEntry in Elasticsearch verify(mockWatchListEntrySearchRepository, times(1)).deleteById(watchListEntry.getId()); } - -// @Test -// @Transactional -// public void searchWatchListEntry() throws Exception { -// // Configure the mock search repository -// // Initialize the database -// watchListEntryRepository.saveAndFlush(watchListEntry); -// when(mockWatchListEntrySearchRepository.search(queryStringQuery("id:" + watchListEntry.getId()), PageRequest.of(0, 20))) -// .thenReturn(new PageImpl<>(Collections.singletonList(watchListEntry), PageRequest.of(0, 1), 1)); -// -// // Search the watchListEntry -// restWatchListEntryMockMvc.perform(get("/api/_search/watch-list-entries?query=id:" + watchListEntry.getId())) -// .andExpect(status().isOk()) -// .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) -// .andExpect(jsonPath("$.[*].id").value(hasItem(watchListEntry.getId().intValue()))) -// .andExpect(jsonPath("$.[*].exerciseId").value(hasItem(DEFAULT_EXERCISE_ID))) -// .andExpect(jsonPath("$.[*].exerciseName").value(hasItem(DEFAULT_EXERCISE_NAME))); -// } + // @Test + // @Transactional + // public void searchWatchListEntry() throws Exception { + // // Configure the mock search repository + // // Initialize the database + // watchListEntryRepository.saveAndFlush(watchListEntry); + // when(mockWatchListEntrySearchRepository.search(queryStringQuery("id:" + watchListEntry.getId()), PageRequest.of(0, 20))) + // .thenReturn(new PageImpl<>(Collections.singletonList(watchListEntry), PageRequest.of(0, 1), 1)); + // + // // Search the watchListEntry + // restWatchListEntryMockMvc.perform(get("/api/_search/watch-list-entries?query=id:" + watchListEntry.getId())) + // .andExpect(status().isOk()) + // .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE)) + // .andExpect(jsonPath("$.[*].id").value(hasItem(watchListEntry.getId().intValue()))) + // .andExpect(jsonPath("$.[*].exerciseId").value(hasItem(DEFAULT_EXERCISE_ID))) + // .andExpect(jsonPath("$.[*].exerciseName").value(hasItem(DEFAULT_EXERCISE_NAME))); + // } } diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/errors/ExceptionTranslatorIT.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/errors/ExceptionTranslatorIT.java index f7ec6e41c01857f57fb17c82c5dba602d9198b99..70f5c385215fc9857d082d11f8a574335303fa58 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/errors/ExceptionTranslatorIT.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/errors/ExceptionTranslatorIT.java @@ -7,6 +7,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers. import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +import at.ac.uibk.gitsearch.IntegrationTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; @@ -14,8 +15,6 @@ import org.springframework.http.MediaType; import org.springframework.security.test.context.support.WithMockUser; import org.springframework.test.web.servlet.MockMvc; -import at.ac.uibk.gitsearch.IntegrationTest; - /** * Integration tests {@link ExceptionTranslator} controller advice. */ @@ -39,9 +38,12 @@ class ExceptionTranslatorIT { @Test void testMethodArgumentNotValid() throws Exception { mockMvc - .perform(post("/api/exception-translator-test/method-argument").content("{}") - .with(csrf().asHeader()) - .contentType(MediaType.APPLICATION_JSON)) + .perform( + post("/api/exception-translator-test/method-argument") + .content("{}") + .with(csrf().asHeader()) + .contentType(MediaType.APPLICATION_JSON) + ) .andExpect(status().isBadRequest()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value(ErrorConstants.ERR_VALIDATION)) @@ -92,8 +94,7 @@ class ExceptionTranslatorIT { @Test void testMethodNotSupported() throws Exception { mockMvc - .perform(post("/api/exception-translator-test/access-denied").with(csrf().asHeader()) - ) + .perform(post("/api/exception-translator-test/access-denied").with(csrf().asHeader())) .andExpect(status().isMethodNotAllowed()) .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON)) .andExpect(jsonPath("$.message").value("error.http.405")) diff --git a/src/test/java/at/ac/uibk/gitsearch/web/rest/util/HeaderUtil.java b/src/test/java/at/ac/uibk/gitsearch/web/rest/util/HeaderUtil.java index 79e4edb3e957b5611a71c9358adbccd53567ec3e..457346b7c28e7e72381c563dd55f026e56480361 100644 --- a/src/test/java/at/ac/uibk/gitsearch/web/rest/util/HeaderUtil.java +++ b/src/test/java/at/ac/uibk/gitsearch/web/rest/util/HeaderUtil.java @@ -2,7 +2,6 @@ package at.ac.uibk.gitsearch.web.rest.util; import java.nio.charset.StandardCharsets; import java.util.Base64; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; @@ -14,16 +13,20 @@ import org.springframework.http.MediaType; public final class HeaderUtil { @SuppressWarnings("unused") - private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class); + private static final Logger log = LoggerFactory.getLogger(HeaderUtil.class); - private HeaderUtil() { - } + private HeaderUtil() {} public static HttpHeaders createAlert(String applicationName, String message, String param) { return tech.jhipster.web.util.HeaderUtil.createAlert(applicationName, message, param); } - public static HttpHeaders createEntityCreationAlert(String applicationName, boolean enableTranslation, String entityName, String param) { + public static HttpHeaders createEntityCreationAlert( + String applicationName, + boolean enableTranslation, + String entityName, + String param + ) { return tech.jhipster.web.util.HeaderUtil.createEntityCreationAlert(applicationName, enableTranslation, entityName, param); } @@ -31,12 +34,29 @@ public final class HeaderUtil { return tech.jhipster.web.util.HeaderUtil.createEntityUpdateAlert(applicationName, enableTranslation, entityName, param); } - public static HttpHeaders createEntityDeletionAlert(String applicationName, boolean enableTranslation, String entityName, String param) { + public static HttpHeaders createEntityDeletionAlert( + String applicationName, + boolean enableTranslation, + String entityName, + String param + ) { return tech.jhipster.web.util.HeaderUtil.createEntityDeletionAlert(applicationName, enableTranslation, entityName, param); } - public static HttpHeaders createFailureAlert(String applicationName, boolean enableTranslation, String entityName, String errorKey, String defaultMessage) { - HttpHeaders headers = tech.jhipster.web.util.HeaderUtil.createFailureAlert(applicationName, enableTranslation, entityName, errorKey, defaultMessage); + public static HttpHeaders createFailureAlert( + String applicationName, + boolean enableTranslation, + String entityName, + String errorKey, + String defaultMessage + ) { + HttpHeaders headers = tech.jhipster.web.util.HeaderUtil.createFailureAlert( + applicationName, + enableTranslation, + entityName, + errorKey, + defaultMessage + ); headers.add("X-" + applicationName + "-message", defaultMessage); return headers; } @@ -49,13 +69,12 @@ public final class HeaderUtil { */ public static HttpHeaders createAuthorization(String username, String password) { HttpHeaders acceptHeaders = new HttpHeaders() { - /** - * - */ - private static final long serialVersionUID = 1L; + * + */ + private static final long serialVersionUID = 1L; - { + { set(com.google.common.net.HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON.toString()); set(com.google.common.net.HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON.toString()); } @@ -67,4 +86,3 @@ public final class HeaderUtil { return acceptHeaders; } } - diff --git a/src/test/javascript/spec/app/bookmarks/bookmarks.component.spec.ts b/src/test/javascript/spec/app/bookmarks/bookmarks.component.spec.ts index f6c374e39daa0e00584a50d0aa9049ef019466f7..b17835d4d6363d0d2be195263cc547edbcd57fc5 100644 --- a/src/test/javascript/spec/app/bookmarks/bookmarks.component.spec.ts +++ b/src/test/javascript/spec/app/bookmarks/bookmarks.component.spec.ts @@ -7,46 +7,46 @@ import { CheckFrequency } from 'app/shared/model/enumerations/check-frequency.mo import { of } from 'rxjs'; describe('Component Tests', () => { - describe('Bookmarks Component', () => { - let comp: BookmarkComponent; - let fixture: ComponentFixture<BookmarkComponent>; - let userWatchListService: UserWatchListService; - - beforeEach(waitForAsync(() => { - TestBed.configureTestingModule({ - imports: [GitsearchTestModule], - declarations: [BookmarkComponent], - }) - .overrideTemplate(BookmarkComponent, '') - .compileComponents(); - - })); - - beforeEach(() => { - fixture = TestBed.createComponent(BookmarkComponent); - comp = fixture.componentInstance; - userWatchListService = fixture.debugElement.injector.get(UserWatchListService); - - }); - - const defaultWatchList: IUserWatchList[] = [{ - id: 1, - name: "My WatchList", - checkFrequency: CheckFrequency.NEVER, - userLogin: "any", - userId: 0 - }]; - - it('Should call userWatchListService.findMyWatchlists on initial ngOnInit', () => { - // GIVEN - spyOn(userWatchListService, 'findMyWatchlists').and.returnValue(of({ body: defaultWatchList })) - // WHEN, - comp.ngOnInit(); - - - // THEN - expect(userWatchListService.findMyWatchlists).toHaveBeenCalled(); - }); + describe('Bookmarks Component', () => { + let comp: BookmarkComponent; + let fixture: ComponentFixture<BookmarkComponent>; + let userWatchListService: UserWatchListService; + + beforeEach( + waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [GitsearchTestModule], + declarations: [BookmarkComponent], + }) + .overrideTemplate(BookmarkComponent, '') + .compileComponents(); + }) + ); + + beforeEach(() => { + fixture = TestBed.createComponent(BookmarkComponent); + comp = fixture.componentInstance; + userWatchListService = fixture.debugElement.injector.get(UserWatchListService); + }); + const defaultWatchList: IUserWatchList[] = [ + { + id: 1, + name: 'My WatchList', + checkFrequency: CheckFrequency.NEVER, + userLogin: 'any', + userId: 0, + }, + ]; + + it('Should call userWatchListService.findMyWatchlists on initial ngOnInit', () => { + // GIVEN + spyOn(userWatchListService, 'findMyWatchlists').and.returnValue(of({ body: defaultWatchList })); + // WHEN, + comp.ngOnInit(); + + // THEN + expect(userWatchListService.findMyWatchlists).toHaveBeenCalled(); }); + }); }); diff --git a/src/test/javascript/spec/app/entities/likes/likes-detail.component.spec.ts b/src/test/javascript/spec/app/entities/likes/likes-detail.component.spec.ts index 319925a35bdee083881b42ad4fe8f7c82c777b71..c836388713580060986b3c81c3ffe6f5b64e37e1 100644 --- a/src/test/javascript/spec/app/entities/likes/likes-detail.component.spec.ts +++ b/src/test/javascript/spec/app/entities/likes/likes-detail.component.spec.ts @@ -10,7 +10,7 @@ describe('Component Tests', () => { describe('Likes Management Detail Component', () => { let comp: LikesDetailComponent; let fixture: ComponentFixture<LikesDetailComponent>; - const route = ({ data: of({ likes: new Likes(123) }) } as any) as ActivatedRoute; + const route = { data: of({ likes: new Likes(123) }) } as any as ActivatedRoute; beforeEach(() => { TestBed.configureTestingModule({ diff --git a/src/test/javascript/spec/app/entities/saved-searches/saved-searches-detail.component.spec.ts b/src/test/javascript/spec/app/entities/saved-searches/saved-searches-detail.component.spec.ts index f9a0f860b104868c17662db7cb5fbcc4d2fa3a32..7880bc79fb477ee640a4db31c709216e8fe1154e 100644 --- a/src/test/javascript/spec/app/entities/saved-searches/saved-searches-detail.component.spec.ts +++ b/src/test/javascript/spec/app/entities/saved-searches/saved-searches-detail.component.spec.ts @@ -10,7 +10,7 @@ describe('Component Tests', () => { describe('SavedSearches Management Detail Component', () => { let comp: SavedSearchesDetailComponent; let fixture: ComponentFixture<SavedSearchesDetailComponent>; - const route = ({ data: of({ savedSearches: new SavedSearches(123) }) } as any) as ActivatedRoute; + const route = { data: of({ savedSearches: new SavedSearches(123) }) } as any as ActivatedRoute; beforeEach(() => { TestBed.configureTestingModule({ diff --git a/src/test/javascript/spec/app/entities/statistics/statistics-detail.component.spec.ts b/src/test/javascript/spec/app/entities/statistics/statistics-detail.component.spec.ts index 948b511d52ed3af775738e33d575e116cae4ea1c..586103e9bfadc7cdd707b4fcf111e03be10de208 100644 --- a/src/test/javascript/spec/app/entities/statistics/statistics-detail.component.spec.ts +++ b/src/test/javascript/spec/app/entities/statistics/statistics-detail.component.spec.ts @@ -10,7 +10,7 @@ describe('Component Tests', () => { describe('Statistics Management Detail Component', () => { let comp: StatisticsDetailComponent; let fixture: ComponentFixture<StatisticsDetailComponent>; - const route = ({ data: of({ statistics: new Statistics(123) }) } as any) as ActivatedRoute; + const route = { data: of({ statistics: new Statistics(123) }) } as any as ActivatedRoute; beforeEach(() => { TestBed.configureTestingModule({ diff --git a/src/test/javascript/spec/app/entities/user-watch-list/user-watch-list-detail.component.spec.ts b/src/test/javascript/spec/app/entities/user-watch-list/user-watch-list-detail.component.spec.ts index 36941b0354f6af32ffe5d2992e9ed481213f2bab..ef016787128046cac7c16fc861331ef1eea46c86 100644 --- a/src/test/javascript/spec/app/entities/user-watch-list/user-watch-list-detail.component.spec.ts +++ b/src/test/javascript/spec/app/entities/user-watch-list/user-watch-list-detail.component.spec.ts @@ -10,7 +10,7 @@ describe('Component Tests', () => { describe('UserWatchList Management Detail Component', () => { let comp: UserWatchListDetailComponent; let fixture: ComponentFixture<UserWatchListDetailComponent>; - const route = ({ data: of({ userWatchList: new UserWatchList(123) }) } as any) as ActivatedRoute; + const route = { data: of({ userWatchList: new UserWatchList(123) }) } as any as ActivatedRoute; beforeEach(() => { TestBed.configureTestingModule({ diff --git a/src/test/javascript/spec/app/entities/watch-list-entry/watch-list-entry-detail.component.spec.ts b/src/test/javascript/spec/app/entities/watch-list-entry/watch-list-entry-detail.component.spec.ts index afda3725cce1a3968f1d0754084ed8bddae8c064..b14ca7ae7f2398abc075f0d950d1e2ee945910d7 100644 --- a/src/test/javascript/spec/app/entities/watch-list-entry/watch-list-entry-detail.component.spec.ts +++ b/src/test/javascript/spec/app/entities/watch-list-entry/watch-list-entry-detail.component.spec.ts @@ -10,7 +10,7 @@ describe('Component Tests', () => { describe('WatchListEntry Management Detail Component', () => { let comp: WatchListEntryDetailComponent; let fixture: ComponentFixture<WatchListEntryDetailComponent>; - const route = ({ data: of({ watchListEntry: new WatchListEntry(123) }) } as any) as ActivatedRoute; + const route = { data: of({ watchListEntry: new WatchListEntry(123) }) } as any as ActivatedRoute; beforeEach(() => { TestBed.configureTestingModule({ diff --git a/src/test/javascript/spec/app/shared/service/message-service.spec.ts b/src/test/javascript/spec/app/shared/service/message-service.spec.ts index e5f2189af14dffe32b0bfc1c5056f55c909ed033..329e90fe6c020c049a34f1ffb395ed23967ff313 100644 --- a/src/test/javascript/spec/app/shared/service/message-service.spec.ts +++ b/src/test/javascript/spec/app/shared/service/message-service.spec.ts @@ -19,31 +19,38 @@ describe('Service Tests', () => { service = injector.get(MessageService); httpMock = injector.get(HttpTestingController); - const messageNow :BroadCastMessage = { - message: "Some Test now Message", - starts_at: new Date(), - ends_at: new Date(new Date().getDate() + 1), - - color: "red", id: 1, font: "unused", active: true, target_path: "unused", broadcast_type: "broadcast_type", dismissable:true - - }; - const messageTomorrow :BroadCastMessage = { - message: "Some Test tomorrwo Message", - starts_at: new Date(new Date().getDate() + 1), - ends_at: new Date(new Date().getDate() + 2), - - color: "red", id: 2, font: "unused", active: true, target_path: "unused", broadcast_type: "broadcast_type", dismissable:true - } - - returnedFromService = new Array<BroadCastMessage>(messageNow, messageTomorrow); - + const messageNow: BroadCastMessage = { + message: 'Some Test now Message', + starts_at: new Date(), + ends_at: new Date(new Date().getDate() + 1), + + color: 'red', + id: 1, + font: 'unused', + active: true, + target_path: 'unused', + broadcast_type: 'broadcast_type', + dismissable: true, + }; + const messageTomorrow: BroadCastMessage = { + message: 'Some Test tomorrwo Message', + starts_at: new Date(new Date().getDate() + 1), + ends_at: new Date(new Date().getDate() + 2), + + color: 'red', + id: 2, + font: 'unused', + active: true, + target_path: 'unused', + broadcast_type: 'broadcast_type', + dismissable: true, + }; + + returnedFromService = new Array<BroadCastMessage>(messageNow, messageTomorrow); }); - - describe('Service methods', () => { it('should get some messages', () => { - expectedResult = service.getMessages(); // this may return an empty list, because webclient may not yet received results const req = httpMock.expectOne({ method: 'GET' }); @@ -51,24 +58,18 @@ describe('Service Tests', () => { expectedResult = service.getMessages(); expect(expectedResult).toMatchObject(returnedFromService); }); - - }); describe('Service methods', () => { it('should get some messages', () => { - expectedResult = service.getActiveMessages(); // this may return an empty list, because webclient may not yet received results - const req = httpMock.expectOne({ method: 'GET' }); req.flush(returnedFromService); expectedResult = service.getActiveMessages(); const now = new Date(); expect(expectedResult).toMatchObject(returnedFromService.filter(m => m.starts_at <= now && m.ends_at >= now)); }); - - }); afterEach(() => { diff --git a/src/test/javascript/spec/app/teaserContent/teaserContent.component.spec.ts b/src/test/javascript/spec/app/teaserContent/teaserContent.component.spec.ts index 44e862a754265f79fb64c92381b9812fd3ab5b64..9b0c71414ae1706db6f29a15dfbccd499f327265 100644 --- a/src/test/javascript/spec/app/teaserContent/teaserContent.component.spec.ts +++ b/src/test/javascript/spec/app/teaserContent/teaserContent.component.spec.ts @@ -1,4 +1,4 @@ -import { ComponentFixture, TestBed, waitForAsync, fakeAsync, tick} from '@angular/core/testing'; +import { ComponentFixture, TestBed, waitForAsync, fakeAsync, tick } from '@angular/core/testing'; import { GitsearchTestModule } from '../../test.module'; import { TeaserContentComponent } from 'app/teaserContent/teaserContent.component'; import { TranslateModule } from '@ngx-translate/core'; diff --git a/src/test/javascript/spec/helpers/mock-userWatchList.service.ts b/src/test/javascript/spec/helpers/mock-userWatchList.service.ts index 4893b4b3e62fdc9348c3b5364bb2464db60840e9..17d0b8561291a5623daaadd30eceb55182eaf34f 100644 --- a/src/test/javascript/spec/helpers/mock-userWatchList.service.ts +++ b/src/test/javascript/spec/helpers/mock-userWatchList.service.ts @@ -15,14 +15,15 @@ export class MockUserWatchListService extends SpyObject { updateSpy: Spy; createSpy: Spy; - defaultWatchList: IUserWatchList[] = [{ + defaultWatchList: IUserWatchList[] = [ + { id: 1, - name: "My WatchList", + name: 'My WatchList', checkFrequency: CheckFrequency.NEVER, - userLogin: "any", - userId: 0 - }]; - + userLogin: 'any', + userId: 0, + }, + ]; constructor() { super(UserWatchListService); @@ -30,21 +31,17 @@ export class MockUserWatchListService extends SpyObject { const entity = new UserWatchList(123); this.getSpy = this.spy('get').andReturn(this); - this.findMyWatchlistsSpy = this.spy('findMyWatchlists').andReturn(of({body: this.defaultWatchList})); - + this.findMyWatchlistsSpy = this.spy('findMyWatchlists').andReturn(of({ body: this.defaultWatchList })); + const headers = new HttpHeaders().append('link', 'link;link'); - this.querySpy = this.spy('query').and.returnValue( - of( - new HttpResponse({body: [entity], headers}))); - - this.deleteSpy = this.spy('delete').and.returnValue(of({})); + this.querySpy = this.spy('query').and.returnValue(of(new HttpResponse({ body: [entity], headers }))); + this.deleteSpy = this.spy('delete').and.returnValue(of({})); this.updateSpy = this.spy('update').and.returnValue(of(new HttpResponse({ body: entity }))); - + const newEntity = new UserWatchList(); this.createSpy = this.spy('create').and.returnValue(of(new HttpResponse({ body: newEntity }))); } - } diff --git a/src/test/resources/at/ac/uibk/gitsearch/repository/search/testData/es_metadata.schema.json b/src/test/resources/at/ac/uibk/gitsearch/repository/search/testData/es_metadata.schema.json index 8aa7c535dbc4d2767875836c2c1251fe66d4f36f..a12979e61a915fb4b9c0cf58b11b4c167d282bc3 100644 --- a/src/test/resources/at/ac/uibk/gitsearch/repository/search/testData/es_metadata.schema.json +++ b/src/test/resources/at/ac/uibk/gitsearch/repository/search/testData/es_metadata.schema.json @@ -1,230 +1,230 @@ { - "mappings" : { - "properties" : { - "file" : { - "properties" : { - "children" : { - "type" : "keyword" - }, - "commit_id" : { - "type" : "keyword" - }, - "filename" : { - "type" : "keyword" - }, - "indexing_date" : { - "type" : "date", - "format" : "dateOptionalTime" - }, - "last_activity_at" : { - "type" : "date", - "format" : "dateOptionalTime" + "mappings": { + "properties": { + "file": { + "properties": { + "children": { + "type": "keyword" + }, + "commit_id": { + "type": "keyword" + }, + "filename": { + "type": "keyword" + }, + "indexing_date": { + "type": "date", + "format": "dateOptionalTime" + }, + "last_activity_at": { + "type": "date", + "format": "dateOptionalTime" + }, + "parentId": { + "type": "keyword" + }, + "path": { + "type": "keyword" + } + } + }, + "metadata": { + "properties": { + "assesses": { + "type": "keyword" + }, + "audience": { + "type": "text" + }, + "collectionContent": { + "type": "keyword" + }, + "contributor": { + "properties": { + "affiliation": { + "type": "text" }, - "parentId" : { - "type" : "keyword" + "email": { + "type": "text" }, - "path" : { - "type" : "keyword" + "name": { + "type": "text" } } }, - "metadata" : { - "properties" : { - "assesses" : { - "type" : "keyword" - }, - "audience" : { - "type" : "text" - }, - "collectionContent": { - "type": "keyword" - }, - "contributor" : { - "properties" : { - "affiliation" : { - "type" : "text" - }, - "email" : { - "type" : "text" - }, - "name" : { - "type" : "text" - } - } - }, - "creator" : { - "properties" : { - "affiliation" : { - "type" : "text" - }, - "email" : { - "type" : "text" - }, - "name" : { - "type" : "text" - } - } - }, - "description" : { - "type" : "text" - }, - "difficulty" : { - "type" : "keyword" - }, - "educationalAlignment" : { - "type" : "keyword" - }, - "educationalFramework" : { - "type" : "keyword" - }, - "educationalLevel" : { - "type" : "keyword" - }, - "educationalUse" : { - "type" : "text" - }, - "format" : { - "type": "text" - }, - "identifier" : { - "type" : "keyword" - }, - "image" : { - "type" : "keyword" + "creator": { + "properties": { + "affiliation": { + "type": "text" }, - "interactivityType" : { - "type" : "keyword" + "email": { + "type": "text" }, - "isBasedOn" : { - "type" : "text" - }, - "keyword" : { - "type": "text" - }, - "language" : { - "type" : "keyword" - }, - "learningResourceType" : { - "type" : "text" - }, - "license" : { - "type" : "keyword" - }, - "metadataVersion" : { - "type" : "keyword" - }, - "programmingLanguage" : { - "type" : "text" - }, - "publicVisibility" : { - "properties" : { - "except" : { - "type" : "keyword" - } - } - }, - "publisher" : { - "properties" : { - "affiliation" : { - "type" : "text" - }, - "email" : { - "type" : "text" - }, - "name" : { - "type" : "text" - } - } - }, - "requires" : { - "type" : "text" - }, - "status" : { - "type" : "keyword" - }, - "structure" : { - "type" : "keyword" - }, - "subject" : { - "type" : "text" - }, - "teaches" : { - "type" : "text" - }, - "timeRequired" : { - "type" : "keyword" - }, - "title" : { - "type" : "text" - }, - "typicalAgeRange" : { - "type" : "keyword" - }, - "valid" : { - "properties" : { - "from" : { - "type" : "keyword" - }, - "to" : { - "type" : "keyword" - } - } - }, - "version" : { - "type" : "keyword" + "name": { + "type": "text" } } }, - "project" : { - "properties" : { - "archived" : { - "type" : "boolean" - }, - "description" : { - "type" : "text" - }, - "forks_count" : { - "type" : "integer" - }, - "groups" : { - "type" : "keyword" - }, - "last_activity_at" : { - "type" : "date", - "format" : "dateOptionalTime" - }, - "main_group" : { - "type" : "keyword" - }, - "namespace" : { - "type" : "keyword" - }, - "open_issues_count" : { - "type" : "integer" - }, - "project_id" : { - "type" : "long" - }, - "project_name" : { - "type" : "keyword" - }, - "star_count" : { - "type" : "integer" - }, - "sub_group" : { - "type" : "keyword" + "description": { + "type": "text" + }, + "difficulty": { + "type": "keyword" + }, + "educationalAlignment": { + "type": "keyword" + }, + "educationalFramework": { + "type": "keyword" + }, + "educationalLevel": { + "type": "keyword" + }, + "educationalUse": { + "type": "text" + }, + "format": { + "type": "text" + }, + "identifier": { + "type": "keyword" + }, + "image": { + "type": "keyword" + }, + "interactivityType": { + "type": "keyword" + }, + "isBasedOn": { + "type": "text" + }, + "keyword": { + "type": "text" + }, + "language": { + "type": "keyword" + }, + "learningResourceType": { + "type": "text" + }, + "license": { + "type": "keyword" + }, + "metadataVersion": { + "type": "keyword" + }, + "programmingLanguage": { + "type": "text" + }, + "publicVisibility": { + "properties": { + "except": { + "type": "keyword" + } + } + }, + "publisher": { + "properties": { + "affiliation": { + "type": "text" }, - "url" : { - "type" : "keyword" + "email": { + "type": "text" }, - "users" : { - "type" : "keyword" + "name": { + "type": "text" + } + } + }, + "requires": { + "type": "text" + }, + "status": { + "type": "keyword" + }, + "structure": { + "type": "keyword" + }, + "subject": { + "type": "text" + }, + "teaches": { + "type": "text" + }, + "timeRequired": { + "type": "keyword" + }, + "title": { + "type": "text" + }, + "typicalAgeRange": { + "type": "keyword" + }, + "valid": { + "properties": { + "from": { + "type": "keyword" }, - "visibility" : { - "type" : "keyword" + "to": { + "type": "keyword" } } + }, + "version": { + "type": "keyword" + } + } + }, + "project": { + "properties": { + "archived": { + "type": "boolean" + }, + "description": { + "type": "text" + }, + "forks_count": { + "type": "integer" + }, + "groups": { + "type": "keyword" + }, + "last_activity_at": { + "type": "date", + "format": "dateOptionalTime" + }, + "main_group": { + "type": "keyword" + }, + "namespace": { + "type": "keyword" + }, + "open_issues_count": { + "type": "integer" + }, + "project_id": { + "type": "long" + }, + "project_name": { + "type": "keyword" + }, + "star_count": { + "type": "integer" + }, + "sub_group": { + "type": "keyword" + }, + "url": { + "type": "keyword" + }, + "users": { + "type": "keyword" + }, + "visibility": { + "type": "keyword" + } } } } -} \ No newline at end of file + } +} diff --git a/webpack/proxy.conf.js b/webpack/proxy.conf.js index b59f140ac8a2c30f2bbc145703998ef052f76a3e..6967c9a7f296c6197108ab5a67f1e2a6ce77d8a7 100644 --- a/webpack/proxy.conf.js +++ b/webpack/proxy.conf.js @@ -1,19 +1,19 @@ function setupProxy({ tls }) { const conf = [ { - context: [ - '/api', - '/oauth2Config', - '/oauth2', - '/login', - '/services', - '/management', - '/swagger-resources', - '/v3/api-docs', - '/h2-console', - '/auth', - '/health' - ], + context: [ + '/api', + '/oauth2Config', + '/oauth2', + '/login', + '/services', + '/management', + '/swagger-resources', + '/v3/api-docs', + '/h2-console', + '/auth', + '/health', + ], target: `http${tls ? 's' : ''}://localhost:8080`, secure: false, changeOrigin: tls,