From ef2cc5f8dfe47f61b1e5c32c02d0f2323444d645 Mon Sep 17 00:00:00 2001 From: Jordan Liggitt Date: Mon, 23 Mar 2015 13:54:39 -0400 Subject: [PATCH 1/2] Initial changes to support console being served from same port as API or as its own server on a separate port --- pkg/cmd/server/api/validation/validation.go | 37 +++++- pkg/cmd/server/origin/asset.go | 137 ++++++++++++++++++++ pkg/cmd/server/origin/asset_config.go | 14 ++ pkg/cmd/server/origin/master.go | 79 ----------- pkg/cmd/server/start/master_args.go | 9 +- pkg/cmd/server/start/start_master.go | 27 +++- 6 files changed, 213 insertions(+), 90 deletions(-) create mode 100644 pkg/cmd/server/origin/asset.go create mode 100644 pkg/cmd/server/origin/asset_config.go diff --git a/pkg/cmd/server/api/validation/validation.go b/pkg/cmd/server/api/validation/validation.go index eba5caf9dfd7..320be4153eb3 100644 --- a/pkg/cmd/server/api/validation/validation.go +++ b/pkg/cmd/server/api/validation/validation.go @@ -2,6 +2,7 @@ package validation import ( "net" + "net/url" "os" "strings" @@ -99,13 +100,47 @@ func ValidateSpecifiedIP(ipString string, field string) errs.ValidationErrorList return allErrs } +func ValidateURL(urlString string, field string) (*url.URL, errs.ValidationErrorList) { + allErrs := errs.ValidationErrorList{} + + urlObj, err := url.Parse(urlString) + if err != nil { + allErrs = append(allErrs, errs.NewFieldInvalid(field, urlString, "must be a valid URL")) + return nil, allErrs + } + if len(urlObj.Scheme) == 0 { + allErrs = append(allErrs, errs.NewFieldInvalid(field, urlString, "must contain a scheme (e.g. http://)")) + } + if len(urlObj.Host) == 0 { + allErrs = append(allErrs, errs.NewFieldInvalid(field, urlString, "must contain a host")) + } + return urlObj, allErrs +} + +func ValidateAssetConfig(config *api.AssetConfig) errs.ValidationErrorList { + allErrs := errs.ValidationErrorList{} + + allErrs = append(allErrs, ValidateServingInfo(config.ServingInfo).Prefix("servingInfo")...) + + urlObj, urlErrs := ValidateURL(config.PublicURL, "publicURL") + if len(urlErrs) > 0 { + allErrs = append(allErrs, urlErrs...) + } + // TODO: remove once this is configurable + if urlObj != nil && urlObj.Path != "/console" { + allErrs = append(allErrs, errs.NewFieldInvalid("publicURL", config.PublicURL, "must be located at the /console path")) + } + + return allErrs +} + func ValidateMasterConfig(config *api.MasterConfig) errs.ValidationErrorList { allErrs := errs.ValidationErrorList{} allErrs = append(allErrs, ValidateServingInfo(config.ServingInfo).Prefix("servingInfo")...) if config.AssetConfig != nil { - allErrs = append(allErrs, ValidateServingInfo(config.AssetConfig.ServingInfo).Prefix("assetConfig.servingInfo")...) + allErrs = append(allErrs, ValidateAssetConfig(config.AssetConfig).Prefix("assetConfig")...) } if config.DNSConfig != nil { diff --git a/pkg/cmd/server/origin/asset.go b/pkg/cmd/server/origin/asset.go new file mode 100644 index 000000000000..e6de86377207 --- /dev/null +++ b/pkg/cmd/server/origin/asset.go @@ -0,0 +1,137 @@ +package origin + +import ( + "crypto/tls" + "fmt" + "net/http" + "net/url" + "time" + + "github.com/GoogleCloudPlatform/kubernetes/pkg/util" + "github.com/elazarl/go-bindata-assetfs" + "github.com/emicklei/go-restful" + "github.com/golang/glog" + "github.com/openshift/origin/pkg/assets" + configapi "github.com/openshift/origin/pkg/cmd/server/api" + cmdutil "github.com/openshift/origin/pkg/cmd/util" + "github.com/openshift/origin/pkg/version" +) + +// InstallSupport registers endpoints for an OAuth2 server into the provided mux, +// then returns an array of strings indicating what endpoints were started +// (these are format strings that will expect to be sent a single string value). +func (c *AssetConfig) InstallAPI(container *restful.Container) []string { + assetHandler, err := c.handler() + if err != nil { + glog.Fatal(err) + } + + publicURL, err := url.Parse(c.Options.PublicURL) + if err != nil { + glog.Fatal(err) + } + + mux := container.ServeMux + mux.Handle(publicURL.Path, http.StripPrefix(publicURL.Path, assetHandler)) + + return []string{fmt.Sprintf("Started OpenShift UI %%s%s", publicURL.Path)} +} + +func (c *AssetConfig) Run() { + assetHandler, err := c.handler() + if err != nil { + glog.Fatal(err) + } + + publicURL, err := url.Parse(c.Options.PublicURL) + if err != nil { + glog.Fatal(err) + } + + mux := http.NewServeMux() + mux.Handle(publicURL.Path, http.StripPrefix(publicURL.Path, assetHandler)) + mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { + http.Redirect(w, req, publicURL.Path, http.StatusFound) + }) + + server := &http.Server{ + Addr: c.Options.ServingInfo.BindAddress, + Handler: mux, + ReadTimeout: 5 * time.Minute, + WriteTimeout: 5 * time.Minute, + MaxHeaderBytes: 1 << 20, + } + + isTLS := configapi.UseTLS(c.Options.ServingInfo) + + go util.Forever(func() { + if isTLS { + server.TLSConfig = &tls.Config{ + // Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability) + MinVersion: tls.VersionTLS10, + } + glog.Infof("OpenShift UI listening at https://%s", c.Options.ServingInfo.BindAddress) + glog.Fatal(server.ListenAndServeTLS(c.Options.ServingInfo.ServerCert.CertFile, c.Options.ServingInfo.ServerCert.KeyFile)) + } else { + glog.Infof("OpenShift UI listening at https://%s", c.Options.ServingInfo.BindAddress) + glog.Fatal(server.ListenAndServe()) + } + }, 0) + + // Attempt to verify the server came up for 20 seconds (100 tries * 100ms, 100ms timeout per try) + cmdutil.WaitForSuccessfulDial(isTLS, "tcp", c.Options.ServingInfo.BindAddress, 100*time.Millisecond, 100*time.Millisecond, 100) + + glog.Infof("OpenShift UI available at %s", c.Options.PublicURL) +} + +func (c *AssetConfig) handler() (http.Handler, error) { + assets.RegisterMimeTypes() + + masterURL, err := url.Parse(c.Options.MasterPublicURL) + if err != nil { + return nil, err + } + + k8sURL, err := url.Parse(c.Options.KubernetesPublicURL) + if err != nil { + return nil, err + } + + config := assets.WebConsoleConfig{ + MasterAddr: masterURL.Host, + MasterPrefix: "/osapi", // TODO: make configurable + KubernetesAddr: k8sURL.Host, + KubernetesPrefix: "/api", // TODO: make configurable + OAuthAuthorizeURI: OpenShiftOAuthAuthorizeURL(masterURL.String()), + OAuthRedirectBase: c.Options.PublicURL, + OAuthClientID: OpenShiftWebConsoleClientID, + LogoutURI: c.Options.LogoutURI, + } + + mux := http.NewServeMux() + mux.Handle("/", + // Gzip first so that inner handlers can react to the addition of the Vary header + assets.GzipHandler( + // Generated config.js can not be cached since it changes depending on startup options + assets.GeneratedConfigHandler( + config, + // Cache control should happen after all Vary headers are added, but before + // any asset related routing (HTML5ModeHandler and FileServer) + assets.CacheControlHandler( + version.Get().GitCommit, + assets.HTML5ModeHandler( + http.FileServer( + &assetfs.AssetFS{ + assets.Asset, + assets.AssetDir, + "", + }, + ), + ), + ), + ), + ), + ) + + return mux, nil +} diff --git a/pkg/cmd/server/origin/asset_config.go b/pkg/cmd/server/origin/asset_config.go new file mode 100644 index 000000000000..b394f4aab682 --- /dev/null +++ b/pkg/cmd/server/origin/asset_config.go @@ -0,0 +1,14 @@ +package origin + +import ( + configapi "github.com/openshift/origin/pkg/cmd/server/api" +) + +// MasterConfig defines the required parameters for starting the OpenShift master +type AssetConfig struct { + Options configapi.AssetConfig +} + +func BuildAssetConfig(options configapi.AssetConfig) (*AssetConfig, error) { + return &AssetConfig{options}, nil +} diff --git a/pkg/cmd/server/origin/master.go b/pkg/cmd/server/origin/master.go index 575a15433d68..829482f519a5 100644 --- a/pkg/cmd/server/origin/master.go +++ b/pkg/cmd/server/origin/master.go @@ -8,13 +8,11 @@ import ( "fmt" "net" "net/http" - "net/url" "os" "regexp" "time" etcdclient "github.com/coreos/go-etcd/etcd" - "github.com/elazarl/go-bindata-assetfs" restful "github.com/emicklei/go-restful" "github.com/emicklei/go-restful/swagger" "github.com/golang/glog" @@ -32,7 +30,6 @@ import ( "github.com/openshift/origin/pkg/api/latest" "github.com/openshift/origin/pkg/api/v1beta1" - "github.com/openshift/origin/pkg/assets" buildclient "github.com/openshift/origin/pkg/build/client" buildcontrollerfactory "github.com/openshift/origin/pkg/build/controller/factory" buildstrategy "github.com/openshift/origin/pkg/build/controller/strategy" @@ -81,7 +78,6 @@ import ( useretcd "github.com/openshift/origin/pkg/user/registry/etcd" userregistry "github.com/openshift/origin/pkg/user/registry/user" "github.com/openshift/origin/pkg/user/registry/useridentitymapping" - "github.com/openshift/origin/pkg/version" authorizationapi "github.com/openshift/origin/pkg/authorization/api" authorizationetcd "github.com/openshift/origin/pkg/authorization/registry/etcd" @@ -471,82 +467,7 @@ func (c *MasterConfig) RunPolicyCache() { // RunAssetServer starts the asset server for the OpenShift UI. func (c *MasterConfig) RunAssetServer() { - // TODO use version.Get().GitCommit as an etag cache header - mux := http.NewServeMux() - masterURL, err := url.Parse(c.Options.AssetConfig.MasterPublicURL) - if err != nil { - glog.Fatalf("Error parsing master url: %v", err) - } - - k8sURL, err := url.Parse(c.Options.AssetConfig.KubernetesPublicURL) - if err != nil { - glog.Fatalf("Error parsing kubernetes url: %v", err) - } - - config := assets.WebConsoleConfig{ - MasterAddr: masterURL.Host, - MasterPrefix: OpenShiftAPIPrefix, - KubernetesAddr: k8sURL.Host, - KubernetesPrefix: "/api", - OAuthAuthorizeURI: OpenShiftOAuthAuthorizeURL(masterURL.String()), - OAuthRedirectBase: c.Options.AssetConfig.PublicURL, - OAuthClientID: OpenShiftWebConsoleClientID, - LogoutURI: c.Options.AssetConfig.LogoutURI, - } - - assets.RegisterMimeTypes() - - mux.Handle("/", - // Gzip first so that inner handlers can react to the addition of the Vary header - assets.GzipHandler( - // Generated config.js can not be cached since it changes depending on startup options - assets.GeneratedConfigHandler( - config, - // Cache control should happen after all Vary headers are added, but before - // any asset related routing (HTML5ModeHandler and FileServer) - assets.CacheControlHandler( - version.Get().GitCommit, - assets.HTML5ModeHandler( - http.FileServer( - &assetfs.AssetFS{ - assets.Asset, - assets.AssetDir, - "", - }, - ), - ), - ), - ), - ), - ) - - server := &http.Server{ - Addr: c.Options.AssetConfig.ServingInfo.BindAddress, - Handler: mux, - ReadTimeout: 5 * time.Minute, - WriteTimeout: 5 * time.Minute, - MaxHeaderBytes: 1 << 20, - } - - go util.Forever(func() { - if c.TLS { - server.TLSConfig = &tls.Config{ - // Change default from SSLv3 to TLSv1.0 (because of POODLE vulnerability) - MinVersion: tls.VersionTLS10, - } - glog.Infof("OpenShift UI listening at https://%s", c.Options.AssetConfig.ServingInfo.BindAddress) - glog.Fatal(server.ListenAndServeTLS(c.Options.AssetConfig.ServingInfo.ServerCert.CertFile, c.Options.AssetConfig.ServingInfo.ServerCert.KeyFile)) - } else { - glog.Infof("OpenShift UI listening at https://%s", c.Options.AssetConfig.ServingInfo.BindAddress) - glog.Fatal(server.ListenAndServe()) - } - }, 0) - - // Attempt to verify the server came up for 20 seconds (100 tries * 100ms, 100ms timeout per try) - cmdutil.WaitForSuccessfulDial(c.TLS, "tcp", c.Options.AssetConfig.ServingInfo.BindAddress, 100*time.Millisecond, 100*time.Millisecond, 100) - - glog.Infof("OpenShift UI available at %s", c.Options.AssetConfig.PublicURL) } func (c *MasterConfig) RunDNSServer() { diff --git a/pkg/cmd/server/start/master_args.go b/pkg/cmd/server/start/master_args.go index bc1a664c1695..69935401477b 100644 --- a/pkg/cmd/server/start/master_args.go +++ b/pkg/cmd/server/start/master_args.go @@ -74,8 +74,8 @@ func NewDefaultMasterArgs() *MasterArgs { PortalNet: flagtypes.DefaultIPNet("172.30.17.0/24"), MasterPublicAddr: flagtypes.Addr{Value: "localhost:8443", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default(), KubernetesPublicAddr: flagtypes.Addr{Value: "localhost:8443", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default(), - AssetPublicAddr: flagtypes.Addr{Value: "localhost:8444", DefaultScheme: "https", DefaultPort: 8444, AllowPrefix: true}.Default(), - AssetBindAddr: flagtypes.Addr{Value: "0.0.0.0:8444", DefaultScheme: "https", DefaultPort: 8444, AllowPrefix: true}.Default(), + AssetPublicAddr: flagtypes.Addr{Value: "https://localhost:8443/console", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default(), + AssetBindAddr: flagtypes.Addr{Value: "0.0.0.0:8443", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default(), DNSBindAddr: flagtypes.Addr{Value: "0.0.0.0:53", DefaultScheme: "http", DefaultPort: 53, AllowPrefix: true}.Default(), ListenArg: NewDefaultListenArg(), @@ -420,7 +420,7 @@ func (args MasterArgs) GetAssetPublicAddress() (*url.URL, error) { return nil, err } assetPublicAddr := *t - assetPublicAddr.Host = net.JoinHostPort(getHost(assetPublicAddr), strconv.Itoa(getPort(assetPublicAddr)+1)) + assetPublicAddr.Path = "/console" // TODO: make a constant, eventually make configurable return &assetPublicAddr, nil } @@ -429,8 +429,7 @@ func (args MasterArgs) GetAssetBindAddress() string { if args.AssetBindAddr.Provided { return args.AssetBindAddr.URL.Host } - // Derive the asset bind address by incrementing the master bind address port by 1 - return net.JoinHostPort(args.ListenArg.ListenAddr.Host, strconv.Itoa(args.ListenArg.ListenAddr.Port+1)) + return args.ListenArg.ListenAddr.URL.Host } func getHost(theURL url.URL) string { diff --git a/pkg/cmd/server/start/start_master.go b/pkg/cmd/server/start/start_master.go index c8694f2e532c..e17cb9149037 100644 --- a/pkg/cmd/server/start/start_master.go +++ b/pkg/cmd/server/start/start_master.go @@ -345,10 +345,27 @@ func StartMaster(openshiftMasterConfig *configapi.MasterConfig) error { // must start policy caching immediately openshiftConfig.RunPolicyCache() + unprotectedInstallers := []origin.APIInstaller{} + authConfig, err := origin.BuildAuthConfig(*openshiftMasterConfig) if err != nil { return err } + unprotectedInstallers = append(unprotectedInstallers, authConfig) + + var assetConfig *origin.AssetConfig + var assetColocated = false + if openshiftMasterConfig.AssetConfig != nil { + assetConfig, err := origin.BuildAssetConfig(*openshiftMasterConfig.AssetConfig) + if err != nil { + return err + } + + if openshiftMasterConfig.AssetConfig.ServingInfo.BindAddress == openshiftMasterConfig.ServingInfo.BindAddress { + assetColocated = true + unprotectedInstallers = append(unprotectedInstallers, assetConfig) + } + } if openshiftMasterConfig.KubernetesMasterConfig != nil { glog.Infof("Static Nodes: %v", openshiftMasterConfig.KubernetesMasterConfig.StaticNodeNames) @@ -359,7 +376,7 @@ func StartMaster(openshiftMasterConfig *configapi.MasterConfig) error { } kubeConfig.EnsurePortalFlags() - openshiftConfig.Run([]origin.APIInstaller{kubeConfig}, []origin.APIInstaller{authConfig}) + openshiftConfig.Run([]origin.APIInstaller{kubeConfig}, unprotectedInstallers) go daemon.SdNotify("READY=1") kubeConfig.RunScheduler() @@ -378,7 +395,7 @@ func StartMaster(openshiftMasterConfig *configapi.MasterConfig) error { ClientConfig: kubeConfig, } - openshiftConfig.Run([]origin.APIInstaller{proxy}, []origin.APIInstaller{authConfig}) + openshiftConfig.Run([]origin.APIInstaller{proxy}, unprotectedInstallers) go daemon.SdNotify("READY=1") } @@ -387,12 +404,12 @@ func StartMaster(openshiftMasterConfig *configapi.MasterConfig) error { glog.Infof("Using images from %q", openshiftConfig.ImageFor("")) + if assetConfig != nil && !assetColocated { + assetConfig.Run() + } if openshiftMasterConfig.DNSConfig != nil { openshiftConfig.RunDNSServer() } - if openshiftMasterConfig.AssetConfig != nil { - openshiftConfig.RunAssetServer() - } openshiftConfig.RunBuildController() openshiftConfig.RunBuildPodController() openshiftConfig.RunBuildImageChangeTriggerController() From 22045ca3d45f2ed520bd534a99250cdb4f0c6c2b Mon Sep 17 00:00:00 2001 From: Jessica Forrester Date: Wed, 25 Mar 2015 15:02:48 -0400 Subject: [PATCH 2/2] Asset changes needed to support a non / context root. Global redirect to asset server or dump of api paths when / is requested. --- assets/README.md | 18 + assets/app/index.html | 6 +- assets/app/scripts/app.js | 4 +- .../scripts/controllers/newfromtemplate.js | 4 +- assets/app/scripts/controllers/project.js | 2 +- assets/app/scripts/controllers/util/logout.js | 4 +- assets/app/scripts/controllers/util/oauth.js | 12 +- assets/app/scripts/directives/catalog.js | 2 +- assets/app/views/_project-nav.html | 2 +- assets/app/views/images.html | 2 +- assets/app/views/projects.html | 2 +- assets/bower.json | 6 +- assets/test/karma.conf.js | 2 +- hack/test-extended.sh | 2 - pkg/assets/bindata.go | 3110 +++++++++++------ pkg/assets/handlers.go | 27 +- pkg/cmd/server/api/validation/validation.go | 24 +- pkg/cmd/server/origin/asset.go | 75 +- pkg/cmd/server/origin/master.go | 60 +- pkg/cmd/server/start/config_test.go | 35 +- pkg/cmd/server/start/master_args.go | 15 +- pkg/cmd/server/start/start_master.go | 14 +- test/integration/root_redirect_test.go | 53 + test/util/server.go | 9 - 24 files changed, 2287 insertions(+), 1203 deletions(-) create mode 100644 test/integration/root_redirect_test.go diff --git a/assets/README.md b/assets/README.md index 1b78c034cf26..1ed43fdf6831 100644 --- a/assets/README.md +++ b/assets/README.md @@ -66,6 +66,24 @@ Architecture The OpenShift v3 management console is based on AngularJS and [Hawt.io](https://github.com/hawtio/hawtio-core) +#### Navigation + +The v3 console supports a custom context root. When running as part of the `openshift start` command the console's context root is injected into the `` tag of the index.html file. In order to support custom context roots, all console URLs must be relative, so they should not contain a leading "/" character. + +For example if you want to specify a URL directly in an HTML template to go to the project overview it would look like + +``` + +``` + +and would actually resolve to be `/contextroot/project/foo/overview` by the browser. Similarly, if you want to use JavaScript to change the current page location, you should use the $location service from angular like + +``` +$location.url("project/foo/overview") +``` + +Finally, if you want to reference the root of the web console use the path `./` + #### Custom directives and filters The v3 console relies heavily on custom directives and filters, some of which are intended to be utilties and used throughout the console source. The list below is NOT a complete list of all of our directives and filters. diff --git a/assets/app/index.html b/assets/app/index.html index 24703f2c748f..0ba829a63e7d 100644 --- a/assets/app/index.html +++ b/assets/app/index.html @@ -31,7 +31,7 @@ - + OpenShift Origin @@ -56,7 +56,7 @@
  • -->
  • - Log out + Log out
  • @@ -99,7 +99,7 @@ - + diff --git a/assets/app/scripts/app.js b/assets/app/scripts/app.js index 20a54ddb889c..a2c304840e27 100644 --- a/assets/app/scripts/app.js +++ b/assets/app/scripts/app.js @@ -42,10 +42,10 @@ angular if (injector) { var routeParams = injector.get("$routeParams"); if (routeParams.project) { - return "/project/" + encodeURIComponent(routeParams.project) + "/" + path; + return "project/" + encodeURIComponent(routeParams.project) + "/" + path; } } - return "/project/:project/" + path; + return "project/:project/" + path; } }; diff --git a/assets/app/scripts/controllers/newfromtemplate.js b/assets/app/scripts/controllers/newfromtemplate.js index a2062be8bdac..b4b8c018bd42 100644 --- a/assets/app/scripts/controllers/newfromtemplate.js +++ b/assets/app/scripts/controllers/newfromtemplate.js @@ -11,7 +11,7 @@ angular.module('openshiftConsole') .controller('NewFromTemplateController', function ($scope, $http, $routeParams, DataService, $q, $location, TaskList, $parse) { function errorPage(message) { - var redirect = URI('/error').query({ + var redirect = URI('error').query({ "error_description": message }).toString(); $location.url(redirect); @@ -133,7 +133,7 @@ angular.module('openshiftConsole') ); return d.promise; }); - $location.path("/project/" + $scope.projectName + "/overview"); + $location.path("project/" + $scope.projectName + "/overview"); }, function(result) { // failure $scope.alerts = [ diff --git a/assets/app/scripts/controllers/project.js b/assets/app/scripts/controllers/project.js index 0547d5798968..4bfa8da6d4a9 100644 --- a/assets/app/scripts/controllers/project.js +++ b/assets/app/scripts/controllers/project.js @@ -33,7 +33,7 @@ angular.module('openshiftConsole') var message = e.status == 403 ? ("The project " + $scope.projectName + " does not exist or you are not authorized to view it.") : ("The project " + $scope.projectName + " does not exist.") - var redirect = URI('/error').query({ + var redirect = URI('error').query({ "error_description": message, "error" : e.status == 403 ? 'access_denied' : 'not_found' }).toString(); diff --git a/assets/app/scripts/controllers/util/logout.js b/assets/app/scripts/controllers/util/logout.js index 00d59db72870..fe31f88d83fb 100644 --- a/assets/app/scripts/controllers/util/logout.js +++ b/assets/app/scripts/controllers/util/logout.js @@ -19,7 +19,7 @@ angular.module('openshiftConsole') // Make sure the logout completed if (AuthService.isLoggedIn()) { $log.debug("LogoutController, logout failed, still logged in"); - $scope.logoutMessage = 'You could not be logged out. Return to the console.'; + $scope.logoutMessage = 'You could not be logged out. Return to the console.'; } else { if (AUTH_CFG.logout_uri) { $log.debug("LogoutController, logout completed, redirecting to AUTH_CFG.logout_uri", AUTH_CFG.logout_uri); @@ -37,6 +37,6 @@ angular.module('openshiftConsole') } else { // TODO: redirect to configurable logout destination $log.debug("LogoutController, not logged in, logout complete"); - $scope.logoutMessage = 'You are logged out. Return to the console.'; + $scope.logoutMessage = 'You are logged out. Return to the console.'; } }); diff --git a/assets/app/scripts/controllers/util/oauth.js b/assets/app/scripts/controllers/util/oauth.js index 3c928ab58d6e..ffb8ce1e796c 100644 --- a/assets/app/scripts/controllers/util/oauth.js +++ b/assets/app/scripts/controllers/util/oauth.js @@ -20,7 +20,7 @@ angular.module('openshiftConsole') // Typically, this means we accessed /oauth directly, rather than via an auth redirect if (!token) { authLogger.log("OAuthController, no token or error, redirecting to /"); - $location.url('/'); + $location.url('./'); return; } @@ -35,24 +35,24 @@ angular.module('openshiftConsole') AuthService.setUser(user, token); // Redirect to original destination (or default to '/') - var destination = then || '/'; + var destination = then || './'; if (URI(destination).is('absolute')) { - if (debug) { Logger.log("OAuthController, invalid absolute redirect", destination); } - destination = '/'; + authLogger.log("OAuthController, invalid absolute redirect", destination); + destination = './'; } authLogger.log("OAuthController, redirecting", destination); $location.url(destination); }) .catch(function(rejection) { // Handle an API error response fetching the user - var redirect = URI('/error').query({error: 'user_fetch_failed'}).toString(); + var redirect = URI('error').query({error: 'user_fetch_failed'}).toString(); authLogger.error("OAuthController, error fetching user", rejection, "redirecting", redirect); $location.url(redirect); }); }) .catch(function(rejection) { - var redirect = URI('/error').query({ + var redirect = URI('error').query({ error: rejection.error || "", error_description: rejection.error_description || "", error_uri: rejection.error_uri || "", diff --git a/assets/app/scripts/directives/catalog.js b/assets/app/scripts/directives/catalog.js index bb58b1b7c1e7..59db22b7420e 100644 --- a/assets/app/scripts/directives/catalog.js +++ b/assets/app/scripts/directives/catalog.js @@ -14,7 +14,7 @@ angular.module('openshiftConsole') // Must trigger off of the modal's hidden event to guarantee modal has finished closing before switching screens $(".modal", elem).on('hidden.bs.modal', function () { scope.$apply(function() { - var createURI = URI.expand("/project/{project}/create/fromtemplate{?q*}", { + var createURI = URI.expand("project/{project}/create/fromtemplate{?q*}", { project: scope.project, q: { name: scope.template.metadata.name, diff --git a/assets/app/views/_project-nav.html b/assets/app/views/_project-nav.html index 298c1d7cdd8a..36b73c478b90 100644 --- a/assets/app/views/_project-nav.html +++ b/assets/app/views/_project-nav.html @@ -18,7 +18,7 @@
    - + diff --git a/assets/app/views/images.html b/assets/app/views/images.html index d01b1125a2fa..3059255c5058 100644 --- a/assets/app/views/images.html +++ b/assets/app/views/images.html @@ -11,7 +11,7 @@

    Images

    {{image.dockerImageReference | imageName}} ({{image.metadata.name}})

    Created:
    -
    Created from: Build {{build.metadata.labels.buildconfig}} ({{build.metadata.name.substr(0, 10)}}) +
    Created from: Build {{build.metadata.labels.buildconfig}} ({{build.metadata.name.substr(0, 10)}})
    diff --git a/assets/app/views/projects.html b/assets/app/views/projects.html index 5cf887994ac3..30c52d8df946 100644 --- a/assets/app/views/projects.html +++ b/assets/app/views/projects.html @@ -1,7 +1,7 @@

    Projects

    {{emptyMessage}}
    diff --git a/assets/bower.json b/assets/bower.json index d46c4c19a6b9..80cfbd6692b5 100644 --- a/assets/bower.json +++ b/assets/bower.json @@ -15,10 +15,10 @@ "uri.js": "1.14.1", "moment": "2.8.4", "patternfly": "1.1.2", - "hawtio-core": "2.0.8", - "hawtio-core-navigation": "2.0.15", + "hawtio-core": "2.0.11", + "hawtio-core-navigation": "2.0.33", "hawtio-extension-service": "2.0.0", - "lodash": "2.4.1", + "lodash": "3.2.0", "jquery": "2.1.3", "sifter": "0.3.4", "microplugin": "0.0.3", diff --git a/assets/test/karma.conf.js b/assets/test/karma.conf.js index cbf99256b0cb..aa0d1e0c7ee2 100644 --- a/assets/test/karma.conf.js +++ b/assets/test/karma.conf.js @@ -38,7 +38,7 @@ module.exports = function(config) { "bower_components/js-logger/src/logger.js", //"bower_components/webcomponentsjs/webcomponents.js", "bower_components/hawtio-core/hawtio-core.js", - "bower_components/lodash/dist/lodash.compat.js", + "bower_components/lodash/lodash.js", "bower_components/hawtio-core-navigation/dist/hawtio-core-navigation.js", "bower_components/hawtio-extension-service/dist/hawtio-extension-service.js", 'app/scripts/**/*.js', diff --git a/hack/test-extended.sh b/hack/test-extended.sh index a212c8c1c6f7..5bc08ea5a49f 100755 --- a/hack/test-extended.sh +++ b/hack/test-extended.sh @@ -13,14 +13,12 @@ TIME_MIN=$((60 * $TIME_SEC)) # TODO: Randomize these ports export OS_MASTER_PORT=$(go run ${OS_ROOT}/test/util/random_port/generate.go) -export OS_ASSETS_PORT=$(go run ${OS_ROOT}/test/util/random_port/generate.go) export OS_DNS_PORT=$(go run ${OS_ROOT}/test/util/random_port/generate.go) export ETCD_PORT=$(go run ${OS_ROOT}/test/util/random_port/generate.go) DEFAULT_SERVER_IP=$(ifconfig | grep -Ev "(127.0.0.1|172.17.42.1)" | grep "inet " | head -n 1 | awk '{print $2}') export OS_MASTER_ADDR=${DEFAULT_SERVER_IP}:${OS_MASTER_PORT} -export OS_ASSETS_ADDR=${DEFAULT_SERVER_IP}:${OS_ASSETS_PORT} export OS_DNS_ADDR=${DEFAULT_SERVER_IP}:${OS_DNS_PORT} export KUBERNETES_MASTER="https://${OS_MASTER_ADDR}" diff --git a/pkg/assets/bindata.go b/pkg/assets/bindata.go index cca4f0e92a2f..19f96d8704b2 100644 --- a/pkg/assets/bindata.go +++ b/pkg/assets/bindata.go @@ -12512,7 +12512,7 @@ var _index_html = []byte(` - + OpenShift Origin
    @@ -12529,7 +12529,7 @@ var _index_html = []byte(` @@ -13179,9 +13179,9 @@ return function() { var b = HawtioCore.injector; if (b) { var c = b.get("$routeParams"); -if (c.project) return "/project/" + encodeURIComponent(c.project) + "/" + a; +if (c.project) return "project/" + encodeURIComponent(c.project) + "/" + a; } -return "/project/:project/" + a; +return "project/:project/" + a; }; }, f = "views", g = "openshiftConsole", h = c.create().id(c.join(g, "overview")).title(function() { return "Overview"; @@ -14182,7 +14182,7 @@ errorNotification:!1 a.project = b, a.projectPromise.resolve(b); }, function(b) { if (a.projectPromise.reject(b), 403 == b.status || 404 == b.status) { -var c = 403 == b.status ? "The project " + a.projectName + " does not exist or you are not authorized to view it." :"The project " + a.projectName + " does not exist.", d = URI("/error").query({ +var c = 403 == b.status ? "The project " + a.projectName + " does not exist or you are not authorized to view it." :"The project " + a.projectName + " does not exist.", d = URI("error").query({ error_description:c, error:403 == b.status ? "access_denied" :"not_found" }).toString(); @@ -14460,7 +14460,7 @@ b.unwatchAll(f); }); } ]), angular.module("openshiftConsole").controller("NewFromTemplateController", [ "$scope", "$http", "$routeParams", "DataService", "$q", "$location", "TaskList", "$parse", function(a, b, c, d, e, f, g, h) { function i(a) { -var b = URI("/error").query({ +var b = URI("error").query({ error_description:a }).toString(); f.url(b); @@ -14528,7 +14528,7 @@ alerts:d, hasErrors:e }); }), c.promise; -}), f.path("/project/" + a.projectName + "/overview"); +}), f.path("project/" + a.projectName + "/overview"); }, function(b) { a.alerts = [ { type:"error", @@ -14568,9 +14568,9 @@ a.expanded = !a.expanded; } ]), angular.module("openshiftConsole").controller("OAuthController", [ "$location", "$q", "RedirectLoginService", "DataService", "AuthService", "Logger", function(a, b, c, d, e, f) { var g = f.get("auth"); c.finish().then(function(b) { -var c = b.token, h = b.then; -if (!c) return g.log("OAuthController, no token or error, redirecting to /"), void a.url("/"); -var i = { +var c = b.token, f = b.then; +if (!c) return g.log("OAuthController, no token or error, redirecting to /"), void a.url("./"); +var h = { errorNotification:!1, http:{ auth:{ @@ -14579,18 +14579,18 @@ triggerLogin:!1 } } }; -g.log("OAuthController, got token, fetching user", i), d.get("users", "~", {}, i).then(function(b) { +g.log("OAuthController, got token, fetching user", h), d.get("users", "~", {}, h).then(function(b) { g.log("OAuthController, got user", b), e.setUser(b, c); -var d = h || "/"; -URI(d).is("absolute") && (debug && f.log("OAuthController, invalid absolute redirect", d), d = "/"), g.log("OAuthController, redirecting", d), a.url(d); +var d = f || "./"; +URI(d).is("absolute") && (g.log("OAuthController, invalid absolute redirect", d), d = "./"), g.log("OAuthController, redirecting", d), a.url(d); })["catch"](function(b) { -var c = URI("/error").query({ +var c = URI("error").query({ error:"user_fetch_failed" }).toString(); g.error("OAuthController, error fetching user", b, "redirecting", c), a.url(c); }); })["catch"](function(b) { -var c = URI("/error").query({ +var c = URI("error").query({ error:b.error || "", error_description:b.error_description || "", error_uri:b.error_uri || "" @@ -14617,8 +14617,8 @@ a.errorMessage = "An error has occurred"; b.error_description && (a.errorDetails = b.error_description); } ]), angular.module("openshiftConsole").controller("LogoutController", [ "$scope", "$log", "AuthService", "AUTH_CFG", function(a, b, c, d) { b.debug("LogoutController"), c.isLoggedIn() ? (b.debug("LogoutController, logged in, initiating logout"), a.logoutMessage = "Logging out...", c.startLogout()["finally"](function() { -c.isLoggedIn() ? (b.debug("LogoutController, logout failed, still logged in"), a.logoutMessage = 'You could not be logged out. Return to the console.') :d.logout_uri ? (b.debug("LogoutController, logout completed, redirecting to AUTH_CFG.logout_uri", d.logout_uri), window.location.href = d.logout_uri) :(b.debug("LogoutController, logout completed, reloading the page"), window.location.reload(!1)); -})) :d.logout_uri ? (b.debug("LogoutController, logout completed, redirecting to AUTH_CFG.logout_uri", d.logout_uri), a.logoutMessage = "Logging out...", window.location.href = d.logout_uri) :(b.debug("LogoutController, not logged in, logout complete"), a.logoutMessage = 'You are logged out. Return to the console.'); +c.isLoggedIn() ? (b.debug("LogoutController, logout failed, still logged in"), a.logoutMessage = 'You could not be logged out. Return to the console.') :d.logout_uri ? (b.debug("LogoutController, logout completed, redirecting to AUTH_CFG.logout_uri", d.logout_uri), window.location.href = d.logout_uri) :(b.debug("LogoutController, logout completed, reloading the page"), window.location.reload(!1)); +})) :d.logout_uri ? (b.debug("LogoutController, logout completed, redirecting to AUTH_CFG.logout_uri", d.logout_uri), a.logoutMessage = "Logging out...", window.location.href = d.logout_uri) :(b.debug("LogoutController, not logged in, logout complete"), a.logoutMessage = 'You are logged out. Return to the console.'); } ]), angular.module("openshiftConsole").controller("CatalogController", [ "$scope", "DataService", "$filter", "LabelFilter", "Logger", function(a, b, c, d, e) { a.projectTemplates = {}, a.openshiftTemplates = {}, a.templatesByTag = {}, a.templates = [], a.instantApps = [], b.list("templates", a, function(b) { a.projectTemplates = b.by("metadata.name"), f(), g(), e.log("project templates", a.projectTemplates); @@ -14870,7 +14870,7 @@ link:function(b, c) { $(".select-template", c).click(function() { $(".modal", c).on("hidden.bs.modal", function() { b.$apply(function() { -var c = URI.expand("/project/{project}/create/fromtemplate{?q*}", { +var c = URI.expand("project/{project}/create/fromtemplate{?q*}", { project:b.project, q:{ name:b.template.metadata.name, @@ -29954,8 +29954,8 @@ a(); var hawtioPluginLoader = function(a) { var b = Logger.get("hawtio-loader"); -return a.log = b, a.urls = [], a.modules = [], a.tasks = [], a.registerPreBootstrapTask = function(b) { -a.tasks.push(b); +return a.log = b, a.urls = [], a.modules = [], a.tasks = [], a.registerPreBootstrapTask = function(b, c) { +c ? a.tasks.unshift(b) :a.tasks.push(b); }, a.addModule = function(c) { b.debug("Adding module: " + c), a.modules.push(c); }, a.addUrl = function(c) { @@ -30116,1242 +30116,2081 @@ return b || (b = {}, a.toastr = b), b; } ]), c.factory("branding", function() { return {}; }), c.factory("userDetails", function() { -return {}; +return { +logout:function() { +b.debug("Dummy userDetails.logout()"); +} +}; }), hawtioPluginLoader.addModule("ng"), hawtioPluginLoader.addModule("ngSanitize"), hawtioPluginLoader.addModule(a.pluginName), $(function() { hawtioPluginLoader.loadPlugins(function() { -a.injector = angular.bootstrap(document, hawtioPluginLoader.getModules()), b.debug("Bootstrapped application"); +a.injector ? b.debug("Application already bootstrapped") :(a.injector = angular.bootstrap(document, hawtioPluginLoader.getModules()), b.debug("Bootstrapped application")); }); }); }(HawtioCore || (HawtioCore = {})), function() { -function a(a, b, c) { -for (var d = (c || 0) - 1, e = a ? a.length :0; ++d < e; ) if (a[d] === b) return d; -return -1; +function a(a, b) { +if (a !== b) { +var c = a === a, d = b === b; +if (a > b || !c || "undefined" == typeof a && d) return 1; +if (b > a || !d || "undefined" == typeof b && c) return -1; } -function b(b, c) { -var d = typeof c; -if (b = b.cache, "boolean" == d || null == c) return b[c] ? 0 :-1; -"number" != d && "string" != d && (d = "object"); -var e = "number" == d ? c :u + c; -return b = (b = b[d]) && b[e], "object" == d ? b && a(b, c) > -1 ? 0 :-1 :b ? 0 :-1; +return 0; } -function c(a) { -var b = this.cache, c = typeof a; -if ("boolean" == c || null == a) b[a] = !0; else { -"number" != c && "string" != c && (c = "object"); -var d = "number" == c ? a :u + a, e = b[c] || (b[c] = {}); -"object" == c ? (e[d] || (e[d] = [])).push(a) :e[d] = !0; +function b(a, b, c) { +if (b !== b) return m(a, c); +for (var d = (c || 0) - 1, e = a.length; ++d < e; ) if (a[d] === b) return d; +return -1; } +function c(a, b) { +var c = a.length; +for (a.sort(b); c--; ) a[c] = a[c].value; +return a; } function d(a) { -return a.charCodeAt(0); -} -function e(a, b) { -for (var c = a.criteria, d = b.criteria, e = -1, f = c.length; ++e < f; ) { -var g = c[e], h = d[e]; -if (g !== h) { -if (g > h || "undefined" == typeof g) return 1; -if (h > g || "undefined" == typeof h) return -1; +return "string" == typeof a ? a :null == a ? "" :a + ""; } +function e(a) { +return a.charCodeAt(0); } -return a.index - b.index; +function f(a, b) { +for (var c = -1, d = a.length; ++c < d && b.indexOf(a.charAt(c)) > -1; ) ; +return c; } -function f(a) { -var b = -1, d = a.length, e = a[0], f = a[d / 2 | 0], g = a[d - 1]; -if (e && "object" == typeof e && f && "object" == typeof f && g && "object" == typeof g) return !1; -var h = i(); -h["false"] = h["null"] = h["true"] = h.undefined = !1; -var j = i(); -for (j.array = a, j.cache = h, j.push = c; ++b < d; ) j.push(a[b]); -return j; +function g(a, b) { +for (var c = a.length; c-- && b.indexOf(a.charAt(c)) > -1; ) ; +return c; } -function g(a) { -return "\\" + _[a]; +function h(b, c) { +return a(b.criteria, c.criteria) || b.index - c.index; } -function h() { -return q.pop() || []; +function i(b, c) { +for (var d = -1, e = b.criteria, f = c.criteria, g = e.length; ++d < g; ) { +var h = a(e[d], f[d]); +if (h) return h; } -function i() { -return r.pop() || { -array:null, -cache:null, -criteria:null, -"false":!1, -index:0, -"null":!1, -number:null, -object:null, -push:null, -string:null, -"true":!1, -undefined:!1, -value:null -}; +return b.index - c.index; } function j(a) { -return "function" != typeof a.toString && "string" == typeof (a + ""); +return Ma[a]; +} +function k(a) { +return Na[a]; } function l(a) { -a.length = 0, q.length < w && q.push(a); +return "\\" + Qa[a]; } -function m(a) { -var b = a.cache; -b && m(b), a.array = a.cache = a.criteria = a.object = a.number = a.string = a.value = null, r.length < w && r.push(a); +function m(a, b, c) { +for (var d = a.length, e = c ? b || d :(b || 0) - 1; c ? e-- :++e < d; ) { +var f = a[e]; +if (f !== f) return e; } -function n(a, b, c) { -b || (b = 0), "undefined" == typeof c && (c = a ? a.length :0); -for (var d = -1, e = c - b || 0, f = Array(0 > e ? 0 :e); ++d < e; ) f[d] = a[b + d]; -return f; +return -1; } -function o(c) { -function q(a) { -return a && "object" == typeof a && !kd(a) && Rc.call(a, "__wrapped__") ? a :new r(a); +function n(a) { +return a && "object" == typeof a || !1; } -function r(a, b) { -this.__chain__ = !!b, this.__wrapped__ = a; +function o(a) { +return 160 >= a && a >= 9 && 13 >= a || 32 == a || 160 == a || 5760 == a || 6158 == a || a >= 8192 && (8202 >= a || 8232 == a || 8233 == a || 8239 == a || 8287 == a || 12288 == a || 65279 == a); } -function w(a) { -function b() { -if (d) { -var a = n(d); -Sc.apply(a, arguments); +function p(a, b) { +for (var c = -1, d = a.length, e = -1, f = []; ++c < d; ) a[c] === b && (a[c] = O, f[++e] = c); +return f; } -if (this instanceof b) { -var f = ba(c.prototype), g = c.apply(f, a || arguments); -return La(g) ? g :f; +function q(a, b) { +for (var c, d = -1, e = a.length, f = -1, g = []; ++d < e; ) { +var h = a[d], i = b ? b(h, d, a) :h; +d && c === i || (c = i, g[++f] = h); } -return c.apply(e, a || arguments); +return g; } -var c = a[0], d = a[2], e = a[4]; -return jd(b, a), b; +function r(a) { +for (var b = -1, c = a.length; ++b < c && o(a.charCodeAt(b)); ) ; +return b; } -function _(a, b, c, d, e) { -if (c) { -var f = c(a); -if ("undefined" != typeof f) return f; -} -var g = La(a); -if (!g) return a; -var i = Kc.call(a); -if (!W[i] || !hd.nodeClass && j(a)) return a; -var k = fd[i]; -switch (i) { -case O: -case P: -return new k(+a); - -case S: -case V: -return new k(a); - -case U: -return f = k(a.source, C.exec(a)), f.lastIndex = a.lastIndex, f; +function s(a) { +for (var b = a.length; b-- && o(a.charCodeAt(b)); ) ; +return b; } -var m = kd(a); -if (b) { -var o = !d; -d || (d = h()), e || (e = h()); -for (var p = d.length; p--; ) if (d[p] == a) return e[p]; -f = m ? k(a.length) :{}; -} else f = m ? n(a) :vd({}, a); -return m && (Rc.call(a, "index") && (f.index = a.index), Rc.call(a, "input") && (f.input = a.input)), b ? (d.push(a), e.push(f), (m ? ud :yd)(a, function(a, g) { -f[g] = _(a, b, c, d, e); -}), o && (l(d), l(e)), f) :f; +function t(a) { +return Oa[a]; } -function ba(a) { -return La(a) ? Yc(a) :{}; +function u(o) { +function V(a) { +if (n(a) && !Xg(a) && !(a instanceof _)) { +if (a instanceof Z) return a; +if (_f.call(a, "__chain__") && _f.call(a, "__wrapped__")) return Ic(a); } -function ca(a, b, c) { -if ("function" != typeof a) return ec; -if ("undefined" == typeof b || !("prototype" in a)) return a; -var d = a.__bindData__; -if ("undefined" == typeof d && (hd.funcNames && (d = !a.name), d = d || !hd.funcDecomp, !d)) { -var e = Pc.call(a); -hd.funcNames || (d = !D.test(e)), d || (d = H.test(e), jd(a, d)); +return new Z(a); } -if (d === !1 || d !== !0 && 1 & d[1]) return a; -switch (c) { -case 1: -return function(c) { -return a.call(b, c); -}; - -case 2: -return function(c, d) { -return a.call(b, c, d); -}; - -case 3: -return function(c, d, e) { -return a.call(b, c, d, e); -}; - -case 4: -return function(c, d, e, f) { -return a.call(b, c, d, e, f); -}; +function Z(a, b, c) { +this.__wrapped__ = a, this.__actions__ = c || [], this.__chain__ = !!b; } -return Pb(a, b); +function _(a) { +this.__wrapped__ = a, this.__actions__ = null, this.__dir__ = 1, this.__dropCount__ = 0, this.__filtered__ = !1, this.__iteratees__ = null, this.__takeCount__ = Dg, this.__views__ = null; } -function da(a) { -function b() { -var a = i ? g :this; -if (e) { -var o = n(e); -Sc.apply(o, arguments); +function Ma() { +var a = this.__actions__, b = this.__iteratees__, c = this.__views__, d = new _(this.__wrapped__); +return d.__actions__ = a ? Za(a) :null, d.__dir__ = this.__dir__, d.__dropCount__ = this.__dropCount__, d.__filtered__ = this.__filtered__, d.__iteratees__ = b ? Za(b) :null, d.__takeCount__ = this.__takeCount__, d.__views__ = c ? Za(c) :null, d; } -if ((f || k) && (o || (o = n(arguments)), f && Sc.apply(o, f), k && o.length < h)) return d |= 16, da([ c, l ? d :-4 & d, o, null, g, h ]); -if (o || (o = arguments), j && (c = a[m]), this instanceof b) { -a = ba(c.prototype); -var p = c.apply(a, o); -return La(p) ? p :a; +function Na() { +if (this.__filtered__) { +var a = new _(this); +a.__dir__ = -1, a.__filtered__ = !0; +} else a = this.clone(), a.__dir__ *= -1; +return a; } -return c.apply(a, o); +function Oa() { +var a = this.__wrapped__.value(); +if (!Xg(a)) return Wb(a, this.__actions__); +var b = this.__dir__, c = 0 > b, d = rc(0, a.length, this.__views__), e = d.start, f = d.end, g = f - e, h = this.__dropCount__, i = xg(g, this.__takeCount__), j = c ? f :e - 1, k = this.__iteratees__, l = k ? k.length :0, m = 0, n = []; +a:for (;g-- && i > m; ) { +j += b; +for (var o = -1, p = a[j]; ++o < l; ) { +var q = k[o], r = q.iteratee, s = r(p, j, a), t = q.type; +if (t == L) p = s; else if (!s) { +if (t == K) continue a; +break a; } -var c = a[0], d = a[1], e = a[2], f = a[3], g = a[4], h = a[5], i = 1 & d, j = 2 & d, k = 4 & d, l = 8 & d, m = c; -return jd(b, a), b; } -function ea(c, d) { -var e = -1, g = pa(), h = c ? c.length :0, i = h >= v && g === a, j = []; -if (i) { -var k = f(d); -k ? (g = b, d = k) :i = !1; +h ? h-- :n[m++] = p; } -for (;++e < h; ) { -var l = c[e]; -g(d, l) < 0 && j.push(l); +return n; } -return i && m(d), j; +function Pa() { +this.__data__ = {}; } -function ga(a, b, c, d) { -for (var e = (d || 0) - 1, f = a ? a.length :0, g = []; ++e < f; ) { -var h = a[e]; -if (h && "object" == typeof h && "number" == typeof h.length && (kd(h) || ta(h))) { -b || (h = ga(h, b, c)); -var i = -1, j = h.length, k = g.length; -for (g.length += j; ++i < j; ) g[k++] = h[i]; -} else c || g.push(h); +function Qa(a) { +return this.has(a) && delete this.__data__[a]; } -return g; +function Sa(a) { +return "__proto__" == a ? v :this.__data__[a]; } -function ha(a, b, c, d, e, f) { -if (c) { -var g = c(a, b); -if ("undefined" != typeof g) return !!g; +function Ta(a) { +return "__proto__" != a && _f.call(this.__data__, a); } -if (a === b) return 0 !== a || 1 / a == 1 / b; -var i = typeof a, k = typeof b; -if (!(a !== a || a && $[i] || b && $[k])) return !1; -if (null == a || null == b) return a === b; -var m = Kc.call(a), n = Kc.call(b); -if (m == M && (m = T), n == M && (n = T), m != n) return !1; -switch (m) { -case O: -case P: -return +a == +b; - -case S: -return a != +a ? b != +b :0 == a ? 1 / a == 1 / b :a == +b; - -case U: -case V: -return a == Dc(b); -} -var o = m == N; -if (!o) { -var p = Rc.call(a, "__wrapped__"), q = Rc.call(b, "__wrapped__"); -if (p || q) return ha(p ? a.__wrapped__ :a, q ? b.__wrapped__ :b, c, d, e, f); -if (m != T || !hd.nodeClass && (j(a) || j(b))) return !1; -var r = !hd.argsObject && ta(a) ? Bc :a.constructor, s = !hd.argsObject && ta(b) ? Bc :b.constructor; -if (r != s && !(Ka(r) && r instanceof r && Ka(s) && s instanceof s) && "constructor" in a && "constructor" in b) return !1; -} -var t = !e; -e || (e = h()), f || (f = h()); -for (var u = e.length; u--; ) if (e[u] == a) return f[u] == b; -var v = 0; -if (g = !0, e.push(a), f.push(b), o) { -if (u = a.length, v = b.length, g = v == u, g || d) for (;v--; ) { -var w = u, x = b[v]; -if (d) for (;w-- && !(g = ha(a[w], x, c, d, e, f)); ) ; else if (!(g = ha(a[v], x, c, d, e, f))) break; -} -} else xd(b, function(b, h, i) { -return Rc.call(i, h) ? (v++, g = Rc.call(a, h) && ha(a[h], b, c, d, e, f)) :void 0; -}), g && !d && xd(a, function(a, b, c) { -return Rc.call(c, b) ? g = --v > -1 :void 0; -}); -return e.pop(), f.pop(), t && (l(e), l(f)), g; +function Ua(a, b) { +return "__proto__" != a && (this.__data__[a] = b), this; } -function ia(a, b, c, d, e) { -(kd(b) ? db :yd)(b, function(b, f) { -var g, h, i = b, j = a[f]; -if (b && ((h = kd(b)) || zd(b))) { -for (var k = d.length; k--; ) if (g = d[k] == b) { -j = e[k]; -break; +function Va(a) { +var b = a ? a.length :0; +for (this.data = { +hash:tg(null), +set:new mg() +}; b--; ) this.push(a[b]); } -if (!g) { -var l; -c && (i = c(j, b), (l = "undefined" != typeof i) && (j = i)), l || (j = h ? kd(j) ? j :[] :zd(j) ? j :{}), d.push(b), e.push(j), l || ia(j, b, c, d, e); +function Xa(a, b) { +var c = a.data, d = "string" == typeof b || Ae(b) ? c.set.has(b) :c.hash[b]; +return d ? 0 :-1; } -} else c && (i = c(j, b), "undefined" == typeof i && (i = b)), "undefined" != typeof i && (j = i); -a[f] = j; -}); +function Ya(a) { +var b = this.data; +"string" == typeof a || Ae(a) ? b.set.add(a) :b.hash[a] = !0; } -function ja(a, b) { -return a + Oc(ed() * (b - a + 1)); +function Za(a, b) { +var c = -1, d = a.length; +for (b || (b = Mf(d)); ++c < d; ) b[c] = a[c]; +return b; } -function ka(c, d, e) { -var g = -1, i = pa(), j = c ? c.length :0, k = [], n = !d && j >= v && i === a, o = e || n ? h() :k; -if (n) { -var p = f(o); -i = b, o = p; +function $a(a, b) { +for (var c = -1, d = a.length; ++c < d && b(a[c], c, a) !== !1; ) ; +return a; } -for (;++g < j; ) { -var q = c[g], r = e ? e(q, g, c) :q; -(d ? !g || o[o.length - 1] !== r :i(o, r) < 0) && ((e || n) && o.push(r), k.push(q)); +function _a(a, b) { +for (var c = a.length; c-- && b(a[c], c, a) !== !1; ) ; +return a; } -return n ? (l(o.array), m(o)) :e && l(o), k; +function ab(a, b) { +for (var c = -1, d = a.length; ++c < d; ) if (!b(a[c], c, a)) return !1; +return !0; } -function la(a) { -return function(b, c, d) { -var e = {}; -if (c = q.createCallback(c, d, 3), kd(b)) for (var f = -1, g = b.length; ++f < g; ) { -var h = b[f]; -a(e, h, c(h, f, b), b); -} else ud(b, function(b, d, f) { -a(e, b, c(b, d, f), f); -}); +function bb(a, b) { +for (var c = -1, d = a.length, e = -1, f = []; ++c < d; ) { +var g = a[c]; +b(g, c, a) && (f[++e] = g); +} +return f; +} +function cb(a, b) { +for (var c = -1, d = a.length, e = Mf(d); ++c < d; ) e[c] = b(a[c], c, a); return e; -}; } -function ma(a, b, c, d, e, f) { -var g = 1 & b, h = 2 & b, i = 4 & b, j = 16 & b, k = 32 & b; -if (!h && !Ka(a)) throw new Ec(); -j && !c.length && (b &= -17, j = c = !1), k && !d.length && (b &= -33, k = d = !1); -var l = a && a.__bindData__; -if (l && l !== !0) return l = n(l), l[2] && (l[2] = n(l[2])), l[3] && (l[3] = n(l[3])), !g || 1 & l[1] || (l[4] = e), !g && 1 & l[1] && (b |= 8), !i || 4 & l[1] || (l[5] = f), j && Sc.apply(l[2] || (l[2] = []), c), k && Wc.apply(l[3] || (l[3] = []), d), l[1] |= b, ma.apply(null, l); -var m = 1 == b || 17 === b ? w :da; -return m([ a, b, c, d, e, f ]); -} -function na() { -Z.shadowedProps = K, Z.array = Z.bottom = Z.loop = Z.top = "", Z.init = "iterable", Z.useHas = !0; -for (var a, b = 0; a = arguments[b]; b++) for (var c in a) Z[c] = a[c]; -var d = Z.args; -Z.firstArg = /^[^,]+/.exec(d)[0]; -var e = yc("baseCreateCallback, errorClass, errorProto, hasOwnProperty, indicatorObject, isArguments, isArray, isString, keys, objectProto, objectTypes, nonEnumProps, stringClass, stringProto, toString", "return function(" + d + ") {\n" + id(Z) + "\n}"); -return e(ca, Q, Gc, Rc, t, ta, kd, Qa, Z.keys, Hc, $, gd, V, Ic, Kc); -} -function oa(a) { -return qd[a]; -} -function pa() { -var b = (b = q.indexOf) === yb ? a :b; -return b; +function db(a) { +for (var b = -1, c = a.length, d = Cg; ++b < c; ) { +var e = a[b]; +e > d && (d = e); } -function qa(a) { -return "function" == typeof a && Lc.test(a); +return d; } -function ra(a) { -var b, c; -return !a || Kc.call(a) != T || (b = a.constructor, Ka(b) && !(b instanceof b)) || !hd.argsClass && ta(a) || !hd.nodeClass && j(a) ? !1 :hd.ownLast ? (xd(a, function(a, b, d) { -return c = Rc.call(d, b), !1; -}), c !== !1) :(xd(a, function(a, b) { -c = b; -}), "undefined" == typeof c || Rc.call(a, c)); +function eb(a) { +for (var b = -1, c = a.length, d = Dg; ++b < c; ) { +var e = a[b]; +d > e && (d = e); } -function sa(a) { -return rd[a]; +return d; } -function ta(a) { -return a && "object" == typeof a && "number" == typeof a.length && Kc.call(a) == M || !1; +function fb(a, b, c, d) { +var e = -1, f = a.length; +for (d && f && (c = a[++e]); ++e < f; ) c = b(c, a[e], e, a); +return c; } -function ua(a, b, c, d) { -return "boolean" != typeof b && null != b && (d = c, c = b, b = !1), _(a, b, "function" == typeof c && ca(c, d, 1)); +function gb(a, b, c, d) { +var e = a.length; +for (d && e && (c = a[--e]); e--; ) c = b(c, a[e], e, a); +return c; } -function va(a, b, c) { -return _(a, !0, "function" == typeof b && ca(b, c, 1)); +function hb(a, b) { +for (var c = -1, d = a.length; ++c < d; ) if (b(a[c], c, a)) return !0; +return !1; } -function wa(a, b) { -var c = ba(a); -return b ? vd(c, b) :c; +function ib(a, b) { +return "undefined" == typeof a ? b :a; } -function xa(a, b, c) { -var d; -return b = q.createCallback(b, c, 3), yd(a, function(a, c, e) { -return b(a, c, e) ? (d = c, !1) :void 0; -}), d; +function jb(a, b, c, d) { +return "undefined" != typeof a && _f.call(d, c) ? a :b; } -function ya(a, b, c) { -var d; -return b = q.createCallback(b, c, 3), Aa(a, function(a, c, e) { -return b(a, c, e) ? (d = c, !1) :void 0; -}), d; +function kb(a, b, c) { +var d = _g(b); +if (!c) return mb(b, a, d); +for (var e = -1, f = d.length; ++e < f; ) { +var g = d[e], h = a[g], i = c(h, b[g], g, a, b); +(i === i ? i === h :h !== h) && ("undefined" != typeof h || g in a) || (a[g] = i); } -function za(a, b, c) { -var d = []; -xd(a, function(a, b) { -d.push(b, a); -}); -var e = d.length; -for (b = ca(b, c, 3); e-- && b(d[e--], d[e], a) !== !1; ) ; return a; } -function Aa(a, b, c) { -var d = md(a), e = d.length; -for (b = ca(b, c, 3); e--; ) { -var f = d[e]; -if (b(a[f], f, a) === !1) break; +function lb(a, b) { +for (var c = -1, d = a.length, e = yc(d), f = b.length, g = Mf(f); ++c < f; ) { +var h = b[c]; +e ? (h = parseFloat(h), g[c] = wc(h, d) ? a[h] :v) :g[c] = a[h]; +} +return g; +} +function mb(a, b, c) { +c || (c = b, b = {}); +for (var d = -1, e = c.length; ++d < e; ) { +var f = c[d]; +b[f] = a[f]; +} +return b; +} +function nb(a, b) { +for (var c = -1, d = b.length; ++c < d; ) { +var e = b[c]; +a[e] = kc(a[e], x, a); } return a; } -function Ba(a) { -var b = []; -return xd(a, function(a, c) { -Ka(a) && b.push(c); -}), b.sort(); +function ob(a, b, c) { +var d = typeof a; +return "function" == d ? "undefined" != typeof b && vc(a) ? Zb(a, b, c) :a :null == a ? Bf :"object" == d ? Kb(a) :"undefined" == typeof b ? Ob(a + "") :Lb(a + "", b); } -function Ca(a, b) { -return a ? Rc.call(a, b) :!1; +function pb(a, b, c, d, e, f, g) { +var h; +if (c && (h = e ? c(a, d, e) :c(a)), "undefined" != typeof h) return h; +if (!Ae(a)) return a; +var i = Xg(a); +if (i) { +if (h = sc(a), !b) return Za(a, h); +} else { +var j = bg.call(a), k = j == U; +if (j != X && j != P && (!k || e)) return Ka[j] ? uc(a, j, b) :e ? a :{}; +if (h = tc(k ? {} :a), !b) return mb(a, h, _g(a)); +} +f || (f = []), g || (g = []); +for (var l = f.length; l--; ) if (f[l] == a) return g[l]; +return f.push(a), g.push(h), (i ? $a :Cb)(a, function(d, e) { +h[e] = pb(d, b, c, e, a, f, g); +}), h; } -function Da(a) { -for (var b = -1, c = md(a), d = c.length, e = {}; ++b < d; ) { -var f = c[b]; -e[a[f]] = f; +function qb(a, b, c, d) { +if ("function" != typeof a) throw new Vf(N); +return ng(function() { +a.apply(v, Sb(c, d)); +}, b); +} +function rb(a, c) { +var d = a ? a.length :0, e = []; +if (!d) return e; +var f = -1, g = qc(), h = g == b, i = h && c.length >= 200 && Ng(c), j = c.length; +i && (g = Xa, h = !1, c = i); +a:for (;++f < d; ) { +var k = a[f]; +if (h && k === k) { +for (var l = j; l--; ) if (c[l] === k) continue a; +e.push(k); +} else g(c, k) < 0 && e.push(k); } return e; } -function Ea(a) { -return a === !0 || a === !1 || a && "object" == typeof a && Kc.call(a) == O || !1; +function sb(a, b) { +var c = a ? a.length :0; +if (!yc(c)) return Cb(a, b); +for (var d = -1, e = Hc(a); ++d < c && b(e[d], d, e) !== !1; ) ; +return a; } -function Fa(a) { -return a && "object" == typeof a && Kc.call(a) == P || !1; +function tb(a, b) { +var c = a ? a.length :0; +if (!yc(c)) return Db(a, b); +for (var d = Hc(a); c-- && b(d[c], c, d) !== !1; ) ; +return a; } -function Ga(a) { -return a && 1 === a.nodeType || !1; +function ub(a, b) { +var c = !0; +return sb(a, function(a, d, e) { +return c = !!b(a, d, e); +}), c; } -function Ha(a) { -var b = !0; -if (!a) return b; -var c = Kc.call(a), d = a.length; -return c == N || c == V || (hd.argsClass ? c == M :ta(a)) || c == T && "number" == typeof d && Ka(a.splice) ? !d :(yd(a, function() { -return b = !1; -}), b); +function vb(a, b, c, d) { +var e = a.length; +for (c = null == c ? 0 :+c || 0, 0 > c && (c = -c > e ? 0 :e + c), d = "undefined" == typeof d || d > e ? e :+d || 0, 0 > d && (d += e), e = c > d ? 0 :d >>> 0, c >>>= 0; e > c; ) a[c++] = b; +return a; } -function Ia(a, b, c, d) { -return ha(a, b, "function" == typeof c && ca(c, d, 2)); +function wb(a, b) { +var c = []; +return sb(a, function(a, d, e) { +b(a, d, e) && c.push(a); +}), c; } -function Ja(a) { -return $c(a) && !_c(parseFloat(a)); +function xb(a, b, c, d) { +var e; +return c(a, function(a, c, f) { +return b(a, c, f) ? (e = d ? c :a, !1) :void 0; +}), e; } -function Ka(a) { -return "function" == typeof a; +function yb(a, b, c, d) { +for (var e = (d || 0) - 1, f = a.length, g = -1, h = []; ++e < f; ) { +var i = a[e]; +if (n(i) && yc(i.length) && (Xg(i) || se(i))) { +b && (i = yb(i, b, c)); +var j = -1, k = i.length; +for (h.length += k; ++j < k; ) h[++g] = i[j]; +} else c || (h[++g] = i); } -function La(a) { -return !(!a || !$[typeof a]); +return h; } -function Ma(a) { -return Oa(a) && a != +a; +function zb(a, b, c) { +for (var d = -1, e = Hc(a), f = c(a), g = f.length; ++d < g; ) { +var h = f[d]; +if (b(e[h], h, e) === !1) break; } -function Na(a) { -return null === a; +return a; } -function Oa(a) { -return "number" == typeof a || a && "object" == typeof a && Kc.call(a) == S || !1; +function Ab(a, b, c) { +for (var d = Hc(a), e = c(a), f = e.length; f--; ) { +var g = e[f]; +if (b(d[g], g, d) === !1) break; } -function Pa(a) { -return a && $[typeof a] && Kc.call(a) == U || !1; +return a; } -function Qa(a) { -return "string" == typeof a || a && "object" == typeof a && Kc.call(a) == V || !1; +function Bb(a, b) { +return zb(a, b, Xe); } -function Ra(a) { -return "undefined" == typeof a; +function Cb(a, b) { +return zb(a, b, _g); } -function Sa(a, b, c) { -var d = {}; -return b = q.createCallback(b, c, 3), yd(a, function(a, c, e) { -d[c] = b(a, c, e); -}), d; +function Db(a, b) { +return Ab(a, b, _g); } -function Ta(a) { -var b = arguments, c = 2; -if (!La(a)) return a; -if ("number" != typeof b[2] && (c = b.length), c > 3 && "function" == typeof b[c - 2]) var d = ca(b[--c - 1], b[c--], 2); else c > 2 && "function" == typeof b[c - 1] && (d = b[--c]); -for (var e = n(arguments, 1, c), f = -1, g = h(), i = h(); ++f < c; ) ia(a, e[f], d, g, i); -return l(g), l(i), a; +function Eb(a, b) { +for (var c = -1, d = b.length, e = -1, f = []; ++c < d; ) { +var g = b[c]; +ze(a[g]) && (f[++e] = g); } -function Ua(a, b, c) { -var d = {}; -if ("function" != typeof b) { -var e = []; -xd(a, function(a, b) { -e.push(b); -}), e = ea(e, ga(arguments, !0, !1, 1)); -for (var f = -1, g = e.length; ++f < g; ) { -var h = e[f]; -d[h] = a[h]; +return f; } -} else b = q.createCallback(b, c, 3), xd(a, function(a, c, e) { -b(a, c, e) || (d[c] = a); -}); -return d; +function Fb(a, b, c) { +var d = -1, e = "function" == typeof b, f = a ? a.length :0, g = yc(f) ? Mf(f) :[]; +return sb(a, function(a) { +var f = e ? b :null != a && a[b]; +g[++d] = f ? f.apply(a, c) :v; +}), g; } -function Va(a) { -for (var b = -1, c = md(a), d = c.length, e = uc(d); ++b < d; ) { -var f = c[b]; -e[b] = [ f, a[f] ]; +function Gb(a, b, c, d, e, f) { +if (a === b) return 0 !== a || 1 / a == 1 / b; +var g = typeof a, h = typeof b; +return "function" != g && "object" != g && "function" != h && "object" != h || null == a || null == b ? a !== a && b !== b :Hb(a, b, Gb, c, d, e, f); +} +function Hb(a, b, c, d, e, f, g) { +var h = Xg(a), i = Xg(b), j = Q, k = Q; +h || (j = bg.call(a), j == P ? j = X :j != X && (h = Ie(a))), i || (k = bg.call(b), k == P ? k = X :k != X && (i = Ie(b))); +var l = j == X, m = k == X, n = j == k; +if (n && !h && !l) return mc(a, b, j); +var o = l && _f.call(a, "__wrapped__"), p = m && _f.call(b, "__wrapped__"); +if (o || p) return c(o ? a.value() :a, p ? b.value() :b, d, e, f, g); +if (!n) return !1; +f || (f = []), g || (g = []); +for (var q = f.length; q--; ) if (f[q] == a) return g[q] == b; +f.push(a), g.push(b); +var r = (h ? lc :nc)(a, b, c, d, e, f, g); +return f.pop(), g.pop(), r; +} +function Ib(a, b, c, d, e) { +var f = b.length; +if (null == a) return !f; +for (var g = -1, h = !e; ++g < f; ) if (h && d[g] ? c[g] !== a[b[g]] :!_f.call(a, b[g])) return !1; +for (g = -1; ++g < f; ) { +var i = b[g]; +if (h && d[g]) var j = _f.call(a, i); else { +var k = a[i], l = c[g]; +j = e ? e(k, l, i) :v, "undefined" == typeof j && (j = Gb(l, k, e, !0)); +} +if (!j) return !1; } -return e; +return !0; } -function Wa(a, b, c) { -var d = {}; -if ("function" != typeof b) for (var e = -1, f = ga(arguments, !0, !1, 1), g = La(a) ? f.length :0; ++e < g; ) { -var h = f[e]; -h in a && (d[h] = a[h]); -} else b = q.createCallback(b, c, 3), xd(a, function(a, c, e) { -b(a, c, e) && (d[c] = a); -}); -return d; +function Jb(a, b) { +var c = []; +return sb(a, function(a, d, e) { +c.push(b(a, d, e)); +}), c; } -function Xa(a, b, c, d) { -var e = kd(a); -if (null == c) if (e) c = []; else { -var f = a && a.constructor, g = f && f.prototype; -c = ba(g); +function Kb(a) { +var b = _g(a), c = b.length; +if (1 == c) { +var d = b[0], e = a[d]; +if (zc(e)) return function(a) { +return null != a && a[d] === e && _f.call(a, d); +}; +} +for (var f = Mf(c), g = Mf(c); c--; ) e = a[b[c]], f[c] = e, g[c] = zc(e); +return function(a) { +return Ib(a, b, f, g); +}; +} +function Lb(a, b) { +return zc(b) ? function(c) { +return null != c && c[a] === b; +} :function(c) { +return null != c && Gb(b, c[a], null, !0); +}; +} +function Mb(a, b, c, d, e) { +var f = yc(b.length) && (Xg(b) || Ie(b)); +return (f ? $a :Cb)(b, function(b, g, h) { +if (n(b)) return d || (d = []), e || (e = []), Nb(a, h, g, Mb, c, d, e); +var i = a[g], j = c ? c(i, b, g, a, h) :v, k = "undefined" == typeof j; +k && (j = b), !f && "undefined" == typeof j || !k && (j === j ? j === i :i !== i) || (a[g] = j); +}), a; +} +function Nb(a, b, c, d, e, f, g) { +for (var h = f.length, i = b[c]; h--; ) if (f[h] == i) return void (a[c] = g[h]); +var j = a[c], k = e ? e(j, i, c, a, b) :v, l = "undefined" == typeof k; +l && (k = i, yc(i.length) && (Xg(i) || Ie(i)) ? k = Xg(j) ? j :j ? Za(j) :[] :Zg(i) || se(i) ? k = se(j) ? Le(j) :Zg(j) ? j :{} :l = !1), f.push(i), g.push(k), l ? a[c] = d(k, i, e, f, g) :(k === k ? k !== j :j === j) && (a[c] = k); +} +function Ob(a) { +return function(b) { +return null == b ? v :b[a]; +}; +} +function Pb(b, c) { +var d = c.length, e = lb(b, c); +for (c.sort(a); d--; ) { +var f = parseFloat(c[d]); +if (f != g && wc(f)) { +var g = f; +og.call(b, f, 1); } -return b && (b = q.createCallback(b, d, 4), (e ? ud :yd)(a, function(a, d, e) { -return b(c, a, d, e); -})), c; } -function Ya(a) { -for (var b = -1, c = md(a), d = c.length, e = uc(d); ++b < d; ) e[b] = a[c[b]]; return e; } -function Za(a) { -var b = arguments, c = -1, d = ga(b, !0, !1, 1), e = b[2] && b[2][b[1]] === a ? 1 :d.length, f = uc(e); -for (hd.unindexedChars && Qa(a) && (a = a.split("")); ++c < e; ) f[c] = a[d[c]]; +function Qb(a, b) { +return a + ig(Bg() * (b - a + 1)); +} +function Rb(a, b, c, d, e) { +return e(a, function(a, e, f) { +c = d ? (d = !1, a) :b(c, a, e, f); +}), c; +} +function Sb(a, b, c) { +var d = -1, e = a.length; +b = null == b ? 0 :+b || 0, 0 > b && (b = -b > e ? 0 :e + b), c = "undefined" == typeof c || c > e ? e :+c || 0, 0 > c && (c += e), e = b > c ? 0 :c - b >>> 0, b >>>= 0; +for (var f = Mf(e); ++d < e; ) f[d] = a[d + b]; return f; } -function $a(a, b, c) { -var d = -1, e = pa(), f = a ? a.length :0, g = !1; -return c = (0 > c ? bd(0, f + c) :c) || 0, kd(a) ? g = e(a, b, c) > -1 :"number" == typeof f ? g = (Qa(a) ? a.indexOf(b, c) :e(a, b, c)) > -1 :ud(a, function(a) { -return ++d >= c ? !(g = a === b) :void 0; -}), g; +function Tb(a, b) { +var c; +return sb(a, function(a, d, e) { +return c = b(a, d, e), !c; +}), !!c; +} +function Ub(a, c) { +var d = -1, e = qc(), f = a.length, g = e == b, h = g && f >= 200, i = h && Ng(), j = []; +i ? (e = Xa, g = !1) :(h = !1, i = c ? [] :j); +a:for (;++d < f; ) { +var k = a[d], l = c ? c(k, d, a) :k; +if (g && k === k) { +for (var m = i.length; m--; ) if (i[m] === l) continue a; +c && i.push(l), j.push(k); +} else e(i, l) < 0 && ((c || h) && i.push(l), j.push(k)); } -function _a(a, b, c) { -var d = !0; -if (b = q.createCallback(b, c, 3), kd(a)) for (var e = -1, f = a.length; ++e < f && (d = !!b(a[e], e, a)); ) ; else ud(a, function(a, c, e) { -return d = !!b(a, c, e); -}); -return d; +return j; } -function ab(a, b, c) { -var d = []; -if (b = q.createCallback(b, c, 3), kd(a)) for (var e = -1, f = a.length; ++e < f; ) { -var g = a[e]; -b(g, e, a) && d.push(g); -} else ud(a, function(a, c, e) { -b(a, c, e) && d.push(a); -}); -return d; +function Vb(a, b) { +for (var c = -1, d = b.length, e = Mf(d); ++c < d; ) e[c] = a[b[c]]; +return e; } -function bb(a, b, c) { -if (b = q.createCallback(b, c, 3), !kd(a)) { -var d; -return ud(a, function(a, c, e) { -return b(a, c, e) ? (d = a, !1) :void 0; -}), d; +function Wb(a, b) { +var c = a; +c instanceof _ && (c = c.value()); +for (var d = -1, e = b.length; ++d < e; ) { +var f = [ c ], g = b[d]; +kg.apply(f, g.args), c = g.func.apply(g.thisArg, f); } -for (var e = -1, f = a.length; ++e < f; ) { -var g = a[e]; -if (b(g, e, a)) return g; +return c; } +function Xb(a, b, c) { +var d = 0, e = a ? a.length :d; +if ("number" == typeof b && b === b && Gg >= e) { +for (;e > d; ) { +var f = d + e >>> 1, g = a[f]; +(c ? b >= g :b > g) ? d = f + 1 :e = f; } -function cb(a, b, c) { -var d; -return b = q.createCallback(b, c, 3), eb(a, function(a, c, e) { -return b(a, c, e) ? (d = a, !1) :void 0; -}), d; +return e; } -function db(a, b, c) { -if (b && "undefined" == typeof c && kd(a)) for (var d = -1, e = a.length; ++d < e && b(a[d], d, a) !== !1; ) ; else ud(a, b, c); -return a; +return Yb(a, b, Bf, c); } -function eb(a, b, c) { -var d = a, e = a ? a.length :0; -if (b = b && "undefined" == typeof c ? b :ca(b, c, 3), kd(a)) for (;e-- && b(a[e], e, a) !== !1; ) ; else { -if ("number" != typeof e) { -var f = md(a); -e = f.length; -} else hd.unindexedChars && Qa(a) && (d = a.split("")); -ud(a, function(a, c, g) { -return c = f ? f[--e] :--e, b(d[c], c, g); -}); +function Yb(a, b, c, d) { +b = c(b); +for (var e = 0, f = a ? a.length :0, g = b !== b, h = "undefined" == typeof b; f > e; ) { +var i = ig((e + f) / 2), j = c(a[i]), k = j === j; +if (g) var l = k || d; else l = h ? k && (d || "undefined" != typeof j) :d ? b >= j :b > j; +l ? e = i + 1 :f = i; } -return a; +return xg(f, Fg); } -function fb(a, b) { -var c = n(arguments, 2), d = -1, e = "function" == typeof b, f = a ? a.length :0, g = uc("number" == typeof f ? f :0); -return db(a, function(a) { -g[++d] = (e ? b :a[b]).apply(a, c); -}), g; +function Zb(a, b, c) { +if ("function" != typeof a) return Bf; +if ("undefined" == typeof b) return a; +switch (c) { +case 1: +return function(c) { +return a.call(b, c); +}; + +case 3: +return function(c, d, e) { +return a.call(b, c, d, e); +}; + +case 4: +return function(c, d, e, f) { +return a.call(b, c, d, e, f); +}; + +case 5: +return function(c, d, e, f, g) { +return a.call(b, c, d, e, f, g); +}; +} +return function() { +return a.apply(b, arguments); +}; +} +function $b(a) { +return fg.call(a, 0); +} +function _b(a, b, c) { +for (var d = c.length, e = -1, f = wg(a.length - d, 0), g = -1, h = b.length, i = Mf(f + h); ++g < h; ) i[g] = b[g]; +for (;++e < d; ) i[c[e]] = a[e]; +for (;f--; ) i[g++] = a[e++]; +return i; +} +function ac(a, b, c) { +for (var d = -1, e = c.length, f = -1, g = wg(a.length - e, 0), h = -1, i = b.length, j = Mf(g + i); ++f < g; ) j[f] = a[f]; +for (var k = f; ++h < i; ) j[k + h] = b[h]; +for (;++d < e; ) j[k + c[d]] = a[f++]; +return j; } -function gb(a, b, c) { -var d = -1, e = a ? a.length :0, f = uc("number" == typeof e ? e :0); -if (b = q.createCallback(b, c, 3), kd(a)) for (;++d < e; ) f[d] = b(a[d], d, a); else ud(a, function(a, c, e) { -f[++d] = b(a, c, e); +function bc(a, b) { +return function(c, d, e) { +var f = b ? b() :{}; +if (d = pc(d, e, 3), Xg(c)) for (var g = -1, h = c.length; ++g < h; ) { +var i = c[g]; +a(f, i, d(i, g, c), c); +} else sb(c, function(b, c, e) { +a(f, b, d(b, c, e), e); }); return f; +}; } -function hb(a, b, c) { -var e = -(1 / 0), f = e; -if ("function" != typeof b && c && c[b] === a && (b = null), null == b && kd(a)) for (var g = -1, h = a.length; ++g < h; ) { -var i = a[g]; -i > f && (f = i); -} else b = null == b && Qa(a) ? d :q.createCallback(b, c, 3), ud(a, function(a, c, d) { -var g = b(a, c, d); -g > e && (e = g, f = a); -}); +function cc(a) { +return function() { +var b = arguments.length, c = arguments[0]; +if (2 > b || null == c) return c; +if (b > 3 && xc(arguments[1], arguments[2], arguments[3]) && (b = 2), b > 3 && "function" == typeof arguments[b - 2]) var d = Zb(arguments[--b - 1], arguments[b--], 5); else b > 2 && "function" == typeof arguments[b - 1] && (d = arguments[--b]); +for (var e = 0; ++e < b; ) { +var f = arguments[e]; +f && a(c, f, d); +} +return c; +}; +} +function dc(a, b) { +function c() { +return (this instanceof c ? d :a).apply(b, arguments); +} +var d = fc(a); +return c; +} +function ec(a) { +return function(b) { +for (var c = -1, d = xf(gf(b)), e = d.length, f = ""; ++c < e; ) f = a(f, d[c], c); return f; +}; +} +function fc(a) { +return function() { +var b = Lg(a.prototype), c = a.apply(b, arguments); +return Ae(c) ? c :b; +}; +} +function gc(a, b) { +return function(c, d, f) { +f && xc(c, d, f) && (d = null); +var g = pc(), h = null == d; +if (g === ob && h || (h = !1, d = g(d, f, 3)), h) { +var i = Xg(c); +if (i || !He(c)) return a(i ? c :Gc(c)); +d = e; +} +return oc(c, d, b); +}; +} +function hc(a, b, c, d, e, f, g, h, i, j) { +function k() { +for (var u = arguments.length, v = u, w = Mf(u); v--; ) w[v] = arguments[v]; +if (d && (w = _b(w, d, e)), f && (w = ac(w, f, g)), o || r) { +var z = k.placeholder, A = p(w, z); +if (u -= A.length, j > u) { +var B = h ? Za(h) :null, E = wg(j - u, 0), F = o ? A :null, G = o ? null :A, H = o ? w :null, I = o ? null :w; +b |= o ? C :D, b &= ~(o ? D :C), q || (b &= ~(x | y)); +var J = hc(a, b, c, H, F, I, G, B, i, E); +return J.placeholder = z, J; +} +} +var K = m ? c :this; +return n && (a = K[t]), h && (w = Dc(w, h)), l && i < w.length && (w.length = i), (this instanceof k ? s || fc(a) :a).apply(K, w); +} +var l = b & F, m = b & x, n = b & y, o = b & A, q = b & z, r = b & B, s = !n && fc(a), t = a; +return k; +} +function ic(a, b, c) { +var d = a.length; +if (b = +b, d >= b || !ug(b)) return ""; +var e = b - d; +return c = null == c ? " " :c + "", pf(c, gg(e / c.length)).slice(0, e); +} +function jc(a, b, c, d) { +function e() { +for (var b = -1, h = arguments.length, i = -1, j = d.length, k = Mf(h + j); ++i < j; ) k[i] = d[i]; +for (;h--; ) k[i++] = arguments[++b]; +return (this instanceof e ? g :a).apply(f ? c :this, k); +} +var f = b & x, g = fc(a); +return e; +} +function kc(a, b, c, d, e, f, g, h) { +var i = b & y; +if (!i && "function" != typeof a) throw new Vf(N); +var j = d ? d.length :0; +if (j || (b &= ~(C | D), d = e = null), j -= e ? e.length :0, b & D) { +var k = d, l = e; +d = e = null; +} +var m = !i && Og(a), n = [ a, b, c, d, e, k, l, f, g, h ]; +if (m && m !== !0 && (Ac(n, m), b = n[1], h = n[9]), n[9] = null == h ? i ? 0 :a.length :wg(h - j, 0) || 0, b == x) var o = dc(n[0], n[2]); else o = b != C && b != (x | C) || n[4].length ? hc.apply(v, n) :jc.apply(v, n); +var p = m ? Mg :Pg; +return p(o, n); +} +function lc(a, b, c, d, e, f, g) { +var h = -1, i = a.length, j = b.length, k = !0; +if (i != j && !(e && j > i)) return !1; +for (;k && ++h < i; ) { +var l = a[h], m = b[h]; +if (k = v, d && (k = e ? d(m, l, h) :d(l, m, h)), "undefined" == typeof k) if (e) for (var n = j; n-- && (m = b[n], !(k = l && l === m || c(l, m, d, e, f, g))); ) ; else k = l && l === m || c(l, m, d, e, f, g); +} +return !!k; +} +function mc(a, b, c) { +switch (c) { +case R: +case S: +return +a == +b; + +case T: +return a.name == b.name && a.message == b.message; + +case W: +return a != +a ? b != +b :0 == a ? 1 / a == 1 / b :a == +b; + +case Y: +case $: +return a == b + ""; +} +return !1; +} +function nc(a, b, c, d, e, f, g) { +var h = _g(a), i = h.length, j = _g(b), k = j.length; +if (i != k && !e) return !1; +for (var l, m = -1; ++m < i; ) { +var n = h[m], o = _f.call(b, n); +if (o) { +var p = a[n], q = b[n]; +o = v, d && (o = e ? d(q, p, n) :d(p, q, n)), "undefined" == typeof o && (o = p && p === q || c(p, q, d, e, f, g)); +} +if (!o) return !1; +l || (l = "constructor" == n); +} +if (!l) { +var r = a.constructor, s = b.constructor; +if (r != s && "constructor" in a && "constructor" in b && !("function" == typeof r && r instanceof r && "function" == typeof s && s instanceof s)) return !1; +} +return !0; +} +function oc(a, b, c) { +var d = c ? Dg :Cg, e = d, f = e; +return sb(a, function(a, g, h) { +var i = b(a, g, h); +((c ? e > i :i > e) || i === d && i === f) && (e = i, f = a); +}), f; +} +function pc(a, b, c) { +var d = V.callback || zf; +return d = d === zf ? ob :d, c ? d(a, b, c) :d; +} +function qc(a, c, d) { +var e = V.indexOf || Wc; +return e = e === Wc ? b :e, a ? e(a, c, d) :e; +} +function rc(a, b, c) { +for (var d = -1, e = c ? c.length :0; ++d < e; ) { +var f = c[d], g = f.size; +switch (f.type) { +case "drop": +a += g; +break; + +case "dropRight": +b -= g; +break; + +case "take": +b = xg(b, a + g); +break; + +case "takeRight": +a = wg(a, b - g); +} +} +return { +start:a, +end:b +}; +} +function sc(a) { +var b = a.length, c = new a.constructor(b); +return b && "string" == typeof a[0] && _f.call(a, "index") && (c.index = a.index, c.input = a.input), c; +} +function tc(a) { +var b = a.constructor; +return "function" == typeof b && b instanceof b || (b = Sf), new b(); +} +function uc(a, b, c) { +var d = a.constructor; +switch (b) { +case aa: +return $b(a); + +case R: +case S: +return new d(+a); + +case ba: +case ca: +case da: +case ea: +case fa: +case ga: +case ha: +case ia: +case ja: +var e = a.buffer; +return new d(c ? $b(e) :e, a.byteOffset, a.length); + +case W: +case $: +return new d(a); + +case Y: +var f = new d(a.source, va.exec(a)); +f.lastIndex = a.lastIndex; } -function ib(a, b, c) { -var e = 1 / 0, f = e; -if ("function" != typeof b && c && c[b] === a && (b = null), null == b && kd(a)) for (var g = -1, h = a.length; ++g < h; ) { -var i = a[g]; -f > i && (f = i); -} else b = null == b && Qa(a) ? d :q.createCallback(b, c, 3), ud(a, function(a, c, d) { -var g = b(a, c, d); -e > g && (e = g, f = a); -}); return f; } -function jb(a, b, c, d) { -var e = arguments.length < 3; -if (b = q.createCallback(b, d, 4), kd(a)) { -var f = -1, g = a.length; -for (e && (c = a[++f]); ++f < g; ) c = b(c, a[f], f, a); -} else ud(a, function(a, d, f) { -c = e ? (e = !1, a) :b(c, a, d, f); -}); +function vc(a) { +var b = V.support, c = !(b.funcNames ? a.name :b.funcDecomp); +if (!c) { +var d = Zf.call(a); +b.funcNames || (c = !wa.test(d)), c || (c = Da.test(d) || De(a), Mg(a, c)); +} return c; } -function kb(a, b, c, d) { -var e = arguments.length < 3; -return b = q.createCallback(b, d, 4), eb(a, function(a, d, f) { -c = e ? (e = !1, a) :b(c, a, d, f); +function wc(a, b) { +return a = +a, b = null == b ? Ig :b, a > -1 && a % 1 == 0 && b > a; +} +function xc(a, b, c) { +if (!Ae(c)) return !1; +var d = typeof b; +if ("number" == d) var e = c.length, f = yc(e) && wc(b, e); else f = "string" == d && b in c; +return f && c[b] === a; +} +function yc(a) { +return "number" == typeof a && a > -1 && a % 1 == 0 && Ig >= a; +} +function zc(a) { +return a === a && (0 === a ? 1 / a > 0 :!Ae(a)); +} +function Ac(a, b) { +var c = a[1], d = b[1], e = c | d, f = F | E, g = x | y, h = f | g | z | B, i = c & F && !(d & F), j = c & E && !(d & E), k = (j ? a :b)[7], l = (i ? a :b)[8], m = !(c >= E && d > g || c > g && d >= E), n = e >= f && h >= e && (E > c || (j || i) && k.length <= l); +if (!m && !n) return a; +d & x && (a[2] = b[2], e |= c & x ? 0 :z); +var o = b[3]; +if (o) { +var q = a[3]; +a[3] = q ? _b(q, o, b[4]) :Za(o), a[4] = q ? p(a[3], O) :Za(b[4]); +} +return o = b[5], o && (q = a[5], a[5] = q ? ac(q, o, b[6]) :Za(o), a[6] = q ? p(a[5], O) :Za(b[6])), o = b[7], o && (a[7] = Za(o)), d & F && (a[8] = null == a[8] ? b[8] :xg(a[8], b[8])), null == a[9] && (a[9] = b[9]), a[0] = b[0], a[1] = e, a; +} +function Bc(a, b) { +a = Hc(a); +for (var c = -1, d = b.length, e = {}; ++c < d; ) { +var f = b[c]; +f in a && (e[f] = a[f]); +} +return e; +} +function Cc(a, b) { +var c = {}; +return Bb(a, function(a, d, e) { +b(a, d, e) && (c[d] = a); }), c; } -function lb(a, b, c) { -return b = q.createCallback(b, c, 3), ab(a, function(a, c, d) { -return !b(a, c, d); -}); +function Dc(a, b) { +for (var c = a.length, d = xg(b.length, c), e = Za(a); d--; ) { +var f = b[d]; +a[d] = wc(f, c) ? e[f] :v; } -function mb(a, b, c) { -if (a && "number" != typeof a.length ? a = Ya(a) :hd.unindexedChars && Qa(a) && (a = a.split("")), null == b || c) return a ? a[ja(0, a.length - 1)] :p; -var d = nb(a); -return d.length = cd(bd(0, b), d.length), d; -} -function nb(a) { -var b = -1, c = a ? a.length :0, d = uc("number" == typeof c ? c :0); -return db(a, function(a) { -var c = ja(0, ++b); -d[b] = d[c], d[c] = a; -}), d; +return a; } -function ob(a) { -var b = a ? a.length :0; -return "number" == typeof b ? b :md(a).length; +function Ec(a) { +{ +var b; +V.support; } -function pb(a, b, c) { -var d; -if (b = q.createCallback(b, c, 3), kd(a)) for (var e = -1, f = a.length; ++e < f && !(d = b(a[e], e, a)); ) ; else ud(a, function(a, c, e) { -return !(d = b(a, c, e)); -}); -return !!d; +if (!n(a) || bg.call(a) != X || !_f.call(a, "constructor") && (b = a.constructor, "function" == typeof b && !(b instanceof b))) return !1; +var c; +return Bb(a, function(a, b) { +c = b; +}), "undefined" == typeof c || _f.call(a, c); } -function qb(a, b, c) { -var d = -1, f = kd(b), g = a ? a.length :0, j = uc("number" == typeof g ? g :0); -for (f || (b = q.createCallback(b, c, 3)), db(a, function(a, c, e) { -var g = j[++d] = i(); -f ? g.criteria = gb(b, function(b) { -return a[b]; -}) :(g.criteria = h())[0] = b(a, c, e), g.index = d, g.value = a; -}), g = j.length, j.sort(e); g--; ) { -var k = j[g]; -j[g] = k.value, f || l(k.criteria), m(k); +function Fc(a) { +for (var b = Xe(a), c = b.length, d = c && a.length, e = V.support, f = d && yc(d) && (Xg(a) || e.nonEnumArgs && se(a)), g = -1, h = []; ++g < c; ) { +var i = b[g]; +(f && wc(i, d) || _f.call(a, i)) && h.push(i); } -return j; +return h; } -function rb(a) { -return a && "number" == typeof a.length ? hd.unindexedChars && Qa(a) ? a.split("") :n(a) :Ya(a); +function Gc(a) { +return null == a ? [] :yc(a.length) ? Ae(a) ? a :Sf(a) :cf(a); } -function sb(a) { -for (var b = -1, c = a ? a.length :0, d = []; ++b < c; ) { -var e = a[b]; -e && d.push(e); +function Hc(a) { +return Ae(a) ? a :Sf(a); } -return d; +function Ic(a) { +return a instanceof _ ? a.clone() :new Z(a.__wrapped__, a.__chain__, Za(a.__actions__)); } -function tb(a) { -return ea(a, ga(arguments, !0, !0, 1)); +function Jc(a, b, c) { +b = (c ? xc(a, b, c) :null == b) ? 1 :wg(+b || 1, 1); +for (var d = 0, e = a ? a.length :0, f = -1, g = Mf(gg(e / b)); e > d; ) g[++f] = Sb(a, d, d += b); +return g; +} +function Kc(a) { +for (var b = -1, c = a ? a.length :0, d = -1, e = []; ++b < c; ) { +var f = a[b]; +f && (e[++d] = f); } -function ub(a, b, c) { +return e; +} +function Lc() { +for (var a = -1, b = arguments.length; ++a < b; ) { +var c = arguments[a]; +if (Xg(c) || se(c)) break; +} +return rb(c, yb(arguments, !1, !0, ++a)); +} +function Mc(a, b, c) { +var d = a ? a.length :0; +return d ? ((c ? xc(a, b, c) :null == b) && (b = 1), Sb(a, 0 > b ? 0 :b)) :[]; +} +function Nc(a, b, c) { +var d = a ? a.length :0; +return d ? ((c ? xc(a, b, c) :null == b) && (b = 1), b = d - (+b || 0), Sb(a, 0, 0 > b ? 0 :b)) :[]; +} +function Oc(a, b, c) { +var d = a ? a.length :0; +if (!d) return []; +for (b = pc(b, c, 3); d-- && b(a[d], d, a); ) ; +return Sb(a, 0, d + 1); +} +function Pc(a, b, c) { +var d = a ? a.length :0; +if (!d) return []; +var e = -1; +for (b = pc(b, c, 3); ++e < d && b(a[e], e, a); ) ; +return Sb(a, e); +} +function Qc(a, b, c, d) { +var e = a ? a.length :0; +return e ? (c && "number" != typeof c && xc(a, b, c) && (c = 0, d = e), vb(a, b, c, d)) :[]; +} +function Rc(a, b, c) { var d = -1, e = a ? a.length :0; -for (b = q.createCallback(b, c, 3); ++d < e; ) if (b(a[d], d, a)) return d; +for (b = pc(b, c, 3); ++d < e; ) if (b(a[d], d, a)) return d; return -1; } -function vb(a, b, c) { +function Sc(a, b, c) { var d = a ? a.length :0; -for (b = q.createCallback(b, c, 3); d--; ) if (b(a[d], d, a)) return d; +for (b = pc(b, c, 3); d--; ) if (b(a[d], d, a)) return d; return -1; } -function wb(a, b, c) { -var d = 0, e = a ? a.length :0; -if ("number" != typeof b && null != b) { -var f = -1; -for (b = q.createCallback(b, c, 3); ++f < e && b(a[f], f, a); ) d++; -} else if (d = b, null == d || c) return a ? a[0] :p; -return n(a, 0, cd(bd(0, d), e)); +function Tc(a) { +return a ? a[0] :v; } -function xb(a, b, c, d) { -return "boolean" != typeof b && null != b && (d = c, c = "function" != typeof b && d && d[b] === a ? null :b, b = !1), null != c && (a = gb(a, c, d)), ga(a, b); +function Uc(a, b, c) { +var d = a ? a.length :0; +return c && xc(a, b, c) && (b = !1), d ? yb(a, b) :[]; } -function yb(b, c, d) { -if ("number" == typeof d) { -var e = b ? b.length :0; -d = 0 > d ? bd(0, e + d) :d || 0; -} else if (d) { -var f = Hb(b, c); -return b[f] === c ? f :-1; +function Vc(a) { +var b = a ? a.length :0; +return b ? yb(a, !0) :[]; } -return a(b, c, d); +function Wc(a, c, d) { +var e = a ? a.length :0; +if (!e) return -1; +if ("number" == typeof d) d = 0 > d ? wg(e + d, 0) :d || 0; else if (d) { +var f = Xb(a, c), g = a[f]; +return (c === c ? c === g :g !== g) ? f :-1; } -function zb(a, b, c) { -var d = 0, e = a ? a.length :0; -if ("number" != typeof b && null != b) { -var f = e; -for (b = q.createCallback(b, c, 3); f-- && b(a[f], f, a); ) d++; -} else d = null == b || c ? 1 :b || d; -return n(a, 0, cd(bd(0, e - d), e)); +return b(a, c, d); } -function Ab() { -for (var c = [], d = -1, e = arguments.length, g = h(), i = pa(), j = i === a, k = h(); ++d < e; ) { -var n = arguments[d]; -(kd(n) || ta(n)) && (c.push(n), g.push(j && n.length >= v && f(d ? c[d] :k))); +function Xc(a) { +return Nc(a, 1); } -var o = c[0], p = -1, q = o ? o.length :0, r = []; -a:for (;++p < q; ) { -var s = g[0]; -if (n = o[p], (s ? b(s, n) :i(k, n)) < 0) { -for (d = e, (s || k).push(n); --d; ) if (s = g[d], (s ? b(s, n) :i(c[d], n)) < 0) continue a; -r.push(n); +function Yc() { +for (var a = [], c = -1, d = arguments.length, e = [], f = qc(), g = f == b; ++c < d; ) { +var h = arguments[c]; +(Xg(h) || se(h)) && (a.push(h), e.push(g && h.length >= 120 && Ng(c && h))); } +d = a.length; +var i = a[0], j = -1, k = i ? i.length :0, l = [], m = e[0]; +a:for (;++j < k; ) if (h = i[j], (m ? Xa(m, h) :f(l, h)) < 0) { +for (c = d; --c; ) { +var n = e[c]; +if ((n ? Xa(n, h) :f(a[c], h)) < 0) continue a; } -for (;e--; ) s = g[e], s && m(s); -return l(g), l(k), r; +m && m.push(h), l.push(h); } -function Bb(a, b, c) { -var d = 0, e = a ? a.length :0; -if ("number" != typeof b && null != b) { -var f = e; -for (b = q.createCallback(b, c, 3); f-- && b(a[f], f, a); ) d++; -} else if (d = b, null == d || c) return a ? a[e - 1] :p; -return n(a, bd(0, e - d)); +return l; } -function Cb(a, b, c) { +function Zc(a) { +var b = a ? a.length :0; +return b ? a[b - 1] :v; +} +function $c(a, b, c) { var d = a ? a.length :0; -for ("number" == typeof c && (d = (0 > c ? bd(0, d + c) :cd(c, d - 1)) + 1); d--; ) if (a[d] === b) return d; +if (!d) return -1; +var e = d; +if ("number" == typeof c) e = (0 > c ? wg(d + c, 0) :xg(c || 0, d - 1)) + 1; else if (c) { +e = Xb(a, b, !0) - 1; +var f = a[e]; +return (b === b ? b === f :f !== f) ? e :-1; +} +if (b !== b) return m(a, e, !0); +for (;e--; ) if (a[e] === b) return e; return -1; } -function Db(a) { -for (var b = arguments, c = 0, d = b.length, e = a ? a.length :0; ++c < d; ) for (var f = -1, g = b[c]; ++f < e; ) a[f] === g && (Vc.call(a, f--, 1), e--); +function _c() { +var a = arguments[0]; +if (!a || !a.length) return a; +for (var b = 0, c = qc(), d = arguments.length; ++b < d; ) for (var e = 0, f = arguments[b]; (e = c(a, f, e)) > -1; ) og.call(a, e, 1); return a; } -function Eb(a, b, c) { -a = +a || 0, c = "number" == typeof c ? c :+c || 1, null == b && (b = a, a = 0); -for (var d = -1, e = bd(0, Mc((b - a) / (c || 1))), f = uc(e); ++d < e; ) f[d] = a, a += c; -return f; +function ad(a) { +return Pb(a || [], yb(arguments, !1, !1, 1)); } -function Fb(a, b, c) { +function bd(a, b, c) { var d = -1, e = a ? a.length :0, f = []; -for (b = q.createCallback(b, c, 3); ++d < e; ) { +for (b = pc(b, c, 3); ++d < e; ) { var g = a[d]; -b(g, d, a) && (f.push(g), Vc.call(a, d--, 1), e--); +b(g, d, a) && (f.push(g), og.call(a, d--, 1), e--); } return f; } -function Gb(a, b, c) { -if ("number" != typeof b && null != b) { -var d = 0, e = -1, f = a ? a.length :0; -for (b = q.createCallback(b, c, 3); ++e < f && b(a[e], e, a); ) d++; -} else d = null == b || c ? 1 :bd(0, b); -return n(a, d); +function cd(a) { +return Mc(a, 1); } -function Hb(a, b, c, d) { -var e = 0, f = a ? a.length :e; -for (c = c ? q.createCallback(c, d, 1) :ec, b = c(b); f > e; ) { -var g = e + f >>> 1; -c(a[g]) < b ? e = g + 1 :f = g; +function dd(a, b, c) { +var d = a ? a.length :0; +return d ? (c && "number" != typeof c && xc(a, b, c) && (b = 0, c = d), Sb(a, b, c)) :[]; } -return e; +function ed(a, b, c, d) { +var e = pc(c); +return e === ob && null == c ? Xb(a, b) :Yb(a, b, e(c, d, 1)); } -function Ib() { -return ka(ga(arguments, !0, !0)); +function fd(a, b, c, d) { +var e = pc(c); +return e === ob && null == c ? Xb(a, b, !0) :Yb(a, b, e(c, d, 1), !0); } -function Jb(a, b, c, d) { -return "boolean" != typeof b && null != b && (d = c, c = "function" != typeof b && d && d[b] === a ? null :b, b = !1), null != c && (c = q.createCallback(c, d, 3)), ka(a, b, c); +function gd(a, b, c) { +var d = a ? a.length :0; +return d ? ((c ? xc(a, b, c) :null == b) && (b = 1), Sb(a, 0, 0 > b ? 0 :b)) :[]; } -function Kb(a) { -return ea(a, n(arguments, 1)); +function hd(a, b, c) { +var d = a ? a.length :0; +return d ? ((c ? xc(a, b, c) :null == b) && (b = 1), b = d - (+b || 0), Sb(a, 0 > b ? 0 :b)) :[]; +} +function id(a, b, c) { +var d = a ? a.length :0; +if (!d) return []; +for (b = pc(b, c, 3); d-- && b(a[d], d, a); ) ; +return Sb(a, d + 1); +} +function jd(a, b, c) { +var d = a ? a.length :0; +if (!d) return []; +var e = -1; +for (b = pc(b, c, 3); ++e < d && b(a[e], e, a); ) ; +return Sb(a, 0, e); +} +function kd() { +return Ub(yb(arguments, !1, !0)); +} +function ld(a, c, d, e) { +var f = a ? a.length :0; +if (!f) return []; +"boolean" != typeof c && null != c && (e = d, d = xc(a, c, e) ? null :c, c = !1); +var g = pc(); +return (g !== ob || null != d) && (d = g(d, e, 3)), c && qc() == b ? q(a, d) :Ub(a, d); +} +function md(a) { +for (var b = -1, c = (a && a.length && db(cb(a, $f))) >>> 0, d = Mf(c); ++b < c; ) d[b] = cb(a, Ob(b)); +return d; +} +function nd(a) { +return rb(a, Sb(arguments, 1)); } -function Lb() { +function od() { for (var a = -1, b = arguments.length; ++a < b; ) { var c = arguments[a]; -if (kd(c) || ta(c)) var d = d ? ka(ea(d, c).concat(ea(c, d))) :c; +if (Xg(c) || se(c)) var d = d ? rb(d, c).concat(rb(c, d)) :c; } -return d || []; +return d ? Ub(d) :[]; } -function Mb() { -for (var a = arguments.length > 1 ? arguments :arguments[0], b = -1, c = a ? hb(Dd(a, "length")) :0, d = uc(0 > c ? 0 :c); ++b < c; ) d[b] = Dd(a, b); -return d; +function pd() { +for (var a = arguments.length, b = Mf(a); a--; ) b[a] = arguments[a]; +return md(b); } -function Nb(a, b) { +function qd(a, b) { var c = -1, d = a ? a.length :0, e = {}; -for (b || !d || kd(a[0]) || (b = []); ++c < d; ) { +for (!d || b || Xg(a[0]) || (b = []); ++c < d; ) { var f = a[c]; b ? e[f] = b[c] :f && (e[f[0]] = f[1]); } return e; } -function Ob(a, b) { -if (!Ka(b)) throw new Ec(); -return function() { -return --a < 1 ? b.apply(this, arguments) :void 0; -}; +function rd(a) { +var b = V(a); +return b.__chain__ = !0, b; } -function Pb(a, b) { -return arguments.length > 2 ? ma(a, 17, n(arguments, 2), null, b) :ma(a, 1, null, null, b); +function sd(a, b, c) { +return b.call(c, a), a; } -function Qb(a) { -for (var b = arguments.length > 1 ? ga(arguments, !0, !1, 1) :Ba(a), c = -1, d = b.length; ++c < d; ) { -var e = b[c]; -a[e] = ma(a[e], 1, null, null, a); +function td(a, b, c) { +return b.call(c, a); } -return a; +function ud() { +return rd(this); } -function Rb(a, b) { -return arguments.length > 2 ? ma(b, 19, n(arguments, 2), null, a) :ma(b, 3, null, null, a); +function vd() { +return new Z(this.value(), this.__chain__); } -function Sb() { -for (var a = arguments, b = a.length; b--; ) if (!Ka(a[b])) throw new Ec(); -return function() { -for (var b = arguments, c = a.length; c--; ) b = [ a[c].apply(this, b) ]; -return b[0]; -}; +function wd(a) { +for (var b, c = this; c instanceof Z; ) { +var d = Ic(c); +b ? e.__wrapped__ = d :b = d; +var e = d; +c = c.__wrapped__; } -function Tb(a, b) { -return b = "number" == typeof b ? b :+b || a.length, ma(a, 4, null, null, null, b); +return e.__wrapped__ = a, b; } -function Ub(a, b, c) { -var d, e, f, g, h, i, j, k = 0, l = !1, m = !0; -if (!Ka(a)) throw new Ec(); -if (b = bd(0, b) || 0, c === !0) { -var n = !0; -m = !1; -} else La(c) && (n = c.leading, l = "maxWait" in c && (bd(b, c.maxWait) || 0), m = "trailing" in c ? c.trailing :m); -var o = function() { -var c = b - (Fd() - g); -if (0 >= c) { -e && Nc(e); -var l = j; -e = i = j = p, l && (k = Fd(), f = a.apply(h, d), i || e || (d = h = null)); -} else i = Uc(o, c); -}, q = function() { -i && Nc(i), e = i = j = p, (m || l !== b) && (k = Fd(), f = a.apply(h, d), i || e || (d = h = null)); -}; -return function() { -if (d = arguments, g = Fd(), h = this, j = m && (i || !n), l === !1) var c = n && !i; else { -e || n || (k = g); -var p = l - (g - k), r = 0 >= p; -r ? (e && (e = Nc(e)), k = g, f = a.apply(h, d)) :e || (e = Uc(q, p)); +function xd() { +var a = this.__wrapped__; +return a instanceof _ ? (this.__actions__.length && (a = new _(this)), new Z(a.reverse(), this.__chain__)) :this.thru(function(a) { +return a.reverse(); +}); +} +function yd() { +return this.value() + ""; +} +function zd() { +return Wb(this.__wrapped__, this.__actions__); +} +function Ad(a) { +var b = a ? a.length :0; +return yc(b) && (a = Gc(a)), lb(a, yb(arguments, !1, !1, 1)); +} +function Bd(a, b, c) { +var d = a ? a.length :0; +return yc(d) || (a = cf(a), d = a.length), d ? (c = "number" == typeof c ? 0 > c ? wg(d + c, 0) :c || 0 :0, "string" == typeof a || !Xg(a) && He(a) ? d > c && a.indexOf(b, c) > -1 :qc(a, b, c) > -1) :!1; +} +function Cd(a, b, c) { +var d = Xg(a) ? ab :ub; +return ("function" != typeof b || "undefined" != typeof c) && (b = pc(b, c, 3)), d(a, b); } -return r && i ? i = Nc(i) :i || b === l || (i = Uc(o, b)), c && (r = !0, f = a.apply(h, d)), !r || i || e || (d = h = null), f; +function Dd(a, b, c) { +var d = Xg(a) ? bb :wb; +return b = pc(b, c, 3), d(a, b); +} +function Ed(a, b, c) { +if (Xg(a)) { +var d = Rc(a, b, c); +return d > -1 ? a[d] :v; +} +return b = pc(b, c, 3), xb(a, b, sb); +} +function Fd(a, b, c) { +return b = pc(b, c, 3), xb(a, b, tb); +} +function Gd(a, b) { +return Ed(a, Kb(b)); +} +function Hd(a, b, c) { +return "function" == typeof b && "undefined" == typeof c && Xg(a) ? $a(a, b) :sb(a, Zb(b, c, 3)); +} +function Id(a, b, c) { +return "function" == typeof b && "undefined" == typeof c && Xg(a) ? _a(a, b) :tb(a, Zb(b, c, 3)); +} +function Jd(a, b) { +return Fb(a, b, Sb(arguments, 2)); +} +function Kd(a, b, c) { +var d = Xg(a) ? cb :Jb; +return b = pc(b, c, 3), d(a, b); +} +function Ld(a, b) { +return Kd(a, Ob(b)); +} +function Md(a, b, c, d) { +var e = Xg(a) ? fb :Rb; +return e(a, pc(b, d, 4), c, arguments.length < 3, sb); +} +function Nd(a, b, c, d) { +var e = Xg(a) ? gb :Rb; +return e(a, pc(b, d, 4), c, arguments.length < 3, tb); +} +function Od(a, b, c) { +var d = Xg(a) ? bb :wb; +return b = pc(b, c, 3), d(a, function(a, c, d) { +return !b(a, c, d); +}); +} +function Pd(a, b, c) { +if (c ? xc(a, b, c) :null == b) { +a = Gc(a); +var d = a.length; +return d > 0 ? a[Qb(0, d - 1)] :v; +} +var e = Qd(a); +return e.length = xg(0 > b ? 0 :+b || 0, e.length), e; +} +function Qd(a) { +a = Gc(a); +for (var b = -1, c = a.length, d = Mf(c); ++b < c; ) { +var e = Qb(0, b); +b != e && (d[b] = d[e]), d[e] = a[b]; +} +return d; +} +function Rd(a) { +var b = a ? a.length :0; +return yc(b) ? b :_g(a).length; +} +function Sd(a, b, c) { +var d = Xg(a) ? hb :Tb; +return ("function" != typeof b || "undefined" != typeof c) && (b = pc(b, c, 3)), d(a, b); +} +function Td(a, b, d) { +var e = -1, f = a ? a.length :0, g = yc(f) ? Mf(f) :[]; +return d && xc(a, b, d) && (b = null), b = pc(b, d, 3), sb(a, function(a, c, d) { +g[++e] = { +criteria:b(a, c, d), +index:e, +value:a +}; +}), c(g, h); +} +function Ud(a) { +var b = arguments; +b.length > 3 && xc(b[1], b[2], b[3]) && (b = [ a, b[1] ]); +var d = -1, e = a ? a.length :0, f = yb(b, !1, !1, 1), g = yc(e) ? Mf(e) :[]; +return sb(a, function(a) { +for (var b = f.length, c = Mf(b); b--; ) c[b] = null == a ? v :a[f[b]]; +g[++d] = { +criteria:c, +index:d, +value:a }; +}), c(g, i); } -function Vb(a) { -if (!Ka(a)) throw new Ec(); -var b = n(arguments, 1); -return Uc(function() { -a.apply(p, b); -}, 1); +function Vd(a, b) { +return Dd(a, Kb(b)); } -function Wb(a, b) { -if (!Ka(a)) throw new Ec(); -var c = n(arguments, 2); -return Uc(function() { -a.apply(p, c); -}, b); +function Wd(a, b) { +if ("function" != typeof b) { +if ("function" != typeof a) throw new Vf(N); +var c = a; +a = b, b = c; } -function Xb(a, b) { -if (!Ka(a)) throw new Ec(); -var c = function() { -var d = c.cache, e = b ? b.apply(this, arguments) :u + arguments[0]; -return Rc.call(d, e) ? d[e] :d[e] = a.apply(this, arguments); +return a = ug(a = +a) ? a :0, function() { +return --a < 1 ? b.apply(this, arguments) :void 0; }; -return c.cache = {}, c; } -function Yb(a) { -var b, c; -if (!Ka(a)) throw new Ec(); +function Xd(a, b, c) { +return c && xc(a, b, c) && (b = null), b = a && null == b ? a.length :wg(+b || 0, 0), kc(a, F, null, null, null, null, b); +} +function Yd(a, b) { +var c; +if ("function" != typeof b) { +if ("function" != typeof a) throw new Vf(N); +var d = a; +a = b, b = d; +} return function() { -return b ? c :(b = !0, c = a.apply(this, arguments), a = null, c); +return --a > 0 ? c = b.apply(this, arguments) :b = null, c; }; } -function Zb(a) { -return ma(a, 16, n(arguments, 1)); +function Zd(a, b) { +var c = x; +if (arguments.length > 2) { +var d = Sb(arguments, 2), e = p(d, Zd.placeholder); +c |= C; } -function $b(a) { -return ma(a, 32, null, n(arguments, 1)); +return kc(a, c, b, d, e); } -function _b(a, b, c) { -var d = !0, e = !0; -if (!Ka(a)) throw new Ec(); -return c === !1 ? d = !1 :La(c) && (d = "leading" in c ? c.leading :d, e = "trailing" in c ? c.trailing :e), X.leading = d, X.maxWait = b, X.trailing = e, Ub(a, b, X); +function $d(a) { +return nb(a, arguments.length > 1 ? yb(arguments, !1, !1, 1) :Ue(a)); +} +function _d(a, b) { +var c = x | y; +if (arguments.length > 2) { +var d = Sb(arguments, 2), e = p(d, _d.placeholder); +c |= C; +} +return kc(b, c, a, d, e); +} +function ae(a, b, c) { +c && xc(a, b, c) && (b = null); +var d = kc(a, A, null, null, null, null, null, b); +return d.placeholder = ae.placeholder, d; +} +function be(a, b, c) { +c && xc(a, b, c) && (b = null); +var d = kc(a, B, null, null, null, null, null, b); +return d.placeholder = be.placeholder, d; +} +function ce(a, b, c) { +function d() { +m && hg(m), i && hg(i), i = m = n = v; +} +function e() { +var c = b - (Wg() - k); +if (0 >= c || c > b) { +i && hg(i); +var d = n; +i = m = n = v, d && (o = Wg(), j = a.apply(l, h), m || i || (h = l = null)); +} else m = ng(e, c); } -function ac(a, b) { -return ma(b, 16, [ a ]); +function f() { +m && hg(m), i = m = n = v, (q || p !== b) && (o = Wg(), j = a.apply(l, h), m || i || (h = l = null)); +} +function g() { +if (h = arguments, k = Wg(), l = this, n = q && (m || !r), p === !1) var c = r && !m; else { +i || r || (o = k); +var d = p - (k - o), g = 0 >= d || d > p; +g ? (i && (i = hg(i)), o = k, j = a.apply(l, h)) :i || (i = ng(f, d)); +} +return g && m ? m = hg(m) :m || b === p || (m = ng(e, b)), c && (g = !0, j = a.apply(l, h)), !g || m || i || (h = l = null), j; +} +var h, i, j, k, l, m, n, o = 0, p = !1, q = !0; +if ("function" != typeof a) throw new Vf(N); +if (b = 0 > b ? 0 :b, c === !0) { +var r = !0; +q = !1; +} else Ae(c) && (r = c.leading, p = "maxWait" in c && wg(+c.maxWait || 0, b), q = "trailing" in c ? c.trailing :q); +return g.cancel = d, g; +} +function de(a) { +return qb(a, 1, arguments, 1); } -function bc(a) { +function ee(a, b) { +return qb(a, b, arguments, 2); +} +function fe() { +var a = arguments, b = a.length; +if (!b) return function() { +return arguments[0]; +}; +if (!ab(a, ze)) throw new Vf(N); return function() { -return a; +for (var c = 0, d = a[c].apply(this, arguments); ++c < b; ) d = a[c].call(this, d); +return d; }; } -function cc(a, b, c) { -var d = typeof a; -if (null == a || "function" == d) return ca(a, b, c); -if ("object" != d) return ic(a); -var e = md(a), f = e[0], g = a[f]; -return 1 != e.length || g !== g || La(g) ? function(b) { -for (var c = e.length, d = !1; c-- && (d = ha(b[e[c]], a[e[c]], null, !0)); ) ; +function ge() { +var a = arguments, b = a.length - 1; +if (0 > b) return function() { +return arguments[0]; +}; +if (!ab(a, ze)) throw new Vf(N); +return function() { +for (var c = b, d = a[c].apply(this, arguments); c--; ) d = a[c].call(this, d); return d; -} :function(a) { -var b = a[f]; -return g === b && (0 !== g || 1 / g == 1 / b); }; } -function dc(a) { -return null == a ? "" :Dc(a).replace(td, oa); +function he(a, b) { +if ("function" != typeof a || b && "function" != typeof b) throw new Vf(N); +var c = function() { +var d = c.cache, e = b ? b.apply(this, arguments) :arguments[0]; +if (d.has(e)) return d.get(e); +var f = a.apply(this, arguments); +return d.set(e, f), f; +}; +return c.cache = new he.Cache(), c; } -function ec(a) { -return a; +function ie(a) { +if ("function" != typeof a) throw new Vf(N); +return function() { +return !a.apply(this, arguments); +}; } -function fc(a, b, c) { -var d = !0, e = b && Ba(b); -b && (c || e.length) || (null == c && (c = b), f = r, b = a, a = q, e = Ba(b)), c === !1 ? d = !1 :La(c) && "chain" in c && (d = c.chain); -var f = a, g = Ka(f); -db(e, function(c) { -var e = a[c] = b[c]; -g && (f.prototype[c] = function() { -var b = this.__chain__, c = this.__wrapped__, g = [ c ]; -Sc.apply(g, arguments); -var h = e.apply(a, g); -if (d || b) { -if (c === h && La(h)) return this; -h = new f(h), h.__chain__ = b; +function je(a) { +return Yd(a, 2); } -return h; -}); -}); +function ke(a) { +var b = Sb(arguments, 1), c = p(b, ke.placeholder); +return kc(a, C, null, b, c); +} +function le(a) { +var b = Sb(arguments, 1), c = p(b, le.placeholder); +return kc(a, D, null, b, c); } -function gc() { -return c._ = Jc, this; +function me(a) { +var b = yb(arguments, !1, !1, 1); +return kc(a, E, null, null, null, b); } -function hc() {} -function ic(a) { +function ne(a) { +if ("function" != typeof a) throw new Vf(N); return function(b) { -return b[a]; +return a.apply(this, b); }; } -function jc(a, b, c) { -var d = null == a, e = null == b; -if (null == c && ("boolean" == typeof a && e ? (c = a, a = 1) :e || "boolean" != typeof b || (c = b, e = !0)), d && e && (b = 1), a = +a || 0, e ? (b = a, a = 0) :b = +b || 0, c || a % 1 || b % 1) { -var f = ed(); -return cd(a + f * (b - a + parseFloat("1e-" + ((f + "").length - 1))), b); +function oe(a, b, c) { +var d = !0, e = !0; +if ("function" != typeof a) throw new Vf(N); +return c === !1 ? d = !1 :Ae(c) && (d = "leading" in c ? !!c.leading :d, e = "trailing" in c ? !!c.trailing :e), La.leading = d, La.maxWait = +b, La.trailing = e, ce(a, b, La); } -return ja(a, b); +function pe(a, b) { +return b = null == b ? Bf :b, kc(b, C, null, [ a ], []); } -function kc(a, b) { -if (a) { -var c = a[b]; -return Ka(c) ? a[b]() :c; -} -} -function lc(a, b, c) { -var d = q.templateSettings; -a = Dc(a || ""), c = wd({}, c, d); -var e, f = wd({}, c.imports, d.imports), h = md(f), i = Ya(f), j = 0, k = c.interpolate || G, l = "__p += '", m = Cc((c.escape || G).source + "|" + k.source + "|" + (k === E ? B :G).source + "|" + (c.evaluate || G).source + "|$", "g"); -a.replace(m, function(b, c, d, f, h, i) { -return d || (d = f), l += a.slice(j, i).replace(I, g), c && (l += "' +\n__e(" + c + ") +\n'"), h && (e = !0, l += "';\n" + h + ";\n__p += '"), d && (l += "' +\n((__t = (" + d + ")) == null ? '' : __t) +\n'"), j = i + b.length, b; -}), l += "';\n"; -var n = c.variable, o = n; -o || (n = "obj", l = "with (" + n + ") {\n" + l + "\n}\n"), l = (e ? l.replace(y, "") :l).replace(z, "$1").replace(A, "$1;"), l = "function(" + n + ") {\n" + (o ? "" :n + " || (" + n + " = {});\n") + "var __t, __p = '', __e = _.escape" + (e ? ", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n" :";\n") + l + "return __p\n}"; -var r = "\n/*\n//# sourceURL=" + (c.sourceURL || "/lodash/template/source[" + L++ + "]") + "\n*/"; -try { -var s = yc(h, "return " + l + r).apply(p, i); -} catch (t) { -throw t.source = l, t; +function qe(a, b, c, d) { +return "boolean" != typeof b && null != b && (d = c, c = xc(a, b, d) ? null :b, b = !1), c = "function" == typeof c && Zb(c, d, 1), pb(a, b, c); } -return b ? s(b) :(s.source = l, s); +function re(a, b, c) { +return b = "function" == typeof b && Zb(b, c, 1), pb(a, !0, b); +} +function se(a) { +var b = n(a) ? a.length :v; +return yc(b) && bg.call(a) == P || !1; +} +function te(a) { +return a === !0 || a === !1 || n(a) && bg.call(a) == R || !1; +} +function ue(a) { +return n(a) && bg.call(a) == S || !1; +} +function ve(a) { +return a && 1 === a.nodeType && n(a) && bg.call(a).indexOf("Element") > -1 || !1; +} +function we(a) { +if (null == a) return !0; +var b = a.length; +return yc(b) && (Xg(a) || He(a) || se(a) || n(a) && ze(a.splice)) ? !b :!_g(a).length; +} +function xe(a, b, c, d) { +if (c = "function" == typeof c && Zb(c, d, 3), !c && zc(a) && zc(b)) return a === b; +var e = c ? c(a, b) :v; +return "undefined" == typeof e ? Gb(a, b, c) :!!e; +} +function ye(a) { +return n(a) && "string" == typeof a.message && bg.call(a) == T || !1; +} +function ze(a) { +return "function" == typeof a || !1; +} +function Ae(a) { +var b = typeof a; +return "function" == b || a && "object" == b || !1; +} +function Be(a, b, c, d) { +var e = _g(b), f = e.length; +if (c = "function" == typeof c && Zb(c, d, 3), !c && 1 == f) { +var g = e[0], h = b[g]; +if (zc(h)) return null != a && h === a[g] && _f.call(a, g); +} +for (var i = Mf(f), j = Mf(f); f--; ) h = i[f] = b[e[f]], j[f] = zc(h); +return Ib(a, e, i, j, c); +} +function Ce(a) { +return Fe(a) && a != +a; +} +function De(a) { +return null == a ? !1 :bg.call(a) == U ? dg.test(Zf.call(a)) :n(a) && ya.test(a) || !1; +} +function Ee(a) { +return null === a; +} +function Fe(a) { +return "number" == typeof a || n(a) && bg.call(a) == W || !1; +} +function Ge(a) { +return n(a) && bg.call(a) == Y || !1; +} +function He(a) { +return "string" == typeof a || n(a) && bg.call(a) == $ || !1; +} +function Ie(a) { +return n(a) && yc(a.length) && Ja[bg.call(a)] || !1; +} +function Je(a) { +return "undefined" == typeof a; +} +function Ke(a) { +var b = a ? a.length :0; +return yc(b) ? b ? Za(a) :[] :cf(a); +} +function Le(a) { +return mb(a, Xe(a)); +} +function Me(a, b, c) { +var d = Lg(a); +return c && xc(a, b, c) && (b = null), b ? mb(b, d, _g(b)) :d; +} +function Ne(a) { +if (null == a) return a; +var b = Za(arguments); +return b.push(ib), $g.apply(v, b); +} +function Oe(a, b, c) { +return b = pc(b, c, 3), xb(a, b, Cb, !0); +} +function Pe(a, b, c) { +return b = pc(b, c, 3), xb(a, b, Db, !0); +} +function Qe(a, b, c) { +return ("function" != typeof b || "undefined" != typeof c) && (b = Zb(b, c, 3)), zb(a, b, Xe); +} +function Re(a, b, c) { +return b = Zb(b, c, 3), Ab(a, b, Xe); +} +function Se(a, b, c) { +return ("function" != typeof b || "undefined" != typeof c) && (b = Zb(b, c, 3)), Cb(a, b); +} +function Te(a, b, c) { +return b = Zb(b, c, 3), Ab(a, b, _g); +} +function Ue(a) { +return Eb(a, Xe(a)); +} +function Ve(a, b) { +return a ? _f.call(a, b) :!1; +} +function We(a, b, c) { +c && xc(a, b, c) && (b = null); +for (var d = -1, e = _g(a), f = e.length, g = {}; ++d < f; ) { +var h = e[d], i = a[h]; +b ? _f.call(g, i) ? g[i].push(h) :g[i] = [ h ] :g[i] = h; +} +return g; +} +function Xe(a) { +if (null == a) return []; +Ae(a) || (a = Sf(a)); +var b = a.length; +b = b && yc(b) && (Xg(a) || Kg.nonEnumArgs && se(a)) && b || 0; +for (var c = a.constructor, d = -1, e = "function" == typeof c && c.prototype === a, f = Mf(b), g = b > 0; ++d < b; ) f[d] = d + ""; +for (var h in a) g && wc(h, b) || "constructor" == h && (e || !_f.call(a, h)) || f.push(h); +return f; +} +function Ye(a, b, c) { +var d = {}; +return b = pc(b, c, 3), Cb(a, function(a, c, e) { +d[c] = b(a, c, e); +}), d; +} +function Ze(a, b, c) { +if (null == a) return {}; +if ("function" != typeof b) { +var d = cb(yb(arguments, !1, !1, 1), Uf); +return Bc(a, rb(Xe(a), d)); +} +return b = Zb(b, c, 3), Cc(a, function(a, c, d) { +return !b(a, c, d); +}); +} +function $e(a) { +for (var b = -1, c = _g(a), d = c.length, e = Mf(d); ++b < d; ) { +var f = c[b]; +e[b] = [ f, a[f] ]; } -function mc(a, b, c) { -a = (a = +a) > -1 ? a :0; -var d = -1, e = uc(a); -for (b = ca(b, c, 1); ++d < a; ) e[d] = b(d); return e; } -function nc(a) { -return null == a ? "" :Dc(a).replace(sd, sa); +function _e(a, b, c) { +return null == a ? {} :"function" == typeof b ? Cc(a, Zb(b, c, 3)) :Bc(a, yb(arguments, !1, !1, 1)); } -function oc(a) { -var b = ++s; -return Dc(null == a ? "" :a) + b; +function af(a, b, c) { +var d = null == a ? v :a[b]; +return "undefined" == typeof d && (d = c), ze(d) ? d.call(a) :d; } -function pc(a) { -return a = new r(a), a.__chain__ = !0, a; +function bf(a, b, c, d) { +var e = Xg(a) || Ie(a); +if (b = pc(b, d, 4), null == c) if (e || Ae(a)) { +var f = a.constructor; +c = e ? Xg(a) ? new f() :[] :Lg(ze(f) && f.prototype); +} else c = {}; +return (e ? $a :Cb)(a, function(a, d, e) { +return b(c, a, d, e); +}), c; } -function qc(a, b) { -return b(a), a; +function cf(a) { +return Vb(a, _g(a)); } -function rc() { -return this.__chain__ = !0, this; +function df(a) { +return Vb(a, Xe(a)); } -function sc() { -return Dc(this.__wrapped__); +function ef(a, b, c) { +c && xc(a, b, c) && (b = c = null); +var d = null == a, e = null == b; +if (null == c && (e && "boolean" == typeof a ? (c = a, a = 1) :"boolean" == typeof b && (c = b, e = !0)), d && e && (b = 1, e = !1), a = +a || 0, e ? (b = a, a = 0) :b = +b || 0, c || a % 1 || b % 1) { +var f = Bg(); +return xg(a + f * (b - a + parseFloat("1e-" + ((f + "").length - 1))), b); } -function tc() { -return this.__wrapped__; +return Qb(a, b); } -c = c ? fa.defaults(aa.Object(), c, fa.pick(aa, J)) :aa; -var uc = c.Array, vc = c.Boolean, wc = c.Date, xc = c.Error, yc = c.Function, zc = c.Math, Ac = c.Number, Bc = c.Object, Cc = c.RegExp, Dc = c.String, Ec = c.TypeError, Fc = [], Gc = xc.prototype, Hc = Bc.prototype, Ic = Dc.prototype, Jc = c._, Kc = Hc.toString, Lc = Cc("^" + Dc(Kc).replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/toString| for [^\]]+/g, ".*?") + "$"), Mc = zc.ceil, Nc = c.clearTimeout, Oc = zc.floor, Pc = yc.prototype.toString, Qc = qa(Qc = Bc.getPrototypeOf) && Qc, Rc = Hc.hasOwnProperty, Sc = Fc.push, Tc = Hc.propertyIsEnumerable, Uc = c.setTimeout, Vc = Fc.splice, Wc = Fc.unshift, Xc = function() { -try { -var a = {}, b = qa(b = Bc.defineProperty) && b, c = b(a, a, a) && b; -} catch (d) {} +function ff(a) { +return a = d(a), a && a.charAt(0).toUpperCase() + a.slice(1); +} +function gf(a) { +return a = d(a), a && a.replace(za, j); +} +function hf(a, b, c) { +a = d(a), b += ""; +var e = a.length; +return c = ("undefined" == typeof c ? e :xg(0 > c ? 0 :+c || 0, e)) - b.length, c >= 0 && a.indexOf(b, c) == c; +} +function jf(a) { +return a = d(a), a && qa.test(a) ? a.replace(oa, k) :a; +} +function kf(a) { +return a = d(a), a && Ca.test(a) ? a.replace(Ba, "\\$&") :a; +} +function lf(a, b, c) { +a = d(a), b = +b; +var e = a.length; +if (e >= b || !ug(b)) return a; +var f = (b - e) / 2, g = ig(f), h = gg(f); +return c = ic("", h, c), c.slice(0, g) + a + c; +} +function mf(a, b, c) { +return a = d(a), a && ic(a, b, c) + a; +} +function nf(a, b, c) { +return a = d(a), a && a + ic(a, b, c); +} +function of(a, b, c) { +return c && xc(a, b, c) && (b = 0), Ag(a, b); +} +function pf(a, b) { +var c = ""; +if (a = d(a), b = +b, 1 > b || !a || !ug(b)) return c; +do b % 2 && (c += a), b = ig(b / 2), a += a; while (b); return c; -}(), Yc = qa(Yc = Bc.create) && Yc, Zc = qa(Zc = uc.isArray) && Zc, $c = c.isFinite, _c = c.isNaN, ad = qa(ad = Bc.keys) && ad, bd = zc.max, cd = zc.min, dd = c.parseInt, ed = zc.random, fd = {}; -fd[N] = uc, fd[O] = vc, fd[P] = wc, fd[R] = yc, fd[T] = Bc, fd[S] = Ac, fd[U] = Cc, fd[V] = Dc; -var gd = {}; -gd[N] = gd[P] = gd[S] = { -constructor:!0, -toLocaleString:!0, -toString:!0, -valueOf:!0 -}, gd[O] = gd[V] = { -constructor:!0, -toString:!0, -valueOf:!0 -}, gd[Q] = gd[R] = gd[U] = { -constructor:!0, -toString:!0 -}, gd[T] = { -constructor:!0 -}, function() { -for (var a = K.length; a--; ) { -var b = K[a]; -for (var c in gd) Rc.call(gd, c) && !Rc.call(gd[c], b) && (gd[c][b] = !1); } -}(), r.prototype = q.prototype; -var hd = q.support = {}; +function qf(a, b, c) { +return a = d(a), c = null == c ? 0 :xg(0 > c ? 0 :+c || 0, a.length), a.lastIndexOf(b, c) == c; +} +function rf(a, b, c) { +var e = V.templateSettings; +c && xc(a, b, c) && (b = c = null), a = d(a), b = kb(kb({}, c || b), e, jb); +var f, g, h = kb(kb({}, b.imports), e.imports, jb), i = _g(h), j = Vb(h, i), k = 0, m = b.interpolate || Aa, n = "__p += '", o = Tf((b.escape || Aa).source + "|" + m.source + "|" + (m === ta ? ua :Aa).source + "|" + (b.evaluate || Aa).source + "|$", "g"), p = "//# sourceURL=" + ("sourceURL" in b ? b.sourceURL :"lodash.templateSources[" + ++Ia + "]") + "\n"; +a.replace(o, function(b, c, d, e, h, i) { +return d || (d = e), n += a.slice(k, i).replace(Ea, l), c && (f = !0, n += "' +\n__e(" + c + ") +\n'"), h && (g = !0, n += "';\n" + h + ";\n__p += '"), d && (n += "' +\n((__t = (" + d + ")) == null ? '' : __t) +\n'"), k = i + b.length, b; +}), n += "';\n"; +var q = b.variable; +q || (n = "with (obj) {\n" + n + "\n}\n"), n = (g ? n.replace(ka, "") :n).replace(la, "$1").replace(ma, "$1;"), n = "function(" + (q || "obj") + ") {\n" + (q ? "" :"obj || (obj = {});\n") + "var __t, __p = ''" + (f ? ", __e = _.escape" :"") + (g ? ", __j = Array.prototype.join;\nfunction print() { __p += __j.call(arguments, '') }\n" :";\n") + n + "return __p\n}"; +var r = yf(function() { +return Pf(i, p + "return " + n).apply(v, j); +}); +if (r.source = n, ye(r)) throw r; +return r; +} +function sf(a, b, c) { +var e = a; +return (a = d(a)) ? (c ? xc(e, b, c) :null == b) ? a.slice(r(a), s(a) + 1) :(b += "", a.slice(f(a, b), g(a, b) + 1)) :a; +} +function tf(a, b, c) { +var e = a; +return a = d(a), a ? a.slice((c ? xc(e, b, c) :null == b) ? r(a) :f(a, b + "")) :a; +} +function uf(a, b, c) { +var e = a; +return a = d(a), a ? (c ? xc(e, b, c) :null == b) ? a.slice(0, s(a) + 1) :a.slice(0, g(a, b + "") + 1) :a; +} +function vf(a, b, c) { +c && xc(a, b, c) && (b = null); +var e = G, f = H; +if (null != b) if (Ae(b)) { +var g = "separator" in b ? b.separator :g; +e = "length" in b ? +b.length || 0 :e, f = "omission" in b ? d(b.omission) :f; +} else e = +b || 0; +if (a = d(a), e >= a.length) return a; +var h = e - f.length; +if (1 > h) return f; +var i = a.slice(0, h); +if (null == g) return i + f; +if (Ge(g)) { +if (a.slice(h).search(g)) { +var j, k, l = a.slice(0, h); +for (g.global || (g = Tf(g.source, (va.exec(g) || "") + "g")), g.lastIndex = 0; j = g.exec(l); ) k = j.index; +i = i.slice(0, null == k ? h :k); +} +} else if (a.indexOf(g, h) != h) { +var m = i.lastIndexOf(g); +m > -1 && (i = i.slice(0, m)); +} +return i + f; +} +function wf(a) { +return a = d(a), a && pa.test(a) ? a.replace(na, t) :a; +} +function xf(a, b, c) { +return c && xc(a, b, c) && (b = null), a = d(a), a.match(b || Fa) || []; +} +function yf(a) { +try { +return a.apply(v, Sb(arguments, 1)); +} catch (b) { +return ye(b) ? b :new Of(b); +} +} +function zf(a, b, c) { +return c && xc(a, b, c) && (b = null), n(a) ? Cf(a) :ob(a, b); +} +function Af(a) { +return function() { +return a; +}; +} +function Bf(a) { +return a; +} +function Cf(a) { +return Kb(pb(a, !0)); +} +function Df(a, b) { +return Lb(a + "", pb(b, !0)); +} +function Ef(a, b, c) { +if (null == c) { +var d = Ae(b), e = d && _g(b), f = e && e.length && Eb(b, e); +(f ? f.length :d) || (f = !1, c = b, b = a, a = this); +} +f || (f = Eb(b, _g(b))); +var g = !0, h = -1, i = ze(a), j = f.length; +c === !1 ? g = !1 :Ae(c) && "chain" in c && (g = c.chain); +for (;++h < j; ) { +var k = f[h], l = b[k]; +a[k] = l, i && (a.prototype[k] = function(b) { +return function() { +var c = this.__chain__; +if (g || c) { +var d = a(this.__wrapped__); +return (d.__actions__ = Za(this.__actions__)).push({ +func:b, +args:arguments, +thisArg:a +}), d.__chain__ = c, d; +} +var e = [ this.value() ]; +return kg.apply(e, arguments), b.apply(a, e); +}; +}(l)); +} +return a; +} +function Ff() { +return o._ = cg, this; +} +function Gf() {} +function Hf(a) { +return Ob(a + ""); +} +function If(a) { +return function(b) { +return null == a ? v :a[b]; +}; +} +function Jf(a, b, c) { +c && xc(a, b, c) && (b = c = null), a = +a || 0, c = null == c ? 1 :+c || 0, null == b ? (b = a, a = 0) :b = +b || 0; +for (var d = -1, e = wg(gg((b - a) / (c || 1)), 0), f = Mf(e); ++d < e; ) f[d] = a, a += c; +return f; +} +function Kf(a, b, c) { +if (a = +a, 1 > a || !ug(a)) return []; +var d = -1, e = Mf(xg(a, Eg)); +for (b = Zb(b, c, 1); ++d < a; ) Eg > d ? e[d] = b(d) :b(d); +return e; +} +function Lf(a) { +var b = ++ag; +return d(a) + b; +} +o = o ? Wa.defaults(Ra.Object(), o, Wa.pick(Ra, Ha)) :Ra; +var Mf = o.Array, Nf = o.Date, Of = o.Error, Pf = o.Function, Qf = o.Math, Rf = o.Number, Sf = o.Object, Tf = o.RegExp, Uf = o.String, Vf = o.TypeError, Wf = Mf.prototype, Xf = Sf.prototype, Yf = (Yf = o.window) && Yf.document, Zf = Pf.prototype.toString, $f = Ob("length"), _f = Xf.hasOwnProperty, ag = 0, bg = Xf.toString, cg = o._, dg = Tf("^" + kf(bg).replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$"), eg = De(eg = o.ArrayBuffer) && eg, fg = De(fg = eg && new eg(0).slice) && fg, gg = Qf.ceil, hg = o.clearTimeout, ig = Qf.floor, jg = De(jg = Sf.getPrototypeOf) && jg, kg = Wf.push, lg = Xf.propertyIsEnumerable, mg = De(mg = o.Set) && mg, ng = o.setTimeout, og = Wf.splice, pg = De(pg = o.Uint8Array) && pg, qg = De(qg = o.WeakMap) && qg, rg = function() { +try { +var a = De(a = o.Float64Array) && a, b = new a(new eg(10), 0, 1) && a; +} catch (c) {} +return b; +}(), sg = De(sg = Mf.isArray) && sg, tg = De(tg = Sf.create) && tg, ug = o.isFinite, vg = De(vg = Sf.keys) && vg, wg = Qf.max, xg = Qf.min, yg = De(yg = Nf.now) && yg, zg = De(zg = Rf.isFinite) && zg, Ag = o.parseInt, Bg = Qf.random, Cg = Rf.NEGATIVE_INFINITY, Dg = Rf.POSITIVE_INFINITY, Eg = Qf.pow(2, 32) - 1, Fg = Eg - 1, Gg = Eg >>> 1, Hg = rg ? rg.BYTES_PER_ELEMENT :0, Ig = Qf.pow(2, 53) - 1, Jg = qg && new qg(), Kg = V.support = {}; !function() { -var a = function() { -this.x = 1; -}, b = { -"0":1, -length:1 -}, d = []; -a.prototype = { -valueOf:1, -y:1 -}; -for (var e in new a()) d.push(e); -for (e in arguments) ; -hd.argsClass = Kc.call(arguments) == M, hd.argsObject = arguments.constructor == Bc && !(arguments instanceof uc), hd.enumErrorProps = Tc.call(Gc, "message") || Tc.call(Gc, "name"), hd.enumPrototypes = Tc.call(a, "prototype"), hd.funcDecomp = !qa(c.WinRTError) && H.test(o), hd.funcNames = "string" == typeof yc.name, hd.nonEnumArgs = 0 != e, hd.nonEnumShadows = !/valueOf/.test(d), hd.ownLast = "x" != d[0], hd.spliceObjects = (Fc.splice.call(b, 0, 1), !b[0]), hd.unindexedChars = "x"[0] + Bc("x")[0] != "xx"; +Kg.funcDecomp = !De(o.WinRTError) && Da.test(u), Kg.funcNames = "string" == typeof Pf.name; try { -hd.nodeClass = !(Kc.call(document) == T && !({ -toString:0 -} + "")); -} catch (f) { -hd.nodeClass = !0; +Kg.dom = 11 === Yf.createDocumentFragment().nodeType; +} catch (a) { +Kg.dom = !1; } -}(1), q.templateSettings = { -escape:/<%-([\s\S]+?)%>/g, -evaluate:/<%([\s\S]+?)%>/g, -interpolate:E, +try { +Kg.nonEnumArgs = !lg.call(arguments, 1); +} catch (a) { +Kg.nonEnumArgs = !0; +} +}(0, 0), V.templateSettings = { +escape:ra, +evaluate:sa, +interpolate:ta, variable:"", imports:{ -_:q -} -}; -var id = function(a) { -var b = "var index, iterable = " + a.firstArg + ", result = " + a.init + ";\nif (!iterable) return result;\n" + a.top + ";"; -a.array ? (b += "\nvar length = iterable.length; index = -1;\nif (" + a.array + ") { ", hd.unindexedChars && (b += "\n if (isString(iterable)) {\n iterable = iterable.split('')\n } "), b += "\n while (++index < length) {\n " + a.loop + ";\n }\n}\nelse { ") :hd.nonEnumArgs && (b += "\n var length = iterable.length; index = -1;\n if (length && isArguments(iterable)) {\n while (++index < length) {\n index += '';\n " + a.loop + ";\n }\n } else { "), hd.enumPrototypes && (b += "\n var skipProto = typeof iterable == 'function';\n "), hd.enumErrorProps && (b += "\n var skipErrorProps = iterable === errorProto || iterable instanceof Error;\n "); -var c = []; -if (hd.enumPrototypes && c.push('!(skipProto && index == "prototype")'), hd.enumErrorProps && c.push('!(skipErrorProps && (index == "message" || index == "name"))'), a.useHas && a.keys) b += "\n var ownIndex = -1,\n ownProps = objectTypes[typeof iterable] && keys(iterable),\n length = ownProps ? ownProps.length : 0;\n\n while (++ownIndex < length) {\n index = ownProps[ownIndex];\n", c.length && (b += " if (" + c.join(" && ") + ") {\n "), b += a.loop + "; ", c.length && (b += "\n }"), b += "\n } "; else if (b += "\n for (index in iterable) {\n", a.useHas && c.push("hasOwnProperty.call(iterable, index)"), c.length && (b += " if (" + c.join(" && ") + ") {\n "), b += a.loop + "; ", c.length && (b += "\n }"), b += "\n } ", hd.nonEnumShadows) { -for (b += "\n\n if (iterable !== objectProto) {\n var ctor = iterable.constructor,\n isProto = iterable === (ctor && ctor.prototype),\n className = iterable === stringProto ? stringClass : iterable === errorProto ? errorClass : toString.call(iterable),\n nonEnum = nonEnumProps[className];\n ", k = 0; 7 > k; k++) b += "\n index = '" + a.shadowedProps[k] + "';\n if ((!(isProto && nonEnum[index]) && hasOwnProperty.call(iterable, index))", a.useHas || (b += " || (!nonEnum[index] && iterable[index] !== objectProto[index])"), b += ") {\n " + a.loop + ";\n } "; -b += "\n } "; +_:V } -return (a.array || hd.nonEnumArgs) && (b += "\n}"), b += a.bottom + ";\nreturn result"; }; -Yc || (ba = function() { +var Lg = function() { function a() {} return function(b) { -if (La(b)) { +if (Ae(b)) { a.prototype = b; -var d = new a(); +var c = new a(); a.prototype = null; } -return d || c.Object(); -}; -}()); -var jd = Xc ? function(a, b) { -Y.value = b, Xc(a, "__bindData__", Y); -} :hc; -hd.argsClass || (ta = function(a) { -return a && "object" == typeof a && "number" == typeof a.length && Rc.call(a, "callee") && !Tc.call(a, "callee") || !1; -}); -var kd = Zc || function(a) { -return a && "object" == typeof a && "number" == typeof a.length && Kc.call(a) == N || !1; -}, ld = na({ -args:"object", -init:"[]", -top:"if (!(objectTypes[typeof object])) return result", -loop:"result.push(index)" -}), md = ad ? function(a) { -return La(a) ? hd.enumPrototypes && "function" == typeof a || hd.nonEnumArgs && a.length && ta(a) ? ld(a) :ad(a) :[]; -} :ld, nd = { -args:"collection, callback, thisArg", -top:"callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3)", -array:"typeof length == 'number'", -keys:md, -loop:"if (callback(iterable[index], index, collection) === false) return result" -}, od = { -args:"object, source, guard", -top:"var args = arguments,\n argsIndex = 0,\n argsLength = typeof guard == 'number' ? 2 : args.length;\nwhile (++argsIndex < argsLength) {\n iterable = args[argsIndex];\n if (iterable && objectTypes[typeof iterable]) {", -keys:md, -loop:"if (typeof result[index] == 'undefined') result[index] = iterable[index]", -bottom:" }\n}" -}, pd = { -top:"if (!objectTypes[typeof iterable]) return result;\n" + nd.top, -array:!1 -}, qd = { -"&":"&", -"<":"<", -">":">", -'"':""", -"'":"'" -}, rd = Da(qd), sd = Cc("(" + md(rd).join("|") + ")", "g"), td = Cc("[" + md(qd).join("") + "]", "g"), ud = na(nd), vd = na(od, { -top:od.top.replace(";", ";\nif (argsLength > 3 && typeof args[argsLength - 2] == 'function') {\n var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2);\n} else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') {\n callback = args[--argsLength];\n}"), -loop:"result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]" -}), wd = na(od), xd = na(nd, pd, { -useHas:!1 -}), yd = na(nd, pd); -Ka(/x/) && (Ka = function(a) { -return "function" == typeof a && Kc.call(a) == R; -}); -var zd = Qc ? function(a) { -if (!a || Kc.call(a) != T || !hd.argsClass && ta(a)) return !1; -var b = a.valueOf, c = qa(b) && (c = Qc(b)) && Qc(c); -return c ? a == c || Qc(a) == c :ra(a); -} :ra, Ad = la(function(a, b, c) { -Rc.call(a, c) ? a[c]++ :a[c] = 1; -}), Bd = la(function(a, b, c) { -(Rc.call(a, c) ? a[c] :a[c] = []).push(b); -}), Cd = la(function(a, b, c) { +return c || o.Object(); +}; +}(), Mg = Jg ? function(a, b) { +return Jg.set(a, b), a; +} :Bf; +fg || ($b = eg && pg ? function(a) { +var b = a.byteLength, c = rg ? ig(b / Hg) :0, d = c * Hg, e = new eg(b); +if (c) { +var f = new rg(e, 0, c); +f.set(new rg(a, 0, c)); +} +return b != d && (f = new pg(e, d), f.set(new pg(a, d))), e; +} :Af(null)); +var Ng = tg && mg ? function(a) { +return new Va(a); +} :Af(null), Og = Jg ? function(a) { +return Jg.get(a); +} :Gf, Pg = function() { +var a = 0, b = 0; +return function(c, d) { +var e = Wg(), f = J - (e - b); +if (b = e, f > 0) { +if (++a >= I) return c; +} else a = 0; +return Mg(c, d); +}; +}(), Qg = bc(function(a, b, c) { +_f.call(a, c) ? ++a[c] :a[c] = 1; +}), Rg = bc(function(a, b, c) { +_f.call(a, c) ? a[c].push(b) :a[c] = [ b ]; +}), Sg = bc(function(a, b, c) { a[c] = b; -}), Dd = gb, Ed = ab, Fd = qa(Fd = wc.now) && Fd || function() { -return new wc().getTime(); -}, Gd = 8 == dd(x + "08") ? dd :function(a, b) { -return dd(Qa(a) ? a.replace(F, "") :a, b || 0); -}; -return q.after = Ob, q.assign = vd, q.at = Za, q.bind = Pb, q.bindAll = Qb, q.bindKey = Rb, q.chain = pc, q.compact = sb, q.compose = Sb, q.constant = bc, q.countBy = Ad, q.create = wa, q.createCallback = cc, q.curry = Tb, q.debounce = Ub, q.defaults = wd, q.defer = Vb, q.delay = Wb, q.difference = tb, q.filter = ab, q.flatten = xb, q.forEach = db, q.forEachRight = eb, q.forIn = xd, q.forInRight = za, q.forOwn = yd, q.forOwnRight = Aa, q.functions = Ba, q.groupBy = Bd, q.indexBy = Cd, q.initial = zb, q.intersection = Ab, q.invert = Da, q.invoke = fb, q.keys = md, q.map = gb, q.mapValues = Sa, q.max = hb, q.memoize = Xb, q.merge = Ta, q.min = ib, q.omit = Ua, q.once = Yb, q.pairs = Va, q.partial = Zb, q.partialRight = $b, q.pick = Wa, q.pluck = Dd, q.property = ic, q.pull = Db, q.range = Eb, q.reject = lb, q.remove = Fb, q.rest = Gb, q.shuffle = nb, q.sortBy = qb, q.tap = qc, q.throttle = _b, q.times = mc, q.toArray = rb, q.transform = Xa, q.union = Ib, q.uniq = Jb, q.values = Ya, q.where = Ed, -q.without = Kb, q.wrap = ac, q.xor = Lb, q.zip = Mb, q.zipObject = Nb, q.collect = gb, q.drop = Gb, q.each = db, q.eachRight = eb, q.extend = vd, q.methods = Ba, q.object = Nb, q.select = ab, q.tail = Gb, q.unique = Jb, q.unzip = Mb, fc(q), q.clone = ua, q.cloneDeep = va, q.contains = $a, q.escape = dc, q.every = _a, q.find = bb, q.findIndex = ub, q.findKey = xa, q.findLast = cb, q.findLastIndex = vb, q.findLastKey = ya, q.has = Ca, q.identity = ec, q.indexOf = yb, q.isArguments = ta, q.isArray = kd, q.isBoolean = Ea, q.isDate = Fa, q.isElement = Ga, q.isEmpty = Ha, q.isEqual = Ia, q.isFinite = Ja, q.isFunction = Ka, q.isNaN = Ma, q.isNull = Na, q.isNumber = Oa, q.isObject = La, q.isPlainObject = zd, q.isRegExp = Pa, q.isString = Qa, q.isUndefined = Ra, q.lastIndexOf = Cb, q.mixin = fc, q.noConflict = gc, q.noop = hc, q.now = Fd, q.parseInt = Gd, q.random = jc, q.reduce = jb, q.reduceRight = kb, q.result = kc, q.runInContext = o, q.size = ob, q.some = pb, q.sortedIndex = Hb, q.template = lc, -q.unescape = nc, q.uniqueId = oc, q.all = _a, q.any = pb, q.detect = bb, q.findWhere = bb, q.foldl = jb, q.foldr = kb, q.include = $a, q.inject = jb, fc(function() { +}), Tg = gc(db), Ug = gc(eb, !0), Vg = bc(function(a, b, c) { +a[c ? 0 :1].push(b); +}, function() { +return [ [], [] ]; +}), Wg = yg || function() { +return new Nf().getTime(); +}, Xg = sg || function(a) { +return n(a) && yc(a.length) && bg.call(a) == Q || !1; +}; +Kg.dom || (ve = function(a) { +return a && 1 === a.nodeType && n(a) && !Zg(a) || !1; +}); +var Yg = zg || function(a) { +return "number" == typeof a && ug(a); +}; +(ze(/x/) || pg && !ze(pg)) && (ze = function(a) { +return bg.call(a) == U; +}); +var Zg = jg ? function(a) { +if (!a || bg.call(a) != X) return !1; +var b = a.valueOf, c = De(b) && (c = jg(b)) && jg(c); +return c ? a == c || jg(a) == c :Ec(a); +} :Ec, $g = cc(kb), _g = vg ? function(a) { +if (a) var b = a.constructor, c = a.length; +return "function" == typeof b && b.prototype === a || "function" != typeof a && c && yc(c) ? Fc(a) :Ae(a) ? vg(a) :[]; +} :Fc, ah = cc(Mb), bh = ec(function(a, b, c) { +return b = b.toLowerCase(), a + (c ? b.charAt(0).toUpperCase() + b.slice(1) :b); +}), ch = ec(function(a, b, c) { +return a + (c ? "-" :"") + b.toLowerCase(); +}); +8 != Ag(Ga + "08") && (of = function(a, b, c) { +return (c ? xc(a, b, c) :null == b) ? b = 0 :b && (b = +b), a = sf(a), Ag(a, b || (xa.test(a) ? 16 :10)); +}); +var dh = ec(function(a, b, c) { +return a + (c ? "_" :"") + b.toLowerCase(); +}), eh = ec(function(a, b, c) { +return a + (c ? " " :"") + (b.charAt(0).toUpperCase() + b.slice(1)); +}); +return Z.prototype = Lg(V.prototype), _.prototype = Lg(Z.prototype), _.prototype.constructor = _, Pa.prototype["delete"] = Qa, Pa.prototype.get = Sa, Pa.prototype.has = Ta, Pa.prototype.set = Ua, Va.prototype.push = Ya, he.Cache = Pa, V.after = Wd, V.ary = Xd, V.assign = $g, V.at = Ad, V.before = Yd, V.bind = Zd, V.bindAll = $d, V.bindKey = _d, V.callback = zf, V.chain = rd, V.chunk = Jc, V.compact = Kc, V.constant = Af, V.countBy = Qg, V.create = Me, V.curry = ae, V.curryRight = be, V.debounce = ce, V.defaults = Ne, V.defer = de, V.delay = ee, V.difference = Lc, V.drop = Mc, V.dropRight = Nc, V.dropRightWhile = Oc, V.dropWhile = Pc, V.fill = Qc, V.filter = Dd, V.flatten = Uc, V.flattenDeep = Vc, V.flow = fe, V.flowRight = ge, V.forEach = Hd, V.forEachRight = Id, V.forIn = Qe, V.forInRight = Re, V.forOwn = Se, V.forOwnRight = Te, V.functions = Ue, V.groupBy = Rg, V.indexBy = Sg, V.initial = Xc, V.intersection = Yc, V.invert = We, V.invoke = Jd, V.keys = _g, V.keysIn = Xe, V.map = Kd, V.mapValues = Ye, +V.matches = Cf, V.matchesProperty = Df, V.memoize = he, V.merge = ah, V.mixin = Ef, V.negate = ie, V.omit = Ze, V.once = je, V.pairs = $e, V.partial = ke, V.partialRight = le, V.partition = Vg, V.pick = _e, V.pluck = Ld, V.property = Hf, V.propertyOf = If, V.pull = _c, V.pullAt = ad, V.range = Jf, V.rearg = me, V.reject = Od, V.remove = bd, V.rest = cd, V.shuffle = Qd, V.slice = dd, V.sortBy = Td, V.sortByAll = Ud, V.spread = ne, V.take = gd, V.takeRight = hd, V.takeRightWhile = id, V.takeWhile = jd, V.tap = sd, V.throttle = oe, V.thru = td, V.times = Kf, V.toArray = Ke, V.toPlainObject = Le, V.transform = bf, V.union = kd, V.uniq = ld, V.unzip = md, V.values = cf, V.valuesIn = df, V.where = Vd, V.without = nd, V.wrap = pe, V.xor = od, V.zip = pd, V.zipObject = qd, V.backflow = ge, V.collect = Kd, V.compose = ge, V.each = Hd, V.eachRight = Id, V.extend = $g, V.iteratee = zf, V.methods = Ue, V.object = qd, V.select = Dd, V.tail = cd, V.unique = ld, Ef(V, V), V.attempt = yf, V.camelCase = bh, +V.capitalize = ff, V.clone = qe, V.cloneDeep = re, V.deburr = gf, V.endsWith = hf, V.escape = jf, V.escapeRegExp = kf, V.every = Cd, V.find = Ed, V.findIndex = Rc, V.findKey = Oe, V.findLast = Fd, V.findLastIndex = Sc, V.findLastKey = Pe, V.findWhere = Gd, V.first = Tc, V.has = Ve, V.identity = Bf, V.includes = Bd, V.indexOf = Wc, V.isArguments = se, V.isArray = Xg, V.isBoolean = te, V.isDate = ue, V.isElement = ve, V.isEmpty = we, V.isEqual = xe, V.isError = ye, V.isFinite = Yg, V.isFunction = ze, V.isMatch = Be, V.isNaN = Ce, V.isNative = De, V.isNull = Ee, V.isNumber = Fe, V.isObject = Ae, V.isPlainObject = Zg, V.isRegExp = Ge, V.isString = He, V.isTypedArray = Ie, V.isUndefined = Je, V.kebabCase = ch, V.last = Zc, V.lastIndexOf = $c, V.max = Tg, V.min = Ug, V.noConflict = Ff, V.noop = Gf, V.now = Wg, V.pad = lf, V.padLeft = mf, V.padRight = nf, V.parseInt = of, V.random = ef, V.reduce = Md, V.reduceRight = Nd, V.repeat = pf, V.result = af, V.runInContext = u, V.size = Rd, V.snakeCase = dh, +V.some = Sd, V.sortedIndex = ed, V.sortedLastIndex = fd, V.startCase = eh, V.startsWith = qf, V.template = rf, V.trim = sf, V.trimLeft = tf, V.trimRight = uf, V.trunc = vf, V.unescape = wf, V.uniqueId = Lf, V.words = xf, V.all = Cd, V.any = Sd, V.contains = Bd, V.detect = Ed, V.foldl = Md, V.foldr = Nd, V.head = Tc, V.include = Bd, V.inject = Md, Ef(V, function() { var a = {}; -return yd(q, function(b, c) { -q.prototype[c] || (a[c] = b); +return Cb(V, function(b, c) { +V.prototype[c] || (a[c] = b); }), a; -}(), !1), q.first = wb, q.last = Bb, q.sample = mb, q.take = wb, q.head = wb, yd(q, function(a, b) { -var c = "sample" !== b; -q.prototype[b] || (q.prototype[b] = function(b, d) { -var e = this.__chain__, f = a(this.__wrapped__, b, d); -return e || null != b && (!d || c && "function" == typeof b) ? new r(f, e) :f; -}); -}), q.VERSION = "2.4.1", q.prototype.chain = rc, q.prototype.toString = sc, q.prototype.value = tc, q.prototype.valueOf = tc, ud([ "join", "pop", "shift" ], function(a) { -var b = Fc[a]; -q.prototype[a] = function() { -var a = this.__chain__, c = b.apply(this.__wrapped__, arguments); -return a ? new r(c, a) :c; -}; -}), ud([ "push", "reverse", "sort", "unshift" ], function(a) { -var b = Fc[a]; -q.prototype[a] = function() { -return b.apply(this.__wrapped__, arguments), this; -}; -}), ud([ "concat", "slice", "splice" ], function(a) { -var b = Fc[a]; -q.prototype[a] = function() { -return new r(b.apply(this.__wrapped__, arguments), this.__chain__); -}; -}), hd.spliceObjects || ud([ "pop", "shift", "splice" ], function(a) { -var b = Fc[a], c = "splice" == a; -q.prototype[a] = function() { -var a = this.__chain__, d = this.__wrapped__, e = b.apply(d, arguments); -return 0 === d.length && delete d[0], a || c ? new r(e, a) :e; -}; -}), q; -} -var p, q = [], r = [], s = 0, t = {}, u = +new Date() + "", v = 75, w = 40, x = " \f \ufeff\n\r\u2028\u2029 ᠎              ", y = /\b__p \+= '';/g, z = /\b(__p \+=) '' \+/g, A = /(__e\(.*?\)|\b__t\)) \+\n'';/g, B = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g, C = /\w*$/, D = /^\s*function[ \n\r\t]+\w/, E = /<%=([\s\S]+?)%>/g, F = RegExp("^[" + x + "]*0+(?=.$)"), G = /($^)/, H = /\bthis\b/, I = /['\n\r\t\u2028\u2029\\]/g, J = [ "Array", "Boolean", "Date", "Error", "Function", "Math", "Number", "Object", "RegExp", "String", "_", "attachEvent", "clearTimeout", "isFinite", "isNaN", "parseInt", "setTimeout" ], K = [ "constructor", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf" ], L = 0, M = "[object Arguments]", N = "[object Array]", O = "[object Boolean]", P = "[object Date]", Q = "[object Error]", R = "[object Function]", S = "[object Number]", T = "[object Object]", U = "[object RegExp]", V = "[object String]", W = {}; -W[R] = !1, W[M] = W[N] = W[O] = W[P] = W[S] = W[T] = W[U] = W[V] = !0; -var X = { +}(), !1), V.sample = Pd, V.prototype.sample = function(a) { +return this.__chain__ || null != a ? this.thru(function(b) { +return Pd(b, a); +}) :Pd(this.value()); +}, V.VERSION = w, $a([ "bind", "bindKey", "curry", "curryRight", "partial", "partialRight" ], function(a) { +V[a].placeholder = V; +}), $a([ "filter", "map", "takeWhile" ], function(a, b) { +var c = b == K, d = b == M; +_.prototype[a] = function(a, e) { +var f = this.clone(), g = f.__filtered__, h = f.__iteratees__ || (f.__iteratees__ = []); +return f.__filtered__ = g || c || d && f.__dir__ < 0, h.push({ +iteratee:pc(a, e, 3), +type:b +}), f; +}; +}), $a([ "drop", "take" ], function(a, b) { +var c = "__" + a + "Count__", d = a + "While"; +_.prototype[a] = function(d) { +d = null == d ? 1 :wg(ig(d) || 0, 0); +var e = this.clone(); +if (e.__filtered__) { +var f = e[c]; +e[c] = b ? xg(f, d) :f + d; +} else { +var g = e.__views__ || (e.__views__ = []); +g.push({ +size:d, +type:a + (e.__dir__ < 0 ? "Right" :"") +}); +} +return e; +}, _.prototype[a + "Right"] = function(b) { +return this.reverse()[a](b).reverse(); +}, _.prototype[a + "RightWhile"] = function(a, b) { +return this.reverse()[d](a, b).reverse(); +}; +}), $a([ "first", "last" ], function(a, b) { +var c = "take" + (b ? "Right" :""); +_.prototype[a] = function() { +return this[c](1).value()[0]; +}; +}), $a([ "initial", "rest" ], function(a, b) { +var c = "drop" + (b ? "" :"Right"); +_.prototype[a] = function() { +return this[c](1); +}; +}), $a([ "pluck", "where" ], function(a, b) { +var c = b ? "filter" :"map", d = b ? Kb :Ob; +_.prototype[a] = function(a) { +return this[c](d(a)); +}; +}), _.prototype.compact = function() { +return this.filter(Bf); +}, _.prototype.dropWhile = function(a, b) { +var c; +return a = pc(a, b, 3), this.filter(function(b, d, e) { +return c || (c = !a(b, d, e)); +}); +}, _.prototype.reject = function(a, b) { +return a = pc(a, b, 3), this.filter(function(b, c, d) { +return !a(b, c, d); +}); +}, _.prototype.slice = function(a, b) { +a = null == a ? 0 :+a || 0; +var c = 0 > a ? this.takeRight(-a) :this.drop(a); +return "undefined" != typeof b && (b = +b || 0, c = 0 > b ? c.dropRight(-b) :c.take(b - a)), c; +}, _.prototype.toArray = function() { +return this.drop(0); +}, Cb(_.prototype, function(a, b) { +var c = V[b], d = /^(?:first|last)$/.test(b); +V.prototype[b] = function() { +var b = this.__wrapped__, e = arguments, f = this.__chain__, g = !!this.__actions__.length, h = b instanceof _, i = h && !g; +if (d && !f) return i ? a.call(b) :c.call(V, this.value()); +var j = function(a) { +var b = [ a ]; +return kg.apply(b, e), c.apply(V, b); +}; +if (h || Xg(b)) { +var k = i ? b :new _(this), l = a.apply(k, e); +if (!d && (g || l.__actions__)) { +var m = l.__actions__ || (l.__actions__ = []); +m.push({ +func:td, +args:[ j ], +thisArg:V +}); +} +return new Z(l, f); +} +return this.thru(j); +}; +}), $a([ "concat", "join", "pop", "push", "shift", "sort", "splice", "unshift" ], function(a) { +var b = Wf[a], c = /^(?:push|sort|unshift)$/.test(a) ? "tap" :"thru", d = /^(?:join|pop|shift)$/.test(a); +V.prototype[a] = function() { +var a = arguments; +return d && !this.__chain__ ? b.apply(this.value(), a) :this[c](function(c) { +return b.apply(c, a); +}); +}; +}), _.prototype.clone = Ma, _.prototype.reverse = Na, _.prototype.value = Oa, V.prototype.chain = ud, V.prototype.commit = vd, V.prototype.plant = wd, V.prototype.reverse = xd, V.prototype.toString = yd, V.prototype.run = V.prototype.toJSON = V.prototype.valueOf = V.prototype.value = zd, V.prototype.collect = V.prototype.map, V.prototype.head = V.prototype.first, V.prototype.select = V.prototype.filter, V.prototype.tail = V.prototype.rest, V; +} +var v, w = "3.2.0", x = 1, y = 2, z = 4, A = 8, B = 16, C = 32, D = 64, E = 128, F = 256, G = 30, H = "...", I = 150, J = 16, K = 0, L = 1, M = 2, N = "Expected a function", O = "__lodash_placeholder__", P = "[object Arguments]", Q = "[object Array]", R = "[object Boolean]", S = "[object Date]", T = "[object Error]", U = "[object Function]", V = "[object Map]", W = "[object Number]", X = "[object Object]", Y = "[object RegExp]", Z = "[object Set]", $ = "[object String]", _ = "[object WeakMap]", aa = "[object ArrayBuffer]", ba = "[object Float32Array]", ca = "[object Float64Array]", da = "[object Int8Array]", ea = "[object Int16Array]", fa = "[object Int32Array]", ga = "[object Uint8Array]", ha = "[object Uint8ClampedArray]", ia = "[object Uint16Array]", ja = "[object Uint32Array]", ka = /\b__p \+= '';/g, la = /\b(__p \+=) '' \+/g, ma = /(__e\(.*?\)|\b__t\)) \+\n'';/g, na = /&(?:amp|lt|gt|quot|#39|#96);/g, oa = /[&<>"'`+"`"+`]/g, pa = RegExp(na.source), qa = RegExp(oa.source), ra = /<%-([\s\S]+?)%>/g, sa = /<%([\s\S]+?)%>/g, ta = /<%=([\s\S]+?)%>/g, ua = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g, va = /\w*$/, wa = /^\s*function[ \n\r\t]+\w/, xa = /^0[xX]/, ya = /^\[object .+?Constructor\]$/, za = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g, Aa = /($^)/, Ba = /[.*+?^${}()|[\]\/\\]/g, Ca = RegExp(Ba.source), Da = /\bthis\b/, Ea = /['\n\r\u2028\u2029\\]/g, Fa = function() { +var a = "[A-Z\\xc0-\\xd6\\xd8-\\xde]", b = "[a-z\\xdf-\\xf6\\xf8-\\xff]+"; +return RegExp(a + "{2,}(?=" + a + b + ")|" + a + "?" + b + "|" + a + "+|[0-9]+", "g"); +}(), Ga = " \f \ufeff\n\r\u2028\u2029 ᠎              ", Ha = [ "Array", "ArrayBuffer", "Date", "Error", "Float32Array", "Float64Array", "Function", "Int8Array", "Int16Array", "Int32Array", "Math", "Number", "Object", "RegExp", "Set", "String", "_", "clearTimeout", "document", "isFinite", "parseInt", "setTimeout", "TypeError", "Uint8Array", "Uint8ClampedArray", "Uint16Array", "Uint32Array", "WeakMap", "window", "WinRTError" ], Ia = -1, Ja = {}; +Ja[ba] = Ja[ca] = Ja[da] = Ja[ea] = Ja[fa] = Ja[ga] = Ja[ha] = Ja[ia] = Ja[ja] = !0, Ja[P] = Ja[Q] = Ja[aa] = Ja[R] = Ja[S] = Ja[T] = Ja[U] = Ja[V] = Ja[W] = Ja[X] = Ja[Y] = Ja[Z] = Ja[$] = Ja[_] = !1; +var Ka = {}; +Ka[P] = Ka[Q] = Ka[aa] = Ka[R] = Ka[S] = Ka[ba] = Ka[ca] = Ka[da] = Ka[ea] = Ka[fa] = Ka[W] = Ka[X] = Ka[Y] = Ka[$] = Ka[ga] = Ka[ha] = Ka[ia] = Ka[ja] = !0, Ka[T] = Ka[U] = Ka[V] = Ka[Z] = Ka[_] = !1; +var La = { leading:!1, maxWait:0, trailing:!1 -}, Y = { -configurable:!1, -enumerable:!1, -value:null, -writable:!1 -}, Z = { -args:"", -array:null, -bottom:"", -firstArg:"", -init:"", -keys:null, -loop:"", -shadowedProps:null, -support:null, -top:"", -useHas:!1 -}, $ = { -"boolean":!1, +}, Ma = { +"À":"A", +"Á":"A", +"Â":"A", +"Ã":"A", +"Ä":"A", +"Å":"A", +"à":"a", +"á":"a", +"â":"a", +"ã":"a", +"ä":"a", +"å":"a", +"Ç":"C", +"ç":"c", +"Ð":"D", +"ð":"d", +"È":"E", +"É":"E", +"Ê":"E", +"Ë":"E", +"è":"e", +"é":"e", +"ê":"e", +"ë":"e", +"Ì":"I", +"Í":"I", +"Î":"I", +"Ï":"I", +"ì":"i", +"í":"i", +"î":"i", +"ï":"i", +"Ñ":"N", +"ñ":"n", +"Ò":"O", +"Ó":"O", +"Ô":"O", +"Õ":"O", +"Ö":"O", +"Ø":"O", +"ò":"o", +"ó":"o", +"ô":"o", +"õ":"o", +"ö":"o", +"ø":"o", +"Ù":"U", +"Ú":"U", +"Û":"U", +"Ü":"U", +"ù":"u", +"ú":"u", +"û":"u", +"ü":"u", +"Ý":"Y", +"ý":"y", +"ÿ":"y", +"Æ":"Ae", +"æ":"ae", +"Þ":"Th", +"þ":"th", +"ß":"ss" +}, Na = { +"&":"&", +"<":"<", +">":">", +'"':""", +"'":"'", +"`+"`"+`":"`" +}, Oa = { +"&":"&", +"<":"<", +">":">", +""":'"', +"'":"'", +"`":"`+"`"+`" +}, Pa = { "function":!0, -object:!0, -number:!1, -string:!1, -undefined:!1 -}, _ = { +object:!0 +}, Qa = { "\\":"\\", "'":"'", "\n":"n", "\r":"r", -" ":"t", "\u2028":"u2028", "\u2029":"u2029" -}, aa = $[typeof window] && window || this, ba = $[typeof exports] && exports && !exports.nodeType && exports, ca = $[typeof module] && module && !module.nodeType && module, da = ca && ca.exports === ba && ba, ea = $[typeof global] && global; -!ea || ea.global !== ea && ea.window !== ea || (aa = ea); -var fa = o(); -"function" == typeof define && "object" == typeof define.amd && define.amd ? (aa._ = fa, define(function() { -return fa; -})) :ba && ca ? da ? (ca.exports = fa)._ = fa :ba._ = fa :aa._ = fa; +}, Ra = Pa[typeof window] && window !== (this && this.window) ? window :this, Sa = Pa[typeof exports] && exports && !exports.nodeType && exports, Ta = Pa[typeof module] && module && !module.nodeType && module, Ua = Sa && Ta && "object" == typeof global && global; +!Ua || Ua.global !== Ua && Ua.window !== Ua && Ua.self !== Ua || (Ra = Ua); +var Va = Ta && Ta.exports === Sa && Sa, Wa = u(); +"function" == typeof define && "object" == typeof define.amd && define.amd ? (Ra._ = Wa, define(function() { +return Wa; +})) :Sa && Ta ? Va ? (Ta.exports = Wa)._ = Wa :Sa._ = Wa :Ra._ = Wa; }.call(this), function() { function a(a, b) { b = b || { @@ -31369,26 +32208,42 @@ var HawtioMainNav; !function(a) { function b(a) { -return new h(a); +return new j(a); } function c(a) { return "isValid" in a ? _.isFunction(a.isValid) ? a.isValid() :!1 :!0; } function d(a, b) { !("isSelected" in b) && "href" in b && (b.isSelected = function() { -return a.path() === b.href() || 0 === a.path().indexOf(b.href() + "/"); +var a = $("").attr("href", b.href()), c = new URI(a[0].href), d = new URI(), e = d.path(), f = d.query(!0), g = f["main-tab"], h = f["sub-tab"], i = !1; +return i = b.isSubTab ? h ? h === b.id :_.startsWith(e, c.path()) :g ? g === b.id :_.startsWith(e, c.path()); }); } function e(a, b, d, e, f) { if (c(f)) { var g = d.$new(); -g.item = f; +f.hide = function() { +return f.show && !f.show(); +}, g.item = f; var h = null; h = _.isFunction(f.template) ? f.template() :a.get("templates/main-nav/navItem.html"), e.append(b(h)(g)); } } +function f(a) { +var b = []; +return a.forEach(function(a) { +g(a, b); +}), b; +} +function g(a, b) { +if (!("rank" in a) || 0 === b.length) return void b.push(a); +var c = _.findIndex(b, function(b) { +return "rank" in b && a.rank > b.rank ? !0 :void 0; +}); +"rank" in b[0] || (c = 0), 0 > c ? b.push(a) :b.splice(c, 0, a); +} a.pluginName = "hawtio-nav"; -var f = Logger.get(a.pluginName), g = function() { +var h = Logger.get(a.pluginName), i = function() { function a() {} return Object.defineProperty(a, "ADD", { get:function() { @@ -31416,8 +32271,8 @@ enumerable:!0, configurable:!0 }), a; }(); -a.Actions = g; -var h = function() { +a.Actions = i; +var j = function() { function b(a) { this.items = [], this.root = a; } @@ -31505,7 +32360,7 @@ this.root.dispatchEvent(f); }, b; }(); a.createRegistry = b; -var i = function() { +var k = function() { function a() { this.self = { id:"" @@ -31521,6 +32376,8 @@ var e = c.join("/"); return e; }, a.prototype.id = function(a) { return this.self.id = a, this; +}, a.prototype.rank = function(a) { +return this.self.rank = a, this; }, a.prototype.title = function(a) { return this.self.title = a, this; }, a.prototype.page = function(a) { @@ -31537,26 +32394,30 @@ return this.self.click = a, this; return this.self.isSelected = a, this; }, a.prototype.isValid = function(a) { return this.self.isValid = a, this; +}, a.prototype.show = function(a) { +return this.self.show = a, this; }, a.prototype.template = function(a) { return this.self.template = a, this; +}, a.prototype.defaultPage = function(a) { +return this.self.defaultPage = a, this; }, a.prototype.tabs = function(a) { for (var b = [], c = 1; c < arguments.length; c++) b[c - 1] = arguments[c]; return this.self.tabs = _.union(this.self.tabs, [ a ], b), this; -}, a.prototype.subPath = function(b, c, d, e, f) { -var g = this.self; +}, a.prototype.subPath = function(b, c, d, e, f, g) { +var h = this.self; this.self.tabs || (this.self.tabs = []); -var h = { +var i = { id:"", title:function() { return b; }, href:function() { -return g.href ? a.join(g.href(), c) :c; +return h.href ? a.join(h.href(), c) :c; } }; -return _.isUndefined(d) || (h.page = function() { +return _.isUndefined(d) || (i.page = function() { return d; -}), _.isUndefined(e) || (h.reload = e), _.isUndefined(f) || (h.isValid = f), this.self.tabs.push(h), this; +}), _.isUndefined(e) || (i.rank = e), _.isUndefined(f) || (i.reload = f), _.isUndefined(g) || (i.isValid = g), this.self.tabs.push(i), this; }, a.prototype.build = function() { var a = _.cloneDeep(this.self); return this.self = { @@ -31564,34 +32425,124 @@ id:"" }, a; }, a; }(); -a.NavItemBuilderImpl = i, a.createBuilder = function() { +a.NavItemBuilderImpl = k, a.createBuilder = function() { return new a.NavItemBuilderImpl(); }; -var j = angular.module(a.pluginName, []); -a._module = j, j.constant("layoutFull", "templates/main-nav/layoutFull.html"), j.controller("HawtioNav.ViewController", [ "$scope", "$route", "$location", "layoutFull", "viewRegistry", function(a, b, c, d, e) { +var l = angular.module(a.pluginName, [ "ngRoute" ]); +a._module = l, l.constant("layoutFull", "templates/main-nav/layoutFull.html"), l.config([ "$routeProvider", function(a) { +a.otherwise({ +templateUrl:"templates/main-nav/welcome.html" +}); +} ]), l.controller("HawtioNav.WelcomeController", [ "$scope", "$location", "WelcomePageRegistry", "HawtioNav", "$timeout", function(a, b, c, d, e) { +function g(a) { +if (a && a.href) { +var c = new URI(a.href()), d = _.merge(b.search(), c.query(!0)); +h.debug("Going to item id: ", a.id, " href: ", c.path(), " query: ", d), e(function() { +b.path(c.path()).search(d); +}, 10); +} +} +function i() { +var a = []; +d.iterate(function(b) { +var c = b.isValid || function() { +return !0; +}, d = b.show || function() { +return !0; +}; +c() && d() && a.push(b); +}); +var b = f(a); +g(b[0]); +} +e(function() { +function a() { +0 === c.pages.length && (h.debug("No welcome pages, going to first available nav"), i()); +var a = _.sortBy(c.pages, function(a) { +return a.rank; +}), b = _.find(a, function(a) { +return "isValid" in a ? a.isValid() :!0; +}); +b ? g(item) :i(); +} +function e(b) { +if (0 === b.length) return void a(); +var c = b.pop(), d = b; +if (h.debug("Trying candidate: ", c, " remaining: ", d), !c) return void a(); +var f = c.defaultPage.isValid; +if (f) { +var i = function() { +g(c); +}, j = function() { +e(d); +}; +try { +f(i, j); +} catch (k) { +h.debug("Failed to eval item: ", c.id, " error: ", k), j(); +} +} else e(d); +} +var f = b.search(); +if (f.tab) { +var j, k = f.tab; +if (d.iterate(function(a) { +j || a.id !== k || (j = a); +}), j) return void g(j); +} +var l = []; +d.iterate(function(a) { +if ("defaultPage" in a) { +var b = a.defaultPage; +if (!("rank" in b)) return void l.push(a); +var c = _.findIndex(l, function(b) { +return "rank" in b && a.rank > b.rank ? !0 :void 0; +}); +0 > c ? l.push(a) :l.splice(c, 0, a); +} +}), e(l); +}, 500); +} ]), l.controller("HawtioNav.ViewController", [ "$scope", "$route", "$location", "layoutFull", "viewRegistry", function(a, b, c, d, e) { +function f(a) { +var b = void 0; +if (!a || 0 === _.keys(a).length) return void h.debug("No query, skipping query matching"); +var c = _.keys(e), d = _.filter(c, function(a) { +return "{" === a.charAt(0); +}); +return d.forEach(function(c) { +if (!b) try { +var d = angular.fromJson(c); +_.isObject(d) && _.merge(d, a, function(a, d) { +a && (b = a === d ? e[c] :void 0); +}); +} catch (f) { +h.debug("Unable to parse json: ", c); +} +}), b; +} function g(a) { var b = void 0; return _.forIn(e, function(c, d) { if (!b) try { var e = new RegExp(d, ""); e.exec(a) && (b = c); -} catch (g) { -f.debug("Invalid RegExp " + text + " for viewRegistry value: " + c); +} catch (f) { +h.debug("Invalid RegExp " + text + " for viewRegistry value: " + c); } }), b; } -function h() { -var b = null, e = c.search(), h = e.tab; -if (angular.isString(h) && (b = g(h)), !b) { +function i() { +var b = null, e = c.search(); +if (b = f(e), b && h.debug("View partial matched on query"), !b) { var i = c.path(); -i && (b = g(i)); +i && (b = g(i), b && h.debug("View partial matched on path name")); } -return b || (b = d), a.viewPartial = b, f.debug("Using view partial: " + b), b; +return b || (b = d, h.debug("Using default view partial")), a.viewPartial = b, h.debug("Using view partial: " + b), b; } -h(), a.$on("$routeChangeSuccess", function() { -h(); +i(), a.$on("$routeChangeSuccess", function() { +i(); }); -} ]), j.run([ "HawtioNav", "$rootScope", function(b, c) { +} ]), l.run([ "HawtioNav", "$rootScope", "$route", function(b, c, d) { b.on(a.Actions.CHANGED, "$apply", function() { c.$$phase || c.$apply(); }), b.on(a.Actions.ADD, "$apply", function(a) { @@ -31602,61 +32553,76 @@ c.$apply(); } catch (d) {} b && b(a); }; -}), f.debug("loaded"); +}), d.reload(), h.debug("loaded"); } ]), hawtioPluginLoader.addModule(a.pluginName), hawtioPluginLoader.addModule("ngRoute"), a._module.directive("hawtioSubTabs", [ "HawtioNav", "$templateCache", "$compile", "$location", "$rootScope", function(a, b, c) { return { restrict:"A", controller:[ "$scope", function(b) { -b.nav = a, b.redraw = !0, b.$watch("nav.selected()", function(a, c) { -a !== c && (b.redraw = !0); +b.nav = a, b.redraw = !0, b.$watch("nav.selected().length", function() { +b.redraw = !0; +}), b.$watchCollection("nav.selected()", function() { +b.redraw = !0; }), b.$on("hawtio-nav-redraw", function() { b.redraw = !0; }); } ], -link:function(d, f, g) { +link:function(d, g, h) { d.$watch("redraw", function() { -f.empty(); -var h = a.selected(); -if (h && h.tabs) { -if (g.showHeading) { -var i = angular.extend({}, h, { +g.empty(); +var i = a.selected(); +if (i && i.tabs) { +if (h.showHeading) { +var j = angular.extend({}, i, { template:function() { return b.get("templates/main-nav/subTabHeader.html"); } }); -e(b, c, d, f, i); +e(b, c, d, g, j); } -h.tabs.forEach(function(a) { -e(b, c, d, f, a); +var k = f(i.tabs); +k.forEach(function(a) { +e(b, c, d, g, a); }); } d.redraw = !1; }); } }; -} ]), a._module.directive("hawtioMainNav", [ "HawtioNav", "$templateCache", "$compile", "$location", "$rootScope", function(b, f, g, h) { -var i = { +} ]), a._module.directive("hawtioMainNav", [ "HawtioNav", "$templateCache", "$compile", "$location", "$rootScope", function(b, f, h, i) { +var j = { nav:{}, numKeys:0, numValid:0 -}, j = function(a) { -c(a) && (i.numValid = i.numValid + 1); +}, k = function(a) { +c(a) && (j.numValid = j.numValid + 1); }; -return b.on(a.Actions.ADD, "isSelectedEnricher", function(a) { -d(h, a), a.tabs && a.tabs.forEach(function(a) { -d(h, a); +return b.on(a.Actions.ADD, "subTabEnricher", function(a) { +a.tabs && a.tabs.length > 0 && a.tabs.forEach(function(b) { +b.isSubTab = !0, b.oldHref || (b.oldHref = b.href, b.href = function() { +var c = new URI(b.oldHref()); +return c.setSearch("main-tab", a.id), c.setSearch("sub-tab", b.id), c.search(_.merge(new URI().query(!0), c.query(!0))), c.toString(); +}); +}); +}), b.on(a.Actions.ADD, "hrefEnricher", function(a) { +a.isSubTab = !1, a.href && !a.oldHref && (a.oldHref = a.href, a.href = function() { +var b = new URI(a.oldHref()); +return b.setSearch("main-tab", a.id), b.search(_.merge(new URI().query(!0), b.query(!0))), b.removeSearch("sub-tab"), b.toString(); +}); +}), b.on(a.Actions.ADD, "isSelectedEnricher", function(a) { +d(i, a), a.tabs && a.tabs.forEach(function(a) { +d(i, a); }); }), b.on(a.Actions.ADD, "PrimaryController", function(a) { -i.nav[a.id] = a; +j.nav[a.id] = a; }), b.on(a.Actions.REMOVE, "PrimaryController", function(a) { -delete i.nav[a.id]; +delete j.nav[a.id]; }), b.on(a.Actions.CHANGED, "PrimaryController", function(a) { -i.numKeys = a.length, i.numValid = 0, a.forEach(j); +j.numKeys = a.length, j.numValid = 0, a.forEach(k); }), { restrict:"A", replace:!1, controller:[ "$scope", "$element", "$attrs", function(a) { -a.config = i, a.redraw = !0, a.$watch("config.numKeys", function(b, c) { +a.config = j, a.redraw = !0, a.$watch("config.numKeys", function(b, c) { b !== c && (a.redraw = !0); }), a.$watch("config.numValid", function(b, c) { b !== c && (a.redraw = !0); @@ -31666,18 +32632,28 @@ a.redraw = !0; } ], link:function(a, c) { a.$watch(function() { -var d = i.numValid; -i.numValid = 0, b.iterate(j), i.numValid !== d && (a.redraw = !0), a.redraw ? (a.redraw = !1, c.empty(), b.iterate(function(b) { -"context" in b && b.context && e(f, g, a, c, b); -}), b.iterate(function(b) { -b.context || e(f, g, a, c, b); -})) :(i.numValid = 0, b.iterate(j)); +var d = j.numValid; +if (j.numValid = 0, b.iterate(k), j.numValid !== d && (a.redraw = !0), a.redraw) { +a.redraw = !1, c.empty(); +var i = []; +b.iterate(function(a) { +"context" in a && a.context && g(a, i); +}), i.forEach(function(b) { +e(f, h, a, c, b); +}); +var l = []; +b.iterate(function(a) { +a.context || g(a, l); +}), l.forEach(function(b) { +e(f, h, a, c, b); +}); +} else j.numValid = 0, b.iterate(k); }); } }; } ]), a._module.provider("HawtioNavBuilder", [ function() { function b(a, b) { -f.debug("Setting route: ", b.href(), " to template URL: ", b.page()); +h.debug("Setting route: ", b.href(), " to template URL: ", b.page()); var c = { templateUrl:b.page() }; @@ -31687,11 +32663,11 @@ this.$get = function() { return {}; }, this.create = function() { return a.createBuilder(); -}, this.join = i.join, this.configureRouting = function(a, c) { +}, this.join = k.join, this.configureRouting = function(a, c) { if (_.isUndefined(c.page)) { if (c.tabs) { var d = _.first(c.tabs).href; -d && (f.debug("Setting route: ", c.href(), " to redirect to ", d()), a.when(c.href(), { +d && (h.debug("Setting route: ", c.href(), " to redirect to ", d()), a.when(c.href(), { reloadOnSearch:c.reload, redirectTo:d() })); @@ -31720,12 +32696,16 @@ getLabels:function() { return []; } }; +} ]), a._module.factory("WelcomePageRegistry", [ function() { +return { +pages:[] +}; } ]), a._module.factory("HawtioNav", [ "$window", "$rootScope", function() { var b = a.createRegistry(window); return b; } ]); }(HawtioMainNav || (HawtioMainNav = {})), angular.module("hawtio-nav").run([ "$templateCache", function(a) { -a.put("templates/main-nav/layoutFull.html", "
    \n\n\n"), a.put("templates/main-nav/navItem.html", '
  • \n {{item.title()}}\n
  • \n'), a.put("templates/main-nav/subTabHeader.html", '
  • \n {{item.title()}}\n
  • \n'); +a.put("templates/main-nav/layoutFull.html", "
    \n\n\n"), a.put("templates/main-nav/layoutTest.html", "
    \n

    Test Layout

    \n
    \n\n\n
    \n
    \n\n\n"), a.put("templates/main-nav/navItem.html", '
  • \n \n
  • \n'), a.put("templates/main-nav/subTabHeader.html", '
  • \n {{item.title()}}\n
  • \n'), a.put("templates/main-nav/welcome.html", '
    \n'); } ]); var HawtioExtensionService; @@ -59500,7 +60480,7 @@ var _views_project_nav_html = []byte(`
    - +
    @@ -60024,7 +61004,7 @@ var _views_images_html = []byte(`

    {{image.dockerImageReference | imageName}} ({{image.metadata.name}})

    Created:
    -
    Created from: Build {{build.metadata.labels.buildconfig}} ({{build.metadata.name.substr(0, 10)}}) +
    Created from: Build {{build.metadata.labels.buildconfig}} ({{build.metadata.name.substr(0, 10)}})
    @@ -60312,7 +61292,7 @@ func views_project_html() ([]byte, error) { var _views_projects_html = []byte(`

    Projects

    {{emptyMessage}}
    diff --git a/pkg/assets/handlers.go b/pkg/assets/handlers.go index 921fd50e266d..5a0edd9c7632 100644 --- a/pkg/assets/handlers.go +++ b/pkg/assets/handlers.go @@ -1,6 +1,7 @@ package assets import ( + "bytes" "compress/gzip" "encoding/hex" "fmt" @@ -76,20 +77,24 @@ func CacheControlHandler(version string, h http.Handler) http.Handler { }) } -func HTML5ModeHandler(h http.Handler) http.Handler { +// HTML5ModeHandler will serve any static assets we know about, all other paths +// are assumed to be HTML5 paths for the console application and index.html will +// be served. +// contextRoot must contain leading and trailing slashes, e.g. /console/ +func HTML5ModeHandler(contextRoot string, h http.Handler) (http.Handler, error) { + b, err := Asset("index.html") + if err != nil { + return nil, err + } + b = bytes.Replace(b, []byte(``), []byte(fmt.Sprintf(``, contextRoot)), 1) + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if _, err := Asset(strings.TrimPrefix(r.URL.Path, "/")); err != nil { - b, err := Asset("index.html") - if err != nil { - http.Error(w, "Failed to read index.html", http.StatusInternalServerError) - return - } else { - w.Write(b) - return - } + w.Write(b) + return } h.ServeHTTP(w, r) - }) + }), nil } var configTemplate = template.Must(template.New("webConsoleConfig").Parse(` @@ -134,7 +139,7 @@ type WebConsoleConfig struct { func GeneratedConfigHandler(config WebConsoleConfig, h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/config.js" { + if strings.TrimPrefix(r.URL.Path, "/") == "config.js" { w.Header().Add("Cache-Control", "no-cache, no-store") if err := configTemplate.Execute(w, config); err != nil { glog.Errorf("Unable to render config template: %v", err) diff --git a/pkg/cmd/server/api/validation/validation.go b/pkg/cmd/server/api/validation/validation.go index 320be4153eb3..99353fbf7173 100644 --- a/pkg/cmd/server/api/validation/validation.go +++ b/pkg/cmd/server/api/validation/validation.go @@ -126,9 +126,10 @@ func ValidateAssetConfig(config *api.AssetConfig) errs.ValidationErrorList { if len(urlErrs) > 0 { allErrs = append(allErrs, urlErrs...) } - // TODO: remove once this is configurable - if urlObj != nil && urlObj.Path != "/console" { - allErrs = append(allErrs, errs.NewFieldInvalid("publicURL", config.PublicURL, "must be located at the /console path")) + if urlObj != nil { + if !strings.HasSuffix(urlObj.Path, "/") { + allErrs = append(allErrs, errs.NewFieldInvalid("publicURL", config.PublicURL, "must have a trailing slash in path")) + } } return allErrs @@ -141,6 +142,23 @@ func ValidateMasterConfig(config *api.MasterConfig) errs.ValidationErrorList { if config.AssetConfig != nil { allErrs = append(allErrs, ValidateAssetConfig(config.AssetConfig).Prefix("assetConfig")...) + colocated := config.AssetConfig.ServingInfo.BindAddress == config.ServingInfo.BindAddress + if colocated { + publicURL, _ := url.Parse(config.AssetConfig.PublicURL) + if publicURL.Path == "/" { + allErrs = append(allErrs, errs.NewFieldInvalid("assetConfig.publicURL", config.AssetConfig.PublicURL, "path can not be / when colocated with master API")) + } + } + + if config.OAuthConfig != nil && config.OAuthConfig.AssetPublicURL != config.AssetConfig.PublicURL { + allErrs = append(allErrs, + errs.NewFieldInvalid("assetConfig.publicURL", config.AssetConfig.PublicURL, "must match oauthConfig.assetPublicURL"), + errs.NewFieldInvalid("oauthConfig.assetPublicURL", config.OAuthConfig.AssetPublicURL, "must match assetConfig.publicURL"), + ) + } + + // TODO warn when the CORS list does not include the assetConfig.publicURL host:port + // only warn cause they could handle CORS headers themselves in a proxy } if config.DNSConfig != nil { diff --git a/pkg/cmd/server/origin/asset.go b/pkg/cmd/server/origin/asset.go index e6de86377207..2ec3890428e4 100644 --- a/pkg/cmd/server/origin/asset.go +++ b/pkg/cmd/server/origin/asset.go @@ -17,11 +17,11 @@ import ( "github.com/openshift/origin/pkg/version" ) -// InstallSupport registers endpoints for an OAuth2 server into the provided mux, +// InstallAPI adds handlers for serving static assets into the provided mux, // then returns an array of strings indicating what endpoints were started // (these are format strings that will expect to be sent a single string value). func (c *AssetConfig) InstallAPI(container *restful.Container) []string { - assetHandler, err := c.handler() + assetHandler, err := c.buildHandler() if err != nil { glog.Fatal(err) } @@ -37,8 +37,10 @@ func (c *AssetConfig) InstallAPI(container *restful.Container) []string { return []string{fmt.Sprintf("Started OpenShift UI %%s%s", publicURL.Path)} } +// Run starts an http server for the static assets listening on the configured +// bind address func (c *AssetConfig) Run() { - assetHandler, err := c.handler() + assetHandler, err := c.buildHandler() if err != nil { glog.Fatal(err) } @@ -50,9 +52,11 @@ func (c *AssetConfig) Run() { mux := http.NewServeMux() mux.Handle(publicURL.Path, http.StripPrefix(publicURL.Path, assetHandler)) - mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { - http.Redirect(w, req, publicURL.Path, http.StatusFound) - }) + if publicURL.Path != "/" { + mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { + http.Redirect(w, req, publicURL.Path, http.StatusFound) + }) + } server := &http.Server{ Addr: c.Options.ServingInfo.BindAddress, @@ -73,7 +77,7 @@ func (c *AssetConfig) Run() { glog.Infof("OpenShift UI listening at https://%s", c.Options.ServingInfo.BindAddress) glog.Fatal(server.ListenAndServeTLS(c.Options.ServingInfo.ServerCert.CertFile, c.Options.ServingInfo.ServerCert.KeyFile)) } else { - glog.Infof("OpenShift UI listening at https://%s", c.Options.ServingInfo.BindAddress) + glog.Infof("OpenShift UI listening at http://%s", c.Options.ServingInfo.BindAddress) glog.Fatal(server.ListenAndServe()) } }, 0) @@ -84,7 +88,7 @@ func (c *AssetConfig) Run() { glog.Infof("OpenShift UI available at %s", c.Options.PublicURL) } -func (c *AssetConfig) handler() (http.Handler, error) { +func (c *AssetConfig) buildHandler() (http.Handler, error) { assets.RegisterMimeTypes() masterURL, err := url.Parse(c.Options.MasterPublicURL) @@ -97,41 +101,44 @@ func (c *AssetConfig) handler() (http.Handler, error) { return nil, err } + publicURL, err := url.Parse(c.Options.PublicURL) + if err != nil { + glog.Fatal(err) + } + config := assets.WebConsoleConfig{ MasterAddr: masterURL.Host, - MasterPrefix: "/osapi", // TODO: make configurable + MasterPrefix: OpenShiftAPIPrefix, KubernetesAddr: k8sURL.Host, - KubernetesPrefix: "/api", // TODO: make configurable + KubernetesPrefix: KubernetesAPIPrefix, OAuthAuthorizeURI: OpenShiftOAuthAuthorizeURL(masterURL.String()), OAuthRedirectBase: c.Options.PublicURL, OAuthClientID: OpenShiftWebConsoleClientID, LogoutURI: c.Options.LogoutURI, } - mux := http.NewServeMux() - mux.Handle("/", - // Gzip first so that inner handlers can react to the addition of the Vary header - assets.GzipHandler( - // Generated config.js can not be cached since it changes depending on startup options - assets.GeneratedConfigHandler( - config, - // Cache control should happen after all Vary headers are added, but before - // any asset related routing (HTML5ModeHandler and FileServer) - assets.CacheControlHandler( - version.Get().GitCommit, - assets.HTML5ModeHandler( - http.FileServer( - &assetfs.AssetFS{ - assets.Asset, - assets.AssetDir, - "", - }, - ), - ), - ), - ), - ), + handler := http.FileServer( + &assetfs.AssetFS{ + assets.Asset, + assets.AssetDir, + "", + }, ) - return mux, nil + handler, err = assets.HTML5ModeHandler(publicURL.Path, handler) + if err != nil { + return nil, err + } + + // Cache control should happen after all Vary headers are added, but before + // any asset related routing (HTML5ModeHandler and FileServer) + handler = assets.CacheControlHandler(version.Get().GitCommit, handler) + + // Generated config.js can not be cached since it changes depending on startup options + handler = assets.GeneratedConfigHandler(config, handler) + + // Gzip first so that inner handlers can react to the addition of the Vary header + handler = assets.GzipHandler(handler) + + return handler, nil } diff --git a/pkg/cmd/server/origin/master.go b/pkg/cmd/server/origin/master.go index 829482f519a5..fb7a9ad28781 100644 --- a/pkg/cmd/server/origin/master.go +++ b/pkg/cmd/server/origin/master.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "regexp" + "strings" "time" etcdclient "github.com/coreos/go-etcd/etcd" @@ -93,7 +94,8 @@ import ( ) const ( - OpenShiftAPIPrefix = "/osapi" + OpenShiftAPIPrefix = "/osapi" // TODO: make configurable + KubernetesAPIPrefix = "/api" // TODO: make configurable OpenShiftAPIV1Beta1 = "v1beta1" OpenShiftAPIPrefixV1Beta1 = OpenShiftAPIPrefix + "/" + OpenShiftAPIV1Beta1 OpenShiftRouteSubdomain = "router.default.local" @@ -269,6 +271,55 @@ func initAPIVersionRoute(root *restful.WebService, version string) { Consumes(restful.MIME_JSON)) } +// If we know the location of the asset server, redirect to it when / is requested +// and the Accept header supports text/html +func assetServerRedirect(handler http.Handler, assetPublicURL string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + accept := req.Header.Get("Accept") + if req.URL.Path == "/" && strings.Contains(accept, "text/html") { + http.Redirect(w, req, assetPublicURL, http.StatusFound) + } else { + // Dispatch to the next handler + handler.ServeHTTP(w, req) + } + }) +} + +// TODO We would like to use the IndexHandler from k8s but we do not yet have a +// MuxHelper to track all registered paths +func indexAPIPaths(handler http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + if req.URL.Path == "/" { + // TODO once we have a MuxHelper we will not need to hardcode this list of paths + object := api.RootPaths{Paths: []string{ + "/api", + "/api/v1beta1", + "/api/v1beta2", + "/api/v1beta3", + "/healthz", + "/healthz/ping", + "/logs/", + "/metrics", + "/osapi", + "/osapi/v1beta1", + "/swaggerapi/", + }} + // TODO it would be nice if apiserver.writeRawJSON was not private + output, err := json.MarshalIndent(object, "", " ") + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + w.Write(output) + } else { + // Dispatch to the next handler + handler.ServeHTTP(w, req) + } + }) +} + // Run launches the OpenShift master. It takes optional installers that may install additional endpoints into the server. // All endpoints get configured CORS behavior // Protected installers' endpoints are protected by API authentication and authorization. @@ -293,6 +344,9 @@ func (c *MasterConfig) Run(protected []APIInstaller, unprotected []APIInstaller) for _, i := range unprotected { extra = append(extra, i.InstallAPI(open)...) } + + handler = indexAPIPaths(handler) + open.Handle("/", handler) // install swagger @@ -310,6 +364,10 @@ func (c *MasterConfig) Run(protected []APIInstaller, unprotected []APIInstaller) handler = apiserver.CORS(handler, origins, nil, nil, "true") } + if c.Options.AssetConfig != nil { + handler = assetServerRedirect(handler, c.Options.AssetConfig.PublicURL) + } + // Make the outermost filter the requestContextMapper to ensure all components share the same context if contextHandler, err := kapi.NewRequestContextFilter(c.getRequestContextMapper(), handler); err != nil { glog.Fatalf("Error setting up request context filter: %v", err) diff --git a/pkg/cmd/server/start/config_test.go b/pkg/cmd/server/start/config_test.go index 6aa60e7934c8..237464b89f24 100644 --- a/pkg/cmd/server/start/config_test.go +++ b/pkg/cmd/server/start/config_test.go @@ -82,27 +82,10 @@ func TestMasterPublicAddressExplicit(t *testing.T) { func TestAssetPublicAddressDefaulting(t *testing.T) { master := "http://example.com:9011" - expected := "http://example.com:9012" - - masterArgs := NewDefaultMasterArgs() - masterArgs.MasterAddr.Set(master) - - actual, err := masterArgs.GetAssetPublicAddress() - if err != nil { - t.Errorf("unexpected error: %v", err) - } - if expected != actual.String() { - t.Errorf("expected %v, got %v", expected, actual) - } -} - -func TestAssetPublicAddressExplicit(t *testing.T) { - master := "http://example.com:9011" - expected := "https://example.com:9014" + expected := "http://example.com:9011/console/" masterArgs := NewDefaultMasterArgs() masterArgs.MasterAddr.Set(master) - masterArgs.AssetPublicAddr.Set(expected) actual, err := masterArgs.GetAssetPublicAddress() if err != nil { @@ -115,24 +98,10 @@ func TestAssetPublicAddressExplicit(t *testing.T) { func TestAssetBindAddressDefaulting(t *testing.T) { bind := "1.2.3.4:9011" - expected := "1.2.3.4:9012" - - masterArgs := NewDefaultMasterArgs() - masterArgs.ListenArg.ListenAddr.Set(bind) - - actual := masterArgs.GetAssetBindAddress() - if expected != actual { - t.Errorf("expected %v, got %v", expected, actual) - } -} - -func TestAssetBindAddressExplicit(t *testing.T) { - bind := "1.2.3.4:9011" - expected := "2.3.4.5:1234" + expected := "1.2.3.4:9011" masterArgs := NewDefaultMasterArgs() masterArgs.ListenArg.ListenAddr.Set(bind) - masterArgs.AssetBindAddr.Set(expected) actual := masterArgs.GetAssetBindAddress() if expected != actual { diff --git a/pkg/cmd/server/start/master_args.go b/pkg/cmd/server/start/master_args.go index 69935401477b..8574bfbd2128 100644 --- a/pkg/cmd/server/start/master_args.go +++ b/pkg/cmd/server/start/master_args.go @@ -29,11 +29,8 @@ type MasterArgs struct { PortalNet flagtypes.IPNet // addresses for external clients MasterPublicAddr flagtypes.Addr - AssetPublicAddr flagtypes.Addr KubernetesPublicAddr flagtypes.Addr - // AssetBindAddr exposed for integration tests to set - AssetBindAddr flagtypes.Addr // DNSBindAddr exposed for integration tests to set DNSBindAddr flagtypes.Addr @@ -74,8 +71,6 @@ func NewDefaultMasterArgs() *MasterArgs { PortalNet: flagtypes.DefaultIPNet("172.30.17.0/24"), MasterPublicAddr: flagtypes.Addr{Value: "localhost:8443", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default(), KubernetesPublicAddr: flagtypes.Addr{Value: "localhost:8443", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default(), - AssetPublicAddr: flagtypes.Addr{Value: "https://localhost:8443/console", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default(), - AssetBindAddr: flagtypes.Addr{Value: "0.0.0.0:8443", DefaultScheme: "https", DefaultPort: 8443, AllowPrefix: true}.Default(), DNSBindAddr: flagtypes.Addr{Value: "0.0.0.0:53", DefaultScheme: "http", DefaultPort: 53, AllowPrefix: true}.Default(), ListenArg: NewDefaultListenArg(), @@ -410,25 +405,17 @@ func (args MasterArgs) GetKubernetesPublicAddress() (*url.URL, error) { } func (args MasterArgs) GetAssetPublicAddress() (*url.URL, error) { - if args.AssetPublicAddr.Provided { - return args.AssetPublicAddr.URL, nil - } - // Derive the asset public address by incrementing the master public address port by 1 - // TODO: derive the scheme/port from the asset bind scheme/port once that is settable via the command line t, err := args.GetMasterPublicAddress() if err != nil { return nil, err } assetPublicAddr := *t - assetPublicAddr.Path = "/console" // TODO: make a constant, eventually make configurable + assetPublicAddr.Path = "/console/" // TODO: make a constant return &assetPublicAddr, nil } func (args MasterArgs) GetAssetBindAddress() string { - if args.AssetBindAddr.Provided { - return args.AssetBindAddr.URL.Host - } return args.ListenArg.ListenAddr.URL.Host } diff --git a/pkg/cmd/server/start/start_master.go b/pkg/cmd/server/start/start_master.go index e17cb9149037..e3aec609c4f2 100644 --- a/pkg/cmd/server/start/start_master.go +++ b/pkg/cmd/server/start/start_master.go @@ -353,17 +353,17 @@ func StartMaster(openshiftMasterConfig *configapi.MasterConfig) error { } unprotectedInstallers = append(unprotectedInstallers, authConfig) - var assetConfig *origin.AssetConfig - var assetColocated = false + var standaloneAssetConfig *origin.AssetConfig if openshiftMasterConfig.AssetConfig != nil { - assetConfig, err := origin.BuildAssetConfig(*openshiftMasterConfig.AssetConfig) + config, err := origin.BuildAssetConfig(*openshiftMasterConfig.AssetConfig) if err != nil { return err } if openshiftMasterConfig.AssetConfig.ServingInfo.BindAddress == openshiftMasterConfig.ServingInfo.BindAddress { - assetColocated = true - unprotectedInstallers = append(unprotectedInstallers, assetConfig) + unprotectedInstallers = append(unprotectedInstallers, config) + } else { + standaloneAssetConfig = config } } @@ -404,8 +404,8 @@ func StartMaster(openshiftMasterConfig *configapi.MasterConfig) error { glog.Infof("Using images from %q", openshiftConfig.ImageFor("")) - if assetConfig != nil && !assetColocated { - assetConfig.Run() + if standaloneAssetConfig != nil { + standaloneAssetConfig.Run() } if openshiftMasterConfig.DNSConfig != nil { openshiftConfig.RunDNSServer() diff --git a/test/integration/root_redirect_test.go b/test/integration/root_redirect_test.go new file mode 100644 index 000000000000..c849006e2caf --- /dev/null +++ b/test/integration/root_redirect_test.go @@ -0,0 +1,53 @@ +// +build integration,!no-etcd + +package integration + +import ( + "crypto/tls" + "net/http" + "testing" + + testutil "github.com/openshift/origin/test/util" +) + +func TestRootRedirect(t *testing.T) { + masterConfig, _, err := testutil.StartTestMaster() + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + + transport := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + + req, err := http.NewRequest("GET", masterConfig.AssetConfig.MasterPublicURL, nil) + req.Header.Set("Accept", "*/*") + resp, err := transport.RoundTrip(req) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if resp.StatusCode != http.StatusOK { + t.Errorf("Expected %d, got %d", http.StatusOK, resp.StatusCode) + } + if resp.Header.Get("Content-Type") != "application/json" { + t.Errorf("Expected %s, got %s", "application/json", resp.Header.Get("Content-Type")) + } + + req, err = http.NewRequest("GET", masterConfig.AssetConfig.MasterPublicURL, nil) + req.Header.Set("Accept", "text/html") + resp, err = transport.RoundTrip(req) + if err != nil { + t.Errorf("Unexpected error: %v", err) + } + if resp.StatusCode != http.StatusFound { + t.Errorf("Expected %d, got %d", http.StatusFound, resp.StatusCode) + } + if resp.Header.Get("Location") != masterConfig.AssetConfig.PublicURL { + t.Errorf("Expected %s, got %s", masterConfig.AssetConfig.PublicURL, resp.Header.Get("Location")) + } + + // TODO add a test for when asset config is nil, the redirect should not occur in this case even when + // accept header contains text/html +} diff --git a/test/util/server.go b/test/util/server.go index 9de0cbb4b449..f899c54237bc 100644 --- a/test/util/server.go +++ b/test/util/server.go @@ -61,15 +61,6 @@ func setupStartOptions() (*start.MasterArgs, *start.NodeArgs, *start.ListenArg, listenArg.ListenAddr.Set(masterAddr) masterArgs.EtcdAddr.Set(GetEtcdURL()) - assetAddr := httptest.NewUnstartedServer(nil).Listener.Addr().String() - if len(os.Getenv("OS_ASSETS_ADDR")) > 0 { - assetAddr = os.Getenv("OS_ASSETS_ADDR") - } - - fmt.Printf("assetAddr: %#v\n", assetAddr) - masterArgs.AssetBindAddr.Set(assetAddr) - masterArgs.AssetPublicAddr.Set(assetAddr) - dnsAddr := httptest.NewUnstartedServer(nil).Listener.Addr().String() if len(os.Getenv("OS_DNS_ADDR")) > 0 { dnsAddr = os.Getenv("OS_DNS_ADDR")