diff --git a/README.md b/README.md
index ced8143d..be84d6d8 100644
--- a/README.md
+++ b/README.md
@@ -22,10 +22,14 @@ $ ./scripts/package.sh
This builds the buildpack's source using GOOS=linux by default. You can supply
another value as the first argument to package.sh.
-## Specifying a project path
+## Configuration
-To specify a project subdirectory (i.e. the directory containing your
-`.csproj`/`.fsproj`/`.vbproj` file), please use the BP_DOTNET_PROJECT_PATH
-environment variable at build time either directly (e.g. pack build my-app
---env BP_DOTNET_PROJECT_PATH=./src/my-app) or through a project.toml file. This
-configuration does not apply to FDD, FDE or Self-Contained app deployments.
+### `BP_DOTNET_PROJECT_PATH`
+To specify a project subdirectory to be used as the root of the app, please use
+the `BP_DOTNET_PROJECT_PATH` environment variable at build time either directly
+(e.g. `pack build my-app --env BP_DOTNET_PROJECT_PATH=./src/my-app`) or through a
+[`project.toml` file](https://github.com/buildpacks/spec/blob/main/extensions/project-descriptor.md).
+
+```shell
+BP_DOTNET_PROJECT_PATH=./src/my-app
+```
diff --git a/build.go b/build.go
index 5750cee0..1c64f03a 100644
--- a/build.go
+++ b/build.go
@@ -9,7 +9,6 @@ import (
"strings"
"time"
- "github.com/Masterminds/semver"
"github.com/Netflix/go-env"
"github.com/paketo-buildpacks/packit/v2"
"github.com/paketo-buildpacks/packit/v2/chronos"
@@ -30,7 +29,6 @@ type SBOMGenerator interface {
// will determine at launch-time which container port the app should listen on.
func Build(
config Configuration,
- buildpackYMLParser BuildpackConfigParser,
configParser ConfigParser,
sbomGenerator SBOMGenerator,
logger scribe.Emitter,
@@ -54,17 +52,6 @@ func Build(
}
logger.Debug.Break()
- projectPath, err := buildpackYMLParser.ParseProjectPath(filepath.Join(context.WorkingDir, "buildpack.yml"))
- if err != nil {
- return packit.BuildResult{}, fmt.Errorf("error parsing buildpack.yml: %w", err)
- }
-
- if projectPath != "" {
- nextMajorVersion := semver.MustParse(context.BuildpackInfo.Version).IncMajor()
- logger.Subprocess("WARNING: Setting the project path through buildpack.yml will be deprecated soon in .NET Execute Buildpack v%s.", nextMajorVersion.String())
- logger.Subprocess("Please specify the project path through the $BP_DOTNET_PROJECT_PATH environment variable instead. See README.md or the documentation on paketo.io for more information.")
- }
-
runtimeConfig, err := configParser.Parse(filepath.Join(context.WorkingDir, "*.runtimeconfig.json"))
if err != nil {
return packit.BuildResult{}, fmt.Errorf("failed to find *.runtimeconfig.json: %w", err)
diff --git a/build_test.go b/build_test.go
index f26d78fc..21af12f8 100644
--- a/build_test.go
+++ b/build_test.go
@@ -24,14 +24,13 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
var (
Expect = NewWithT(t).Expect
- buffer *bytes.Buffer
- buildpackYMLParser *fakes.BuildpackConfigParser
- cnbDir string
- configParser *fakes.ConfigParser
- layersDir string
- logger scribe.Emitter
- sbomGenerator *fakes.SBOMGenerator
- workingDir string
+ buffer *bytes.Buffer
+ cnbDir string
+ configParser *fakes.ConfigParser
+ layersDir string
+ logger scribe.Emitter
+ sbomGenerator *fakes.SBOMGenerator
+ workingDir string
build packit.BuildFunc
)
@@ -49,15 +48,13 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
configParser = &fakes.ConfigParser{}
- buildpackYMLParser = &fakes.BuildpackConfigParser{}
-
sbomGenerator = &fakes.SBOMGenerator{}
sbomGenerator.GenerateCall.Returns.SBOM = sbom.SBOM{}
buffer = bytes.NewBuffer(nil)
logger = scribe.NewEmitter(buffer)
- build = dotnetexecute.Build(dotnetexecute.Configuration{}, buildpackYMLParser, configParser, sbomGenerator, logger, chronos.DefaultClock)
+ build = dotnetexecute.Build(dotnetexecute.Configuration{}, configParser, sbomGenerator, logger, chronos.DefaultClock)
})
it.After(func() {
@@ -161,8 +158,6 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
-
Expect(configParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(sbomGenerator.GenerateCall.Receives.Path).To(Equal(workingDir))
@@ -245,7 +240,7 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
build = dotnetexecute.Build(dotnetexecute.Configuration{
LiveReloadEnabled: true,
- }, buildpackYMLParser, configParser, sbomGenerator, logger, chronos.DefaultClock)
+ }, configParser, sbomGenerator, logger, chronos.DefaultClock)
})
it.After(func() {
@@ -338,7 +333,7 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
build = dotnetexecute.Build(dotnetexecute.Configuration{
DebugEnabled: true,
- }, buildpackYMLParser, configParser, sbomGenerator, logger, chronos.DefaultClock)
+ }, configParser, sbomGenerator, logger, chronos.DefaultClock)
})
it.After(func() {
@@ -385,65 +380,7 @@ func testBuild(t *testing.T, context spec.G, it spec.S) {
})
})
- context("The project path is set via buildpack.yml", func() {
- it.Before(func() {
- buildpackYMLParser.ParseProjectPathCall.Returns.ProjectPath = "src/proj1"
- configParser.ParseCall.Returns.RuntimeConfig = dotnetexecute.RuntimeConfig{
- Path: filepath.Join(workingDir, "my.app.runtimeconfig.json"),
- AppName: "my.app",
- Executable: true,
- }
- })
-
- it("Logs a deprecation warning to the user", func() {
- _, err := build(packit.BuildContext{
- WorkingDir: workingDir,
- CNBPath: cnbDir,
- Stack: "some-stack",
- BuildpackInfo: packit.BuildpackInfo{
- Name: "Some Buildpack",
- Version: "1.2.3",
- },
- Plan: packit.BuildpackPlan{
- Entries: []packit.BuildpackPlanEntry{},
- },
- Layers: packit.Layers{Path: layersDir},
- })
- Expect(err).NotTo(HaveOccurred())
-
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
-
- Expect(configParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
-
- Expect(buffer.String()).To(ContainSubstring("WARNING: Setting the project path through buildpack.yml will be deprecated soon in .NET Execute Buildpack v2.0.0"))
- Expect(buffer.String()).To(ContainSubstring("Please specify the project path through the $BP_DOTNET_PROJECT_PATH environment variable instead. See README.md or the documentation on paketo.io for more information."))
- })
- })
-
context("failure cases", func() {
- context("buildpack.yml parsing fails", func() {
- it.Before(func() {
- buildpackYMLParser.ParseProjectPathCall.Returns.Err = errors.New("error parsing buildpack.yml")
- })
-
- it("logs a warning", func() {
- _, err := build(packit.BuildContext{
- WorkingDir: workingDir,
- CNBPath: cnbDir,
- Stack: "some-stack",
- BuildpackInfo: packit.BuildpackInfo{
- Name: "Some Buildpack",
- Version: "some-version",
- },
- Plan: packit.BuildpackPlan{
- Entries: []packit.BuildpackPlanEntry{},
- },
- Layers: packit.Layers{Path: layersDir},
- })
- Expect(err).To(MatchError(ContainSubstring("error parsing buildpack.yml")))
- })
- })
-
context("runtime config parsing fails", func() {
it.Before(func() {
configParser.ParseCall.Returns.Error = errors.New("error parsing runtimeconfig.json")
diff --git a/buildpack_yml_parser.go b/buildpack_yml_parser.go
deleted file mode 100644
index 68301f94..00000000
--- a/buildpack_yml_parser.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package dotnetexecute
-
-import (
- "os"
-
- yaml "gopkg.in/yaml.v2"
-)
-
-type Config struct {
- ProjectPath string `yaml:"project-path"`
-}
-
-type BuildpackYMLParser struct{}
-
-func NewBuildpackYMLParser() BuildpackYMLParser {
- return BuildpackYMLParser{}
-}
-
-func (p BuildpackYMLParser) Parse(path string) (Config, error) {
- var buildpack struct {
- DotnetBuild Config `yaml:"dotnet-build"`
- }
-
- file, err := os.Open(path)
- if err != nil && !os.IsNotExist(err) {
- return Config{}, err
- }
- defer file.Close()
-
- if !os.IsNotExist(err) {
- err = yaml.NewDecoder(file).Decode(&buildpack)
- if err != nil {
- return Config{}, err
- }
- }
-
- return buildpack.DotnetBuild, nil
-}
-
-func (p BuildpackYMLParser) ParseProjectPath(path string) (string, error) {
- config, err := p.Parse(path)
- if err != nil {
- return "", err
- }
-
- return config.ProjectPath, nil
-}
diff --git a/buildpack_yml_parser_test.go b/buildpack_yml_parser_test.go
deleted file mode 100644
index 3c867a44..00000000
--- a/buildpack_yml_parser_test.go
+++ /dev/null
@@ -1,97 +0,0 @@
-package dotnetexecute_test
-
-import (
- "os"
- "testing"
-
- dotnetexecute "github.com/paketo-buildpacks/dotnet-execute"
- "github.com/sclevine/spec"
-
- . "github.com/onsi/gomega"
-)
-
-func testBuildpackYMLParser(t *testing.T, context spec.G, it spec.S) {
- var (
- Expect = NewWithT(t).Expect
-
- path string
- parser dotnetexecute.BuildpackYMLParser
- )
-
- it.Before(func() {
- file, err := os.CreateTemp("", "buildpack.yml")
- Expect(err).NotTo(HaveOccurred())
- defer file.Close()
-
- _, err = file.WriteString(`---
-dotnet-build:
- project-path: "src/proj1"
-`)
- Expect(err).NotTo(HaveOccurred())
-
- path = file.Name()
-
- parser = dotnetexecute.NewBuildpackYMLParser()
- })
-
- it.After(func() {
- Expect(os.RemoveAll(path)).To(Succeed())
- })
-
- context("Parse", func() {
- it("parses a buildpack.yml file", func() {
- configData, err := parser.Parse(path)
- Expect(err).NotTo(HaveOccurred())
- Expect(configData.ProjectPath).To(Equal("src/proj1"))
- })
- })
-
- context("ParseProjectPath", func() {
- it("parses the project-path from a buildpack.yml file", func() {
- projectPath, err := parser.ParseProjectPath(path)
- Expect(err).NotTo(HaveOccurred())
- Expect(projectPath).To(Equal("src/proj1"))
- })
-
- context("when the buildpack.yml file does not exist", func() {
- it.Before(func() {
- Expect(os.Remove(path)).To(Succeed())
- })
-
- it("returns an empty project-path", func() {
- projectPath, err := parser.ParseProjectPath(path)
- Expect(err).NotTo(HaveOccurred())
- Expect(projectPath).To(BeEmpty())
- })
- })
- })
-
- context("failure cases", func() {
- context("when the buildpack.yml file cannot be read", func() {
- it.Before(func() {
- Expect(os.Chmod(path, 0000)).To(Succeed())
- })
-
- it.After(func() {
- Expect(os.Chmod(path, 0644)).To(Succeed())
- })
-
- it("returns an error", func() {
- _, err := parser.ParseProjectPath(path)
- Expect(err).To(MatchError(ContainSubstring("permission denied")))
- })
- })
-
- context("when the contents of the buildpack.yml file are malformed", func() {
- it.Before(func() {
- err := os.WriteFile(path, []byte("%%%"), 0644)
- Expect(err).NotTo(HaveOccurred())
- })
-
- it("returns an error", func() {
- _, err := parser.ParseProjectPath(path)
- Expect(err).To(MatchError(ContainSubstring("could not find expected directive name")))
- })
- })
- })
-}
diff --git a/detect.go b/detect.go
index 9877bc7b..06a641a7 100644
--- a/detect.go
+++ b/detect.go
@@ -18,11 +18,6 @@ type BuildPlanMetadata struct {
Launch bool `toml:"launch"`
}
-//go:generate faux --interface BuildpackConfigParser --output fakes/buildpack_config_parser.go
-type BuildpackConfigParser interface {
- ParseProjectPath(path string) (projectPath string, err error)
-}
-
//go:generate faux --interface ConfigParser --output fakes/config_parser.go
type ConfigParser interface {
Parse(glob string) (RuntimeConfig, error)
@@ -65,7 +60,6 @@ type ProjectParser interface {
func Detect(
config Configuration,
logger scribe.Emitter,
- buildpackYMLParser BuildpackConfigParser,
configParser ConfigParser,
projectParser ProjectParser,
) packit.DetectFunc {
@@ -104,14 +98,6 @@ func Detect(
})
}
- if config.ProjectPath == "" {
- var err error
- config.ProjectPath, err = buildpackYMLParser.ParseProjectPath(filepath.Join(context.WorkingDir, "buildpack.yml"))
- if err != nil {
- return packit.DetectResult{}, fmt.Errorf("failed to parse buildpack.yml: %w", err)
- }
- }
-
root := context.WorkingDir
if config.ProjectPath != "" {
root = filepath.Join(root, config.ProjectPath)
diff --git a/detect_test.go b/detect_test.go
index ad193e60..f70a73d8 100644
--- a/detect_test.go
+++ b/detect_test.go
@@ -23,7 +23,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
buffer *bytes.Buffer
workingDir string
- buildpackYMLParser *fakes.BuildpackConfigParser
logger scribe.Emitter
projectParser *fakes.ProjectParser
runtimeConfigParser *fakes.ConfigParser
@@ -36,7 +35,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
workingDir, err = os.MkdirTemp("", "working-dir")
Expect(err).NotTo(HaveOccurred())
- buildpackYMLParser = &fakes.BuildpackConfigParser{}
runtimeConfigParser = &fakes.ConfigParser{}
runtimeConfigParser.ParseCall.Returns.RuntimeConfig = dotnetexecute.RuntimeConfig{
Path: filepath.Join(workingDir, "some-app.runtimeconfig.json"),
@@ -46,7 +44,7 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
buffer = bytes.NewBuffer(nil)
logger = scribe.NewEmitter(buffer)
- detect = dotnetexecute.Detect(dotnetexecute.Configuration{}, logger, buildpackYMLParser, runtimeConfigParser, projectParser)
+ detect = dotnetexecute.Detect(dotnetexecute.Configuration{}, logger, runtimeConfigParser, projectParser)
})
it.After(func() {
@@ -77,7 +75,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(workingDir))
})
@@ -113,7 +110,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(workingDir))
})
@@ -150,7 +146,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(workingDir))
})
@@ -188,7 +183,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(workingDir))
})
@@ -228,7 +222,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(workingDir))
@@ -269,7 +262,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(workingDir))
@@ -310,7 +302,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(workingDir))
@@ -359,7 +350,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
},
}))
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(workingDir))
@@ -367,39 +357,11 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
})
})
- context("there is a buildpack.yml which sets a custom project-path", func() {
- it.Before(func() {
- buildpackYMLParser.ParseProjectPathCall.Returns.ProjectPath = "src/proj1"
- })
-
- context("project-path directory contains a proj file", func() {
- it.Before(func() {
- projectParser.FindProjectFileCall.Returns.String = "/path/to/some-file.csproj"
- })
-
- it("detects successfully", func() {
- _, err := detect(packit.DetectContext{
- WorkingDir: workingDir,
- BuildpackInfo: packit.BuildpackInfo{
- Version: "0.0.1",
- },
- })
- Expect(err).NotTo(HaveOccurred())
-
- Expect(buildpackYMLParser.ParseProjectPathCall.Receives.Path).To(Equal(filepath.Join(workingDir, "buildpack.yml")))
- Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "src/proj1", "*.runtimeconfig.json")))
-
- Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(filepath.Join(workingDir, "src/proj1")))
- Expect(projectParser.NodeIsRequiredCall.Receives.Path).To(Equal("/path/to/some-file.csproj"))
- })
- })
- })
-
context("when BP_DOTNET_PROJECT_PATH sets a custom project-path", func() {
it.Before(func() {
detect = dotnetexecute.Detect(dotnetexecute.Configuration{
ProjectPath: "src/proj1",
- }, logger, buildpackYMLParser, runtimeConfigParser, projectParser)
+ }, logger, runtimeConfigParser, projectParser)
})
context("project-path directory contains a proj file", func() {
@@ -413,7 +375,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
})
Expect(err).NotTo(HaveOccurred())
- Expect(buildpackYMLParser.ParseProjectPathCall.CallCount).To(Equal(0))
Expect(runtimeConfigParser.ParseCall.Receives.Glob).To(Equal(filepath.Join(workingDir, "src/proj1", "*.runtimeconfig.json")))
Expect(projectParser.FindProjectFileCall.Receives.Root).To(Equal(filepath.Join(workingDir, "src/proj1")))
@@ -426,7 +387,7 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
it.Before(func() {
detect = dotnetexecute.Detect(dotnetexecute.Configuration{
LiveReloadEnabled: true,
- }, logger, buildpackYMLParser, runtimeConfigParser, projectParser)
+ }, logger, runtimeConfigParser, projectParser)
})
it("requires watchexec at launch", func() {
@@ -443,11 +404,12 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
))
})
})
+
context("when BP_DEBUG_ENABLED is set to true", func() {
it.Before(func() {
detect = dotnetexecute.Detect(dotnetexecute.Configuration{
DebugEnabled: true,
- }, logger, buildpackYMLParser, runtimeConfigParser, projectParser)
+ }, logger, runtimeConfigParser, projectParser)
})
it("requires vsdbg at launch", func() {
@@ -466,19 +428,6 @@ func testDetect(t *testing.T, context spec.G, it spec.S) {
})
context("failure cases", func() {
- context("when the buildpack.yml parser fails", func() {
- it.Before(func() {
- buildpackYMLParser.ParseProjectPathCall.Returns.Err = errors.New("some-error")
- })
-
- it("returns an error", func() {
- _, err := detect(packit.DetectContext{
- WorkingDir: "/working-dir",
- })
- Expect(err).To(MatchError("failed to parse buildpack.yml: some-error"))
- })
- })
-
context("when the runtime config parsing fails", func() {
it.Before(func() {
runtimeConfigParser.ParseCall.Returns.Error = errors.New("failed to parse runtime config")
diff --git a/fakes/buildpack_config_parser.go b/fakes/buildpack_config_parser.go
deleted file mode 100644
index 94dc5374..00000000
--- a/fakes/buildpack_config_parser.go
+++ /dev/null
@@ -1,29 +0,0 @@
-package fakes
-
-import "sync"
-
-type BuildpackConfigParser struct {
- ParseProjectPathCall struct {
- mutex sync.Mutex
- CallCount int
- Receives struct {
- Path string
- }
- Returns struct {
- ProjectPath string
- Err error
- }
- Stub func(string) (string, error)
- }
-}
-
-func (f *BuildpackConfigParser) ParseProjectPath(param1 string) (string, error) {
- f.ParseProjectPathCall.mutex.Lock()
- defer f.ParseProjectPathCall.mutex.Unlock()
- f.ParseProjectPathCall.CallCount++
- f.ParseProjectPathCall.Receives.Path = param1
- if f.ParseProjectPathCall.Stub != nil {
- return f.ParseProjectPathCall.Stub(param1)
- }
- return f.ParseProjectPathCall.Returns.ProjectPath, f.ParseProjectPathCall.Returns.Err
-}
diff --git a/init_test.go b/init_test.go
index 1cc141a8..fcf77b48 100644
--- a/init_test.go
+++ b/init_test.go
@@ -10,7 +10,6 @@ import (
func TestUnitDotnetExecute(t *testing.T) {
suite := spec.New("dotnet-execute", spec.Report(report.Terminal{}))
suite("Build", testBuild)
- suite("BuildpackYMLParser", testBuildpackYMLParser)
suite("Detect", testDetect)
suite("RuntimeConfigParser", testRuntimeConfigParser)
suite("ProjectFileParser", testProjectFileParser)
diff --git a/integration.json b/integration.json
index 69abbfad..ffba9369 100644
--- a/integration.json
+++ b/integration.json
@@ -1,5 +1,5 @@
{
- "builders": ["paketobuildpacks/builder:buildpackless-base", "paketobuildpacks/builder-jammy-buildpackless-base"],
+ "builders": ["paketobuildpacks/builder-jammy-buildpackless-base"],
"dotnet-core-aspnet": "github.com/paketo-buildpacks/dotnet-core-aspnet",
"dotnet-core-runtime": "github.com/paketo-buildpacks/dotnet-core-runtime",
"dotnet-core-aspnet-runtime": "github.com/paketo-buildpacks/dotnet-core-aspnet-runtime",
diff --git a/integration/framework_dependent_deployment_test.go b/integration/framework_dependent_deployment_test.go
index 97eb7f41..ce3ccc5f 100644
--- a/integration/framework_dependent_deployment_test.go
+++ b/integration/framework_dependent_deployment_test.go
@@ -27,7 +27,7 @@ func testFrameworkDependentDeployment(t *testing.T, context spec.G, it spec.S) {
docker = occam.NewDocker()
})
- context("when building a default .NET 6 FDD app", func() {
+ context("when building a default .NET 8 FDD app", func() {
var (
image occam.Image
container occam.Container
@@ -51,7 +51,7 @@ func testFrameworkDependentDeployment(t *testing.T, context spec.G, it spec.S) {
it("builds and runs successfully", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "fdd_6"))
+ source, err = occam.Source(filepath.Join("testdata", "framework_dependent_deployment_8"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
diff --git a/integration/framework_dependent_executable_test.go b/integration/framework_dependent_executable_test.go
index ff5ebff4..4a28cdb0 100644
--- a/integration/framework_dependent_executable_test.go
+++ b/integration/framework_dependent_executable_test.go
@@ -49,10 +49,10 @@ func testFrameworkDependentExecutable(t *testing.T, context spec.G, it spec.S) {
Expect(os.RemoveAll(source)).To(Succeed())
})
- context("when the app is a .NET 6 framework dependent executable", func() {
+ context("when the app is a .NET 8 framework dependent executable", func() {
it("builds and runs successfully", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "fde_6"))
+ source, err = occam.Source(filepath.Join("testdata", "framework_dependent_executable_8"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
@@ -73,14 +73,14 @@ func testFrameworkDependentExecutable(t *testing.T, context spec.G, it spec.S) {
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())
- Eventually(container).Should(Serve(ContainSubstring("fde_dotnet_6")).OnPort(8080))
+ Eventually(container).Should(Serve(ContainSubstring("Welcome")).OnPort(8080))
})
})
- context("when the app is a .NET 8 framework dependent executable", func() {
+ context("when the app is a .NET 9 framework dependent executable", func() {
it("builds and runs successfully", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "fde_dotnet_8"))
+ source, err = occam.Source(filepath.Join("testdata", "framework_dependent_executable_9"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
@@ -101,7 +101,7 @@ func testFrameworkDependentExecutable(t *testing.T, context spec.G, it spec.S) {
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())
- Eventually(container).Should(Serve(ContainSubstring("fde_dotnet_8")).OnPort(8080))
+ Eventually(container).Should(Serve(ContainSubstring("Welcome")).OnPort(8080))
})
})
@@ -114,7 +114,7 @@ func testFrameworkDependentExecutable(t *testing.T, context spec.G, it spec.S) {
it("adds a default start process with watchexec and names the normal start process no-reload", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "fde_6"))
+ source, err = occam.Source(filepath.Join("testdata", "framework_dependent_executable_8"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
@@ -138,7 +138,7 @@ func testFrameworkDependentExecutable(t *testing.T, context spec.G, it spec.S) {
return logs.String()
}).Should(ContainSubstring(`Now listening on: http://0.0.0.0:8080`))
- noReloadContainer, err = docker.Container.Run.WithEntrypoint("fde_dotnet_6").Execute(image.ID)
+ noReloadContainer, err = docker.Container.Run.WithEntrypoint("framework_dependent_8").Execute(image.ID)
Expect(err).NotTo(HaveOccurred())
Eventually(func() string {
diff --git a/integration/logging_test.go b/integration/logging_test.go
index 87c72f23..a3422b17 100644
--- a/integration/logging_test.go
+++ b/integration/logging_test.go
@@ -48,7 +48,7 @@ func testLogging(t *testing.T, context spec.G, it spec.S) {
it("presents the expected log output", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "self_contained_executable_6"))
+ source, err = occam.Source(filepath.Join("testdata", "self_contained_8"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
@@ -80,7 +80,7 @@ func testLogging(t *testing.T, context spec.G, it spec.S) {
" application/vnd.syft+json",
"",
" Assigning launch processes:",
- ` source_6_selfcontained (default): /workspace/source_6_selfcontained`,
+ ` webapp_8 (default): /workspace/webapp_8`,
"",
" Setting up layer 'port-chooser'",
" Available at app launch: true",
diff --git a/integration/node_app_test.go b/integration/node_app_test.go
index ff75909f..3d63b725 100644
--- a/integration/node_app_test.go
+++ b/integration/node_app_test.go
@@ -28,7 +28,7 @@ func testNodeApp(t *testing.T, context spec.G, it spec.S) {
docker = occam.NewDocker()
})
- context("when building a .NET 6 + node app", func() {
+ context("when building a .NET 8 + node app", func() {
var (
image occam.Image
container occam.Container
diff --git a/integration/self_contained_executable_test.go b/integration/self_contained_executable_test.go
index 3a76d48c..1f9af5fa 100644
--- a/integration/self_contained_executable_test.go
+++ b/integration/self_contained_executable_test.go
@@ -49,10 +49,10 @@ func testSelfContainedExecutable(t *testing.T, context spec.G, it spec.S) {
Expect(os.RemoveAll(source)).To(Succeed())
})
- context("when the self-contained executable uses .NET 6", func() {
+ context("when the self-contained executable uses .NET 8", func() {
it("builds and runs successfully", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "self_contained_executable_6"))
+ source, err = occam.Source(filepath.Join("testdata", "self_contained_8"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
@@ -72,7 +72,7 @@ func testSelfContainedExecutable(t *testing.T, context spec.G, it spec.S) {
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())
- Eventually(container).Should(Serve(ContainSubstring("Hello, world!")).OnPort(8080))
+ Eventually(container).Should(Serve(ContainSubstring("Welcome")).OnPort(8080))
})
})
})
diff --git a/integration/source_app_test.go b/integration/source_app_test.go
index 706e9d8a..b496f6ea 100644
--- a/integration/source_app_test.go
+++ b/integration/source_app_test.go
@@ -49,10 +49,10 @@ func testSourceApp(t *testing.T, context spec.G, it spec.S) {
Expect(os.RemoveAll(source)).To(Succeed())
})
- context("when 'net6.0' is specified as the TargetFramework", func() {
+ context("when .NET 8 is the desired framework", func() {
it("builds and runs successfully", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "source_6"))
+ source, err = occam.Source(filepath.Join("testdata", "source_8"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
@@ -75,7 +75,7 @@ func testSourceApp(t *testing.T, context spec.G, it spec.S) {
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())
- Eventually(container).Should(Serve(ContainSubstring("source_6_app")).OnPort(8080))
+ Eventually(container).Should(Serve(ContainSubstring("Welcome")).OnPort(8080))
})
context("remote debugging is enabled", func() {
@@ -85,7 +85,7 @@ func testSourceApp(t *testing.T, context spec.G, it spec.S) {
})
it("builds and runs successfully", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "source_6"))
+ source, err = occam.Source(filepath.Join("testdata", "source_8"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
@@ -112,7 +112,7 @@ func testSourceApp(t *testing.T, context spec.G, it spec.S) {
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())
- Eventually(container).Should(Serve(ContainSubstring("source_6_app")).OnPort(8080))
+ Eventually(container).Should(Serve(ContainSubstring("Welcome")).OnPort(8080))
vsdbgContainer, err = docker.Container.Run.
WithEntrypoint("launcher").
@@ -129,10 +129,10 @@ func testSourceApp(t *testing.T, context spec.G, it spec.S) {
})
})
- context("when .NET 8 is the desired framework", func() {
+ context("when .NET 9 is the desired framework", func() {
it("builds and runs successfully", func() {
var err error
- source, err = occam.Source(filepath.Join("testdata", "source_8"))
+ source, err = occam.Source(filepath.Join("testdata", "source_9"))
Expect(err).NotTo(HaveOccurred())
var logs fmt.Stringer
@@ -155,7 +155,7 @@ func testSourceApp(t *testing.T, context spec.G, it spec.S) {
Execute(image.ID)
Expect(err).NotTo(HaveOccurred())
- Eventually(container).Should(Serve(ContainSubstring("source_8")).OnPort(8080))
+ Eventually(container).Should(Serve(ContainSubstring("Welcome")).OnPort(8080))
})
})
})
diff --git a/integration/testdata/fdd_6/README.md b/integration/testdata/fdd_6/README.md
deleted file mode 100644
index ffa95dec..00000000
--- a/integration/testdata/fdd_6/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-This app was generated using `dotnet` CLI v6.0.100:
-```
-cd integration/testdata
-dotnet new webapp -o /tmp/fde_dotnet_6
-
-dotnet publish /tmp/fde_dotnet_6 --configuration Release --runtime ubuntu.18.04-x64 --self-contained false --output ./fde_6
-```
diff --git a/integration/testdata/fdd_6/fde_dotnet_6.deps.json b/integration/testdata/fdd_6/fde_dotnet_6.deps.json
deleted file mode 100644
index 695906a4..00000000
--- a/integration/testdata/fdd_6/fde_dotnet_6.deps.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
- "runtimeTarget": {
- "name": ".NETCoreApp,Version=v6.0/ubuntu.18.04-x64",
- "signature": ""
- },
- "compilationOptions": {},
- "targets": {
- ".NETCoreApp,Version=v6.0": {},
- ".NETCoreApp,Version=v6.0/ubuntu.18.04-x64": {
- "fde_dotnet_6/1.0.0": {
- "runtime": {
- "fde_dotnet_6.dll": {}
- }
- }
- }
- },
- "libraries": {
- "fde_dotnet_6/1.0.0": {
- "type": "project",
- "serviceable": false,
- "sha512": ""
- }
- }
-}
\ No newline at end of file
diff --git a/integration/testdata/fdd_6/fde_dotnet_6.dll b/integration/testdata/fdd_6/fde_dotnet_6.dll
deleted file mode 100644
index f83ca7c4..00000000
Binary files a/integration/testdata/fdd_6/fde_dotnet_6.dll and /dev/null differ
diff --git a/integration/testdata/fdd_6/fde_dotnet_6.pdb b/integration/testdata/fdd_6/fde_dotnet_6.pdb
deleted file mode 100644
index 7e0b1680..00000000
Binary files a/integration/testdata/fdd_6/fde_dotnet_6.pdb and /dev/null differ
diff --git a/integration/testdata/fdd_6/fde_dotnet_6.runtimeconfig.json b/integration/testdata/fdd_6/fde_dotnet_6.runtimeconfig.json
deleted file mode 100644
index 80d03471..00000000
--- a/integration/testdata/fdd_6/fde_dotnet_6.runtimeconfig.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "runtimeOptions": {
- "tfm": "net6.0",
- "frameworks": [
- {
- "name": "Microsoft.NETCore.App",
- "version": "6.0.0"
- },
- {
- "name": "Microsoft.AspNetCore.App",
- "version": "6.0.0"
- }
- ],
- "configProperties": {
- "System.GC.Server": true,
- "System.Reflection.Metadata.MetadataUpdater.IsSupported": false,
- "System.Runtime.Serialization.EnableUnsafeBinaryFormatterSerialization": false
- }
- }
-}
\ No newline at end of file
diff --git a/integration/testdata/fdd_6/wwwroot/css/site.css b/integration/testdata/fdd_6/wwwroot/css/site.css
deleted file mode 100644
index 50d5b608..00000000
--- a/integration/testdata/fdd_6/wwwroot/css/site.css
+++ /dev/null
@@ -1,18 +0,0 @@
-html {
- font-size: 14px;
-}
-
-@media (min-width: 768px) {
- html {
- font-size: 16px;
- }
-}
-
-html {
- position: relative;
- min-height: 100%;
-}
-
-body {
- margin-bottom: 60px;
-}
\ No newline at end of file
diff --git a/integration/testdata/fdd_6/wwwroot/fde_dotnet_6.styles.css b/integration/testdata/fdd_6/wwwroot/fde_dotnet_6.styles.css
deleted file mode 100644
index 2ff8fd4d..00000000
--- a/integration/testdata/fdd_6/wwwroot/fde_dotnet_6.styles.css
+++ /dev/null
@@ -1,49 +0,0 @@
-/* _content/fde_dotnet_6/Views/Shared/_Layout.cshtml.rz.scp.css */
-/* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
-for details on configuring this project to bundle and minify static web assets. */
-
-a.navbar-brand[b-zuhyvukn0y] {
- white-space: normal;
- text-align: center;
- word-break: break-all;
-}
-
-a[b-zuhyvukn0y] {
- color: #0077cc;
-}
-
-.btn-primary[b-zuhyvukn0y] {
- color: #fff;
- background-color: #1b6ec2;
- border-color: #1861ac;
-}
-
-.nav-pills .nav-link.active[b-zuhyvukn0y], .nav-pills .show > .nav-link[b-zuhyvukn0y] {
- color: #fff;
- background-color: #1b6ec2;
- border-color: #1861ac;
-}
-
-.border-top[b-zuhyvukn0y] {
- border-top: 1px solid #e5e5e5;
-}
-.border-bottom[b-zuhyvukn0y] {
- border-bottom: 1px solid #e5e5e5;
-}
-
-.box-shadow[b-zuhyvukn0y] {
- box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
-}
-
-button.accept-policy[b-zuhyvukn0y] {
- font-size: 1rem;
- line-height: inherit;
-}
-
-.footer[b-zuhyvukn0y] {
- position: absolute;
- bottom: 0;
- width: 100%;
- white-space: nowrap;
- line-height: 60px;
-}
diff --git a/integration/testdata/fdd_6/wwwroot/js/site.js b/integration/testdata/fdd_6/wwwroot/js/site.js
deleted file mode 100644
index b2f58e17..00000000
--- a/integration/testdata/fdd_6/wwwroot/js/site.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification
-// for details on configuring this project to bundle and minify static web assets.
-
-// Write your JavaScript code.
diff --git a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt b/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
deleted file mode 100644
index 78109a89..00000000
--- a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Copyright (c) .NET Foundation. All rights reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use
-these files except in compliance with the License. You may obtain a copy of the
-License at
-
-http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software distributed
-under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-CONDITIONS OF ANY KIND, either express or implied. See the License for the
-specific language governing permissions and limitations under the License.
diff --git a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js b/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js
deleted file mode 100644
index 73f52983..00000000
--- a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js
+++ /dev/null
@@ -1,432 +0,0 @@
-// Unobtrusive validation support library for jQuery and jQuery Validate
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-// @version v3.2.11
-
-/*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */
-/*global document: false, jQuery: false */
-
-(function (factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define("jquery.validate.unobtrusive", ['jquery-validation'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports
- module.exports = factory(require('jquery-validation'));
- } else {
- // Browser global
- jQuery.validator.unobtrusive = factory(jQuery);
- }
-}(function ($) {
- var $jQval = $.validator,
- adapters,
- data_validation = "unobtrusiveValidation";
-
- function setValidationValues(options, ruleName, value) {
- options.rules[ruleName] = value;
- if (options.message) {
- options.messages[ruleName] = options.message;
- }
- }
-
- function splitAndTrim(value) {
- return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g);
- }
-
- function escapeAttributeValue(value) {
- // As mentioned on http://api.jquery.com/category/selectors/
- return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1");
- }
-
- function getModelPrefix(fieldName) {
- return fieldName.substr(0, fieldName.lastIndexOf(".") + 1);
- }
-
- function appendModelPrefix(value, prefix) {
- if (value.indexOf("*.") === 0) {
- value = value.replace("*.", prefix);
- }
- return value;
- }
-
- function onError(error, inputElement) { // 'this' is the form element
- var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"),
- replaceAttrValue = container.attr("data-valmsg-replace"),
- replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null;
-
- container.removeClass("field-validation-valid").addClass("field-validation-error");
- error.data("unobtrusiveContainer", container);
-
- if (replace) {
- container.empty();
- error.removeClass("input-validation-error").appendTo(container);
- }
- else {
- error.hide();
- }
- }
-
- function onErrors(event, validator) { // 'this' is the form element
- var container = $(this).find("[data-valmsg-summary=true]"),
- list = container.find("ul");
-
- if (list && list.length && validator.errorList.length) {
- list.empty();
- container.addClass("validation-summary-errors").removeClass("validation-summary-valid");
-
- $.each(validator.errorList, function () {
- $("
").html(this.message).appendTo(list);
- });
- }
- }
-
- function onSuccess(error) { // 'this' is the form element
- var container = error.data("unobtrusiveContainer");
-
- if (container) {
- var replaceAttrValue = container.attr("data-valmsg-replace"),
- replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null;
-
- container.addClass("field-validation-valid").removeClass("field-validation-error");
- error.removeData("unobtrusiveContainer");
-
- if (replace) {
- container.empty();
- }
- }
- }
-
- function onReset(event) { // 'this' is the form element
- var $form = $(this),
- key = '__jquery_unobtrusive_validation_form_reset';
- if ($form.data(key)) {
- return;
- }
- // Set a flag that indicates we're currently resetting the form.
- $form.data(key, true);
- try {
- $form.data("validator").resetForm();
- } finally {
- $form.removeData(key);
- }
-
- $form.find(".validation-summary-errors")
- .addClass("validation-summary-valid")
- .removeClass("validation-summary-errors");
- $form.find(".field-validation-error")
- .addClass("field-validation-valid")
- .removeClass("field-validation-error")
- .removeData("unobtrusiveContainer")
- .find(">*") // If we were using valmsg-replace, get the underlying error
- .removeData("unobtrusiveContainer");
- }
-
- function validationInfo(form) {
- var $form = $(form),
- result = $form.data(data_validation),
- onResetProxy = $.proxy(onReset, form),
- defaultOptions = $jQval.unobtrusive.options || {},
- execInContext = function (name, args) {
- var func = defaultOptions[name];
- func && $.isFunction(func) && func.apply(form, args);
- };
-
- if (!result) {
- result = {
- options: { // options structure passed to jQuery Validate's validate() method
- errorClass: defaultOptions.errorClass || "input-validation-error",
- errorElement: defaultOptions.errorElement || "span",
- errorPlacement: function () {
- onError.apply(form, arguments);
- execInContext("errorPlacement", arguments);
- },
- invalidHandler: function () {
- onErrors.apply(form, arguments);
- execInContext("invalidHandler", arguments);
- },
- messages: {},
- rules: {},
- success: function () {
- onSuccess.apply(form, arguments);
- execInContext("success", arguments);
- }
- },
- attachValidation: function () {
- $form
- .off("reset." + data_validation, onResetProxy)
- .on("reset." + data_validation, onResetProxy)
- .validate(this.options);
- },
- validate: function () { // a validation function that is called by unobtrusive Ajax
- $form.validate();
- return $form.valid();
- }
- };
- $form.data(data_validation, result);
- }
-
- return result;
- }
-
- $jQval.unobtrusive = {
- adapters: [],
-
- parseElement: function (element, skipAttach) {
- ///
- /// Parses a single HTML element for unobtrusive validation attributes.
- ///
- /// The HTML element to be parsed.
- /// [Optional] true to skip attaching the
- /// validation to the form. If parsing just this single element, you should specify true.
- /// If parsing several elements, you should specify false, and manually attach the validation
- /// to the form when you are finished. The default is false.
- var $element = $(element),
- form = $element.parents("form")[0],
- valInfo, rules, messages;
-
- if (!form) { // Cannot do client-side validation without a form
- return;
- }
-
- valInfo = validationInfo(form);
- valInfo.options.rules[element.name] = rules = {};
- valInfo.options.messages[element.name] = messages = {};
-
- $.each(this.adapters, function () {
- var prefix = "data-val-" + this.name,
- message = $element.attr(prefix),
- paramValues = {};
-
- if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy)
- prefix += "-";
-
- $.each(this.params, function () {
- paramValues[this] = $element.attr(prefix + this);
- });
-
- this.adapt({
- element: element,
- form: form,
- message: message,
- params: paramValues,
- rules: rules,
- messages: messages
- });
- }
- });
-
- $.extend(rules, { "__dummy__": true });
-
- if (!skipAttach) {
- valInfo.attachValidation();
- }
- },
-
- parse: function (selector) {
- ///
- /// Parses all the HTML elements in the specified selector. It looks for input elements decorated
- /// with the [data-val=true] attribute value and enables validation according to the data-val-*
- /// attribute values.
- ///
- /// Any valid jQuery selector.
-
- // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one
- // element with data-val=true
- var $selector = $(selector),
- $forms = $selector.parents()
- .addBack()
- .filter("form")
- .add($selector.find("form"))
- .has("[data-val=true]");
-
- $selector.find("[data-val=true]").each(function () {
- $jQval.unobtrusive.parseElement(this, true);
- });
-
- $forms.each(function () {
- var info = validationInfo(this);
- if (info) {
- info.attachValidation();
- }
- });
- }
- };
-
- adapters = $jQval.unobtrusive.adapters;
-
- adapters.add = function (adapterName, params, fn) {
- /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation.
- /// The name of the adapter to be added. This matches the name used
- /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
- /// [Optional] An array of parameter names (strings) that will
- /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and
- /// mmmm is the parameter name).
- /// The function to call, which adapts the values from the HTML
- /// attributes into jQuery Validate rules and/or messages.
- ///
- if (!fn) { // Called with no params, just a function
- fn = params;
- params = [];
- }
- this.push({ name: adapterName, params: params, adapt: fn });
- return this;
- };
-
- adapters.addBool = function (adapterName, ruleName) {
- /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
- /// the jQuery Validate validation rule has no parameter values.
- /// The name of the adapter to be added. This matches the name used
- /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
- /// [Optional] The name of the jQuery Validate rule. If not provided, the value
- /// of adapterName will be used instead.
- ///
- return this.add(adapterName, function (options) {
- setValidationValues(options, ruleName || adapterName, true);
- });
- };
-
- adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) {
- /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
- /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and
- /// one for min-and-max). The HTML parameters are expected to be named -min and -max.
- /// The name of the adapter to be added. This matches the name used
- /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name).
- /// The name of the jQuery Validate rule to be used when you only
- /// have a minimum value.
- /// The name of the jQuery Validate rule to be used when you only
- /// have a maximum value.
- /// The name of the jQuery Validate rule to be used when you
- /// have both a minimum and maximum value.
- /// [Optional] The name of the HTML attribute that
- /// contains the minimum value. The default is "min".
- /// [Optional] The name of the HTML attribute that
- /// contains the maximum value. The default is "max".
- ///
- return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) {
- var min = options.params.min,
- max = options.params.max;
-
- if (min && max) {
- setValidationValues(options, minMaxRuleName, [min, max]);
- }
- else if (min) {
- setValidationValues(options, minRuleName, min);
- }
- else if (max) {
- setValidationValues(options, maxRuleName, max);
- }
- });
- };
-
- adapters.addSingleVal = function (adapterName, attribute, ruleName) {
- /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where
- /// the jQuery Validate validation rule has a single value.
- /// The name of the adapter to be added. This matches the name used
- /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name).
- /// [Optional] The name of the HTML attribute that contains the value.
- /// The default is "val".
- /// [Optional] The name of the jQuery Validate rule. If not provided, the value
- /// of adapterName will be used instead.
- ///
- return this.add(adapterName, [attribute || "val"], function (options) {
- setValidationValues(options, ruleName || adapterName, options.params[attribute]);
- });
- };
-
- $jQval.addMethod("__dummy__", function (value, element, params) {
- return true;
- });
-
- $jQval.addMethod("regex", function (value, element, params) {
- var match;
- if (this.optional(element)) {
- return true;
- }
-
- match = new RegExp(params).exec(value);
- return (match && (match.index === 0) && (match[0].length === value.length));
- });
-
- $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) {
- var match;
- if (nonalphamin) {
- match = value.match(/\W/g);
- match = match && match.length >= nonalphamin;
- }
- return match;
- });
-
- if ($jQval.methods.extension) {
- adapters.addSingleVal("accept", "mimtype");
- adapters.addSingleVal("extension", "extension");
- } else {
- // for backward compatibility, when the 'extension' validation method does not exist, such as with versions
- // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for
- // validating the extension, and ignore mime-type validations as they are not supported.
- adapters.addSingleVal("extension", "extension", "accept");
- }
-
- adapters.addSingleVal("regex", "pattern");
- adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");
- adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range");
- adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength");
- adapters.add("equalto", ["other"], function (options) {
- var prefix = getModelPrefix(options.element.name),
- other = options.params.other,
- fullOtherName = appendModelPrefix(other, prefix),
- element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0];
-
- setValidationValues(options, "equalTo", element);
- });
- adapters.add("required", function (options) {
- // jQuery Validate equates "required" with "mandatory" for checkbox elements
- if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
- setValidationValues(options, "required", true);
- }
- });
- adapters.add("remote", ["url", "type", "additionalfields"], function (options) {
- var value = {
- url: options.params.url,
- type: options.params.type || "GET",
- data: {}
- },
- prefix = getModelPrefix(options.element.name);
-
- $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) {
- var paramName = appendModelPrefix(fieldName, prefix);
- value.data[paramName] = function () {
- var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']");
- // For checkboxes and radio buttons, only pick up values from checked fields.
- if (field.is(":checkbox")) {
- return field.filter(":checked").val() || field.filter(":hidden").val() || '';
- }
- else if (field.is(":radio")) {
- return field.filter(":checked").val() || '';
- }
- return field.val();
- };
- });
-
- setValidationValues(options, "remote", value);
- });
- adapters.add("password", ["min", "nonalphamin", "regex"], function (options) {
- if (options.params.min) {
- setValidationValues(options, "minlength", options.params.min);
- }
- if (options.params.nonalphamin) {
- setValidationValues(options, "nonalphamin", options.params.nonalphamin);
- }
- if (options.params.regex) {
- setValidationValues(options, "regex", options.params.regex);
- }
- });
- adapters.add("fileextensions", ["extensions"], function (options) {
- setValidationValues(options, "extension", options.params.extensions);
- });
-
- $(function () {
- $jQval.unobtrusive.parse(document);
- });
-
- return $jQval.unobtrusive;
-}));
diff --git a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js b/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js
deleted file mode 100644
index 553d4274..00000000
--- a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Unobtrusive validation support library for jQuery and jQuery Validate
-// Copyright (c) .NET Foundation. All rights reserved.
-// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-// @version v3.2.11
-!function(a){"function"==typeof define&&define.amd?define("jquery.validate.unobtrusive",["jquery-validation"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery-validation")):jQuery.validator.unobtrusive=a(jQuery)}(function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,.\/:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function u(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=f.unobtrusive.options||{},u=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),u("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),u("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),u("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var m,f=a.validator,v="unobtrusiveValidation";return f.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=u(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){f.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=u(this);a&&a.attachValidation()})}},m=f.unobtrusive.adapters,m.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},m.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},m.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},m.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},f.addMethod("__dummy__",function(a,e,n){return!0}),f.addMethod("regex",function(a,e,n){var t;return!!this.optional(e)||(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),f.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),f.methods.extension?(m.addSingleVal("accept","mimtype"),m.addSingleVal("extension","extension")):m.addSingleVal("extension","extension","accept"),m.addSingleVal("regex","pattern"),m.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),m.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),m.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),m.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),m.add("required",function(a){"INPUT"===a.element.tagName.toUpperCase()&&"CHECKBOX"===a.element.type.toUpperCase()||e(a,"required",!0)}),m.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),m.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),m.add("fileextensions",["extensions"],function(a){e(a,"extension",a.params.extensions)}),a(function(){f.unobtrusive.parse(document)}),f.unobtrusive});
diff --git a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/additional-methods.js b/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/additional-methods.js
deleted file mode 100644
index 480ecd1d..00000000
--- a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/additional-methods.js
+++ /dev/null
@@ -1,1158 +0,0 @@
-/*!
- * jQuery Validation Plugin v1.17.0
- *
- * https://jqueryvalidation.org/
- *
- * Copyright (c) 2017 Jörn Zaefferer
- * Released under the MIT license
- */
-(function( factory ) {
- if ( typeof define === "function" && define.amd ) {
- define( ["jquery", "./jquery.validate"], factory );
- } else if (typeof module === "object" && module.exports) {
- module.exports = factory( require( "jquery" ) );
- } else {
- factory( jQuery );
- }
-}(function( $ ) {
-
-( function() {
-
- function stripHtml( value ) {
-
- // Remove html tags and space chars
- return value.replace( /<.[^<>]*?>/g, " " ).replace( / | /gi, " " )
-
- // Remove punctuation
- .replace( /[.(),;:!?%#$'\"_+=\/\-“”’]*/g, "" );
- }
-
- $.validator.addMethod( "maxWords", function( value, element, params ) {
- return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length <= params;
- }, $.validator.format( "Please enter {0} words or less." ) );
-
- $.validator.addMethod( "minWords", function( value, element, params ) {
- return this.optional( element ) || stripHtml( value ).match( /\b\w+\b/g ).length >= params;
- }, $.validator.format( "Please enter at least {0} words." ) );
-
- $.validator.addMethod( "rangeWords", function( value, element, params ) {
- var valueStripped = stripHtml( value ),
- regex = /\b\w+\b/g;
- return this.optional( element ) || valueStripped.match( regex ).length >= params[ 0 ] && valueStripped.match( regex ).length <= params[ 1 ];
- }, $.validator.format( "Please enter between {0} and {1} words." ) );
-
-}() );
-
-// Accept a value from a file input based on a required mimetype
-$.validator.addMethod( "accept", function( value, element, param ) {
-
- // Split mime on commas in case we have multiple types we can accept
- var typeParam = typeof param === "string" ? param.replace( /\s/g, "" ) : "image/*",
- optionalValue = this.optional( element ),
- i, file, regex;
-
- // Element is optional
- if ( optionalValue ) {
- return optionalValue;
- }
-
- if ( $( element ).attr( "type" ) === "file" ) {
-
- // Escape string to be used in the regex
- // see: https://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
- // Escape also "/*" as "/.*" as a wildcard
- typeParam = typeParam
- .replace( /[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g, "\\$&" )
- .replace( /,/g, "|" )
- .replace( /\/\*/g, "/.*" );
-
- // Check if the element has a FileList before checking each file
- if ( element.files && element.files.length ) {
- regex = new RegExp( ".?(" + typeParam + ")$", "i" );
- for ( i = 0; i < element.files.length; i++ ) {
- file = element.files[ i ];
-
- // Grab the mimetype from the loaded file, verify it matches
- if ( !file.type.match( regex ) ) {
- return false;
- }
- }
- }
- }
-
- // Either return true because we've validated each file, or because the
- // browser does not support element.files and the FileList feature
- return true;
-}, $.validator.format( "Please enter a value with a valid mimetype." ) );
-
-$.validator.addMethod( "alphanumeric", function( value, element ) {
- return this.optional( element ) || /^\w+$/i.test( value );
-}, "Letters, numbers, and underscores only please" );
-
-/*
- * Dutch bank account numbers (not 'giro' numbers) have 9 digits
- * and pass the '11 check'.
- * We accept the notation with spaces, as that is common.
- * acceptable: 123456789 or 12 34 56 789
- */
-$.validator.addMethod( "bankaccountNL", function( value, element ) {
- if ( this.optional( element ) ) {
- return true;
- }
- if ( !( /^[0-9]{9}|([0-9]{2} ){3}[0-9]{3}$/.test( value ) ) ) {
- return false;
- }
-
- // Now '11 check'
- var account = value.replace( / /g, "" ), // Remove spaces
- sum = 0,
- len = account.length,
- pos, factor, digit;
- for ( pos = 0; pos < len; pos++ ) {
- factor = len - pos;
- digit = account.substring( pos, pos + 1 );
- sum = sum + factor * digit;
- }
- return sum % 11 === 0;
-}, "Please specify a valid bank account number" );
-
-$.validator.addMethod( "bankorgiroaccountNL", function( value, element ) {
- return this.optional( element ) ||
- ( $.validator.methods.bankaccountNL.call( this, value, element ) ) ||
- ( $.validator.methods.giroaccountNL.call( this, value, element ) );
-}, "Please specify a valid bank or giro account number" );
-
-/**
- * BIC is the business identifier code (ISO 9362). This BIC check is not a guarantee for authenticity.
- *
- * BIC pattern: BBBBCCLLbbb (8 or 11 characters long; bbb is optional)
- *
- * Validation is case-insensitive. Please make sure to normalize input yourself.
- *
- * BIC definition in detail:
- * - First 4 characters - bank code (only letters)
- * - Next 2 characters - ISO 3166-1 alpha-2 country code (only letters)
- * - Next 2 characters - location code (letters and digits)
- * a. shall not start with '0' or '1'
- * b. second character must be a letter ('O' is not allowed) or digit ('0' for test (therefore not allowed), '1' denoting passive participant, '2' typically reverse-billing)
- * - Last 3 characters - branch code, optional (shall not start with 'X' except in case of 'XXX' for primary office) (letters and digits)
- */
-$.validator.addMethod( "bic", function( value, element ) {
- return this.optional( element ) || /^([A-Z]{6}[A-Z2-9][A-NP-Z1-9])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test( value.toUpperCase() );
-}, "Please specify a valid BIC code" );
-
-/*
- * Código de identificación fiscal ( CIF ) is the tax identification code for Spanish legal entities
- * Further rules can be found in Spanish on http://es.wikipedia.org/wiki/C%C3%B3digo_de_identificaci%C3%B3n_fiscal
- *
- * Spanish CIF structure:
- *
- * [ T ][ P ][ P ][ N ][ N ][ N ][ N ][ N ][ C ]
- *
- * Where:
- *
- * T: 1 character. Kind of Organization Letter: [ABCDEFGHJKLMNPQRSUVW]
- * P: 2 characters. Province.
- * N: 5 characters. Secuencial Number within the province.
- * C: 1 character. Control Digit: [0-9A-J].
- *
- * [ T ]: Kind of Organizations. Possible values:
- *
- * A. Corporations
- * B. LLCs
- * C. General partnerships
- * D. Companies limited partnerships
- * E. Communities of goods
- * F. Cooperative Societies
- * G. Associations
- * H. Communities of homeowners in horizontal property regime
- * J. Civil Societies
- * K. Old format
- * L. Old format
- * M. Old format
- * N. Nonresident entities
- * P. Local authorities
- * Q. Autonomous bodies, state or not, and the like, and congregations and religious institutions
- * R. Congregations and religious institutions (since 2008 ORDER EHA/451/2008)
- * S. Organs of State Administration and regions
- * V. Agrarian Transformation
- * W. Permanent establishments of non-resident in Spain
- *
- * [ C ]: Control Digit. It can be a number or a letter depending on T value:
- * [ T ] --> [ C ]
- * ------ ----------
- * A Number
- * B Number
- * E Number
- * H Number
- * K Letter
- * P Letter
- * Q Letter
- * S Letter
- *
- */
-$.validator.addMethod( "cifES", function( value, element ) {
- "use strict";
-
- if ( this.optional( element ) ) {
- return true;
- }
-
- var cifRegEx = new RegExp( /^([ABCDEFGHJKLMNPQRSUVW])(\d{7})([0-9A-J])$/gi );
- var letter = value.substring( 0, 1 ), // [ T ]
- number = value.substring( 1, 8 ), // [ P ][ P ][ N ][ N ][ N ][ N ][ N ]
- control = value.substring( 8, 9 ), // [ C ]
- all_sum = 0,
- even_sum = 0,
- odd_sum = 0,
- i, n,
- control_digit,
- control_letter;
-
- function isOdd( n ) {
- return n % 2 === 0;
- }
-
- // Quick format test
- if ( value.length !== 9 || !cifRegEx.test( value ) ) {
- return false;
- }
-
- for ( i = 0; i < number.length; i++ ) {
- n = parseInt( number[ i ], 10 );
-
- // Odd positions
- if ( isOdd( i ) ) {
-
- // Odd positions are multiplied first.
- n *= 2;
-
- // If the multiplication is bigger than 10 we need to adjust
- odd_sum += n < 10 ? n : n - 9;
-
- // Even positions
- // Just sum them
- } else {
- even_sum += n;
- }
- }
-
- all_sum = even_sum + odd_sum;
- control_digit = ( 10 - ( all_sum ).toString().substr( -1 ) ).toString();
- control_digit = parseInt( control_digit, 10 ) > 9 ? "0" : control_digit;
- control_letter = "JABCDEFGHI".substr( control_digit, 1 ).toString();
-
- // Control must be a digit
- if ( letter.match( /[ABEH]/ ) ) {
- return control === control_digit;
-
- // Control must be a letter
- } else if ( letter.match( /[KPQS]/ ) ) {
- return control === control_letter;
- }
-
- // Can be either
- return control === control_digit || control === control_letter;
-
-}, "Please specify a valid CIF number." );
-
-/*
- * Brazillian CPF number (Cadastrado de Pessoas Físicas) is the equivalent of a Brazilian tax registration number.
- * CPF numbers have 11 digits in total: 9 numbers followed by 2 check numbers that are being used for validation.
- */
-$.validator.addMethod( "cpfBR", function( value ) {
-
- // Removing special characters from value
- value = value.replace( /([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g, "" );
-
- // Checking value to have 11 digits only
- if ( value.length !== 11 ) {
- return false;
- }
-
- var sum = 0,
- firstCN, secondCN, checkResult, i;
-
- firstCN = parseInt( value.substring( 9, 10 ), 10 );
- secondCN = parseInt( value.substring( 10, 11 ), 10 );
-
- checkResult = function( sum, cn ) {
- var result = ( sum * 10 ) % 11;
- if ( ( result === 10 ) || ( result === 11 ) ) {
- result = 0;
- }
- return ( result === cn );
- };
-
- // Checking for dump data
- if ( value === "" ||
- value === "00000000000" ||
- value === "11111111111" ||
- value === "22222222222" ||
- value === "33333333333" ||
- value === "44444444444" ||
- value === "55555555555" ||
- value === "66666666666" ||
- value === "77777777777" ||
- value === "88888888888" ||
- value === "99999999999"
- ) {
- return false;
- }
-
- // Step 1 - using first Check Number:
- for ( i = 1; i <= 9; i++ ) {
- sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 11 - i );
- }
-
- // If first Check Number (CN) is valid, move to Step 2 - using second Check Number:
- if ( checkResult( sum, firstCN ) ) {
- sum = 0;
- for ( i = 1; i <= 10; i++ ) {
- sum = sum + parseInt( value.substring( i - 1, i ), 10 ) * ( 12 - i );
- }
- return checkResult( sum, secondCN );
- }
- return false;
-
-}, "Please specify a valid CPF number" );
-
-// https://jqueryvalidation.org/creditcard-method/
-// based on https://en.wikipedia.org/wiki/Luhn_algorithm
-$.validator.addMethod( "creditcard", function( value, element ) {
- if ( this.optional( element ) ) {
- return "dependency-mismatch";
- }
-
- // Accept only spaces, digits and dashes
- if ( /[^0-9 \-]+/.test( value ) ) {
- return false;
- }
-
- var nCheck = 0,
- nDigit = 0,
- bEven = false,
- n, cDigit;
-
- value = value.replace( /\D/g, "" );
-
- // Basing min and max length on
- // https://developer.ean.com/general_info/Valid_Credit_Card_Types
- if ( value.length < 13 || value.length > 19 ) {
- return false;
- }
-
- for ( n = value.length - 1; n >= 0; n-- ) {
- cDigit = value.charAt( n );
- nDigit = parseInt( cDigit, 10 );
- if ( bEven ) {
- if ( ( nDigit *= 2 ) > 9 ) {
- nDigit -= 9;
- }
- }
-
- nCheck += nDigit;
- bEven = !bEven;
- }
-
- return ( nCheck % 10 ) === 0;
-}, "Please enter a valid credit card number." );
-
-/* NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator
- * Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0
- * Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings)
- */
-$.validator.addMethod( "creditcardtypes", function( value, element, param ) {
- if ( /[^0-9\-]+/.test( value ) ) {
- return false;
- }
-
- value = value.replace( /\D/g, "" );
-
- var validTypes = 0x0000;
-
- if ( param.mastercard ) {
- validTypes |= 0x0001;
- }
- if ( param.visa ) {
- validTypes |= 0x0002;
- }
- if ( param.amex ) {
- validTypes |= 0x0004;
- }
- if ( param.dinersclub ) {
- validTypes |= 0x0008;
- }
- if ( param.enroute ) {
- validTypes |= 0x0010;
- }
- if ( param.discover ) {
- validTypes |= 0x0020;
- }
- if ( param.jcb ) {
- validTypes |= 0x0040;
- }
- if ( param.unknown ) {
- validTypes |= 0x0080;
- }
- if ( param.all ) {
- validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080;
- }
- if ( validTypes & 0x0001 && /^(5[12345])/.test( value ) ) { // Mastercard
- return value.length === 16;
- }
- if ( validTypes & 0x0002 && /^(4)/.test( value ) ) { // Visa
- return value.length === 16;
- }
- if ( validTypes & 0x0004 && /^(3[47])/.test( value ) ) { // Amex
- return value.length === 15;
- }
- if ( validTypes & 0x0008 && /^(3(0[012345]|[68]))/.test( value ) ) { // Dinersclub
- return value.length === 14;
- }
- if ( validTypes & 0x0010 && /^(2(014|149))/.test( value ) ) { // Enroute
- return value.length === 15;
- }
- if ( validTypes & 0x0020 && /^(6011)/.test( value ) ) { // Discover
- return value.length === 16;
- }
- if ( validTypes & 0x0040 && /^(3)/.test( value ) ) { // Jcb
- return value.length === 16;
- }
- if ( validTypes & 0x0040 && /^(2131|1800)/.test( value ) ) { // Jcb
- return value.length === 15;
- }
- if ( validTypes & 0x0080 ) { // Unknown
- return true;
- }
- return false;
-}, "Please enter a valid credit card number." );
-
-/**
- * Validates currencies with any given symbols by @jameslouiz
- * Symbols can be optional or required. Symbols required by default
- *
- * Usage examples:
- * currency: ["£", false] - Use false for soft currency validation
- * currency: ["$", false]
- * currency: ["RM", false] - also works with text based symbols such as "RM" - Malaysia Ringgit etc
- *
- *
- *
- * Soft symbol checking
- * currencyInput: {
- * currency: ["$", false]
- * }
- *
- * Strict symbol checking (default)
- * currencyInput: {
- * currency: "$"
- * //OR
- * currency: ["$", true]
- * }
- *
- * Multiple Symbols
- * currencyInput: {
- * currency: "$,£,¢"
- * }
- */
-$.validator.addMethod( "currency", function( value, element, param ) {
- var isParamString = typeof param === "string",
- symbol = isParamString ? param : param[ 0 ],
- soft = isParamString ? true : param[ 1 ],
- regex;
-
- symbol = symbol.replace( /,/g, "" );
- symbol = soft ? symbol + "]" : symbol + "]?";
- regex = "^[" + symbol + "([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$";
- regex = new RegExp( regex );
- return this.optional( element ) || regex.test( value );
-
-}, "Please specify a valid currency" );
-
-$.validator.addMethod( "dateFA", function( value, element ) {
- return this.optional( element ) || /^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test( value );
-}, $.validator.messages.date );
-
-/**
- * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy.
- *
- * @example $.validator.methods.date("01/01/1900")
- * @result true
- *
- * @example $.validator.methods.date("01/13/1990")
- * @result false
- *
- * @example $.validator.methods.date("01.01.1900")
- * @result false
- *
- * @example
- * @desc Declares an optional input element whose value must be a valid date.
- *
- * @name $.validator.methods.dateITA
- * @type Boolean
- * @cat Plugins/Validate/Methods
- */
-$.validator.addMethod( "dateITA", function( value, element ) {
- var check = false,
- re = /^\d{1,2}\/\d{1,2}\/\d{4}$/,
- adata, gg, mm, aaaa, xdata;
- if ( re.test( value ) ) {
- adata = value.split( "/" );
- gg = parseInt( adata[ 0 ], 10 );
- mm = parseInt( adata[ 1 ], 10 );
- aaaa = parseInt( adata[ 2 ], 10 );
- xdata = new Date( Date.UTC( aaaa, mm - 1, gg, 12, 0, 0, 0 ) );
- if ( ( xdata.getUTCFullYear() === aaaa ) && ( xdata.getUTCMonth() === mm - 1 ) && ( xdata.getUTCDate() === gg ) ) {
- check = true;
- } else {
- check = false;
- }
- } else {
- check = false;
- }
- return this.optional( element ) || check;
-}, $.validator.messages.date );
-
-$.validator.addMethod( "dateNL", function( value, element ) {
- return this.optional( element ) || /^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test( value );
-}, $.validator.messages.date );
-
-// Older "accept" file extension method. Old docs: http://docs.jquery.com/Plugins/Validation/Methods/accept
-$.validator.addMethod( "extension", function( value, element, param ) {
- param = typeof param === "string" ? param.replace( /,/g, "|" ) : "png|jpe?g|gif";
- return this.optional( element ) || value.match( new RegExp( "\\.(" + param + ")$", "i" ) );
-}, $.validator.format( "Please enter a value with a valid extension." ) );
-
-/**
- * Dutch giro account numbers (not bank numbers) have max 7 digits
- */
-$.validator.addMethod( "giroaccountNL", function( value, element ) {
- return this.optional( element ) || /^[0-9]{1,7}$/.test( value );
-}, "Please specify a valid giro account number" );
-
-/**
- * IBAN is the international bank account number.
- * It has a country - specific format, that is checked here too
- *
- * Validation is case-insensitive. Please make sure to normalize input yourself.
- */
-$.validator.addMethod( "iban", function( value, element ) {
-
- // Some quick simple tests to prevent needless work
- if ( this.optional( element ) ) {
- return true;
- }
-
- // Remove spaces and to upper case
- var iban = value.replace( / /g, "" ).toUpperCase(),
- ibancheckdigits = "",
- leadingZeroes = true,
- cRest = "",
- cOperator = "",
- countrycode, ibancheck, charAt, cChar, bbanpattern, bbancountrypatterns, ibanregexp, i, p;
-
- // Check for IBAN code length.
- // It contains:
- // country code ISO 3166-1 - two letters,
- // two check digits,
- // Basic Bank Account Number (BBAN) - up to 30 chars
- var minimalIBANlength = 5;
- if ( iban.length < minimalIBANlength ) {
- return false;
- }
-
- // Check the country code and find the country specific format
- countrycode = iban.substring( 0, 2 );
- bbancountrypatterns = {
- "AL": "\\d{8}[\\dA-Z]{16}",
- "AD": "\\d{8}[\\dA-Z]{12}",
- "AT": "\\d{16}",
- "AZ": "[\\dA-Z]{4}\\d{20}",
- "BE": "\\d{12}",
- "BH": "[A-Z]{4}[\\dA-Z]{14}",
- "BA": "\\d{16}",
- "BR": "\\d{23}[A-Z][\\dA-Z]",
- "BG": "[A-Z]{4}\\d{6}[\\dA-Z]{8}",
- "CR": "\\d{17}",
- "HR": "\\d{17}",
- "CY": "\\d{8}[\\dA-Z]{16}",
- "CZ": "\\d{20}",
- "DK": "\\d{14}",
- "DO": "[A-Z]{4}\\d{20}",
- "EE": "\\d{16}",
- "FO": "\\d{14}",
- "FI": "\\d{14}",
- "FR": "\\d{10}[\\dA-Z]{11}\\d{2}",
- "GE": "[\\dA-Z]{2}\\d{16}",
- "DE": "\\d{18}",
- "GI": "[A-Z]{4}[\\dA-Z]{15}",
- "GR": "\\d{7}[\\dA-Z]{16}",
- "GL": "\\d{14}",
- "GT": "[\\dA-Z]{4}[\\dA-Z]{20}",
- "HU": "\\d{24}",
- "IS": "\\d{22}",
- "IE": "[\\dA-Z]{4}\\d{14}",
- "IL": "\\d{19}",
- "IT": "[A-Z]\\d{10}[\\dA-Z]{12}",
- "KZ": "\\d{3}[\\dA-Z]{13}",
- "KW": "[A-Z]{4}[\\dA-Z]{22}",
- "LV": "[A-Z]{4}[\\dA-Z]{13}",
- "LB": "\\d{4}[\\dA-Z]{20}",
- "LI": "\\d{5}[\\dA-Z]{12}",
- "LT": "\\d{16}",
- "LU": "\\d{3}[\\dA-Z]{13}",
- "MK": "\\d{3}[\\dA-Z]{10}\\d{2}",
- "MT": "[A-Z]{4}\\d{5}[\\dA-Z]{18}",
- "MR": "\\d{23}",
- "MU": "[A-Z]{4}\\d{19}[A-Z]{3}",
- "MC": "\\d{10}[\\dA-Z]{11}\\d{2}",
- "MD": "[\\dA-Z]{2}\\d{18}",
- "ME": "\\d{18}",
- "NL": "[A-Z]{4}\\d{10}",
- "NO": "\\d{11}",
- "PK": "[\\dA-Z]{4}\\d{16}",
- "PS": "[\\dA-Z]{4}\\d{21}",
- "PL": "\\d{24}",
- "PT": "\\d{21}",
- "RO": "[A-Z]{4}[\\dA-Z]{16}",
- "SM": "[A-Z]\\d{10}[\\dA-Z]{12}",
- "SA": "\\d{2}[\\dA-Z]{18}",
- "RS": "\\d{18}",
- "SK": "\\d{20}",
- "SI": "\\d{15}",
- "ES": "\\d{20}",
- "SE": "\\d{20}",
- "CH": "\\d{5}[\\dA-Z]{12}",
- "TN": "\\d{20}",
- "TR": "\\d{5}[\\dA-Z]{17}",
- "AE": "\\d{3}\\d{16}",
- "GB": "[A-Z]{4}\\d{14}",
- "VG": "[\\dA-Z]{4}\\d{16}"
- };
-
- bbanpattern = bbancountrypatterns[ countrycode ];
-
- // As new countries will start using IBAN in the
- // future, we only check if the countrycode is known.
- // This prevents false negatives, while almost all
- // false positives introduced by this, will be caught
- // by the checksum validation below anyway.
- // Strict checking should return FALSE for unknown
- // countries.
- if ( typeof bbanpattern !== "undefined" ) {
- ibanregexp = new RegExp( "^[A-Z]{2}\\d{2}" + bbanpattern + "$", "" );
- if ( !( ibanregexp.test( iban ) ) ) {
- return false; // Invalid country specific format
- }
- }
-
- // Now check the checksum, first convert to digits
- ibancheck = iban.substring( 4, iban.length ) + iban.substring( 0, 4 );
- for ( i = 0; i < ibancheck.length; i++ ) {
- charAt = ibancheck.charAt( i );
- if ( charAt !== "0" ) {
- leadingZeroes = false;
- }
- if ( !leadingZeroes ) {
- ibancheckdigits += "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".indexOf( charAt );
- }
- }
-
- // Calculate the result of: ibancheckdigits % 97
- for ( p = 0; p < ibancheckdigits.length; p++ ) {
- cChar = ibancheckdigits.charAt( p );
- cOperator = "" + cRest + "" + cChar;
- cRest = cOperator % 97;
- }
- return cRest === 1;
-}, "Please specify a valid IBAN" );
-
-$.validator.addMethod( "integer", function( value, element ) {
- return this.optional( element ) || /^-?\d+$/.test( value );
-}, "A positive or negative non-decimal number please" );
-
-$.validator.addMethod( "ipv4", function( value, element ) {
- return this.optional( element ) || /^(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)\.(25[0-5]|2[0-4]\d|[01]?\d\d?)$/i.test( value );
-}, "Please enter a valid IP v4 address." );
-
-$.validator.addMethod( "ipv6", function( value, element ) {
- return this.optional( element ) || /^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(([0-9A-Fa-f]{1,4}:){0,5}:((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|(::([0-9A-Fa-f]{1,4}:){0,5}((\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b)\.){3}(\b((25[0-5])|(1\d{2})|(2[0-4]\d)|(\d{1,2}))\b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$/i.test( value );
-}, "Please enter a valid IP v6 address." );
-
-$.validator.addMethod( "lettersonly", function( value, element ) {
- return this.optional( element ) || /^[a-z]+$/i.test( value );
-}, "Letters only please" );
-
-$.validator.addMethod( "letterswithbasicpunc", function( value, element ) {
- return this.optional( element ) || /^[a-z\-.,()'"\s]+$/i.test( value );
-}, "Letters or punctuation only please" );
-
-$.validator.addMethod( "mobileNL", function( value, element ) {
- return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)6((\s|\s?\-\s?)?[0-9]){8}$/.test( value );
-}, "Please specify a valid mobile number" );
-
-/* For UK phone functions, do the following server side processing:
- * Compare original input with this RegEx pattern:
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
- * Extract $1 and set $prefix to '+44' if $1 is '44', otherwise set $prefix to '0'
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
- */
-$.validator.addMethod( "mobileUK", function( phone_number, element ) {
- phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
- return this.optional( element ) || phone_number.length > 9 &&
- phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/ );
-}, "Please specify a valid mobile number" );
-
-$.validator.addMethod( "netmask", function( value, element ) {
- return this.optional( element ) || /^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test( value );
-}, "Please enter a valid netmask." );
-
-/*
- * The NIE (Número de Identificación de Extranjero) is a Spanish tax identification number assigned by the Spanish
- * authorities to any foreigner.
- *
- * The NIE is the equivalent of a Spaniards Número de Identificación Fiscal (NIF) which serves as a fiscal
- * identification number. The CIF number (Certificado de Identificación Fiscal) is equivalent to the NIF, but applies to
- * companies rather than individuals. The NIE consists of an 'X' or 'Y' followed by 7 or 8 digits then another letter.
- */
-$.validator.addMethod( "nieES", function( value, element ) {
- "use strict";
-
- if ( this.optional( element ) ) {
- return true;
- }
-
- var nieRegEx = new RegExp( /^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi );
- var validChars = "TRWAGMYFPDXBNJZSQVHLCKET",
- letter = value.substr( value.length - 1 ).toUpperCase(),
- number;
-
- value = value.toString().toUpperCase();
-
- // Quick format test
- if ( value.length > 10 || value.length < 9 || !nieRegEx.test( value ) ) {
- return false;
- }
-
- // X means same number
- // Y means number + 10000000
- // Z means number + 20000000
- value = value.replace( /^[X]/, "0" )
- .replace( /^[Y]/, "1" )
- .replace( /^[Z]/, "2" );
-
- number = value.length === 9 ? value.substr( 0, 8 ) : value.substr( 0, 9 );
-
- return validChars.charAt( parseInt( number, 10 ) % 23 ) === letter;
-
-}, "Please specify a valid NIE number." );
-
-/*
- * The Número de Identificación Fiscal ( NIF ) is the way tax identification used in Spain for individuals
- */
-$.validator.addMethod( "nifES", function( value, element ) {
- "use strict";
-
- if ( this.optional( element ) ) {
- return true;
- }
-
- value = value.toUpperCase();
-
- // Basic format test
- if ( !value.match( "((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)" ) ) {
- return false;
- }
-
- // Test NIF
- if ( /^[0-9]{8}[A-Z]{1}$/.test( value ) ) {
- return ( "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 0 ) % 23 ) === value.charAt( 8 ) );
- }
-
- // Test specials NIF (starts with K, L or M)
- if ( /^[KLM]{1}/.test( value ) ) {
- return ( value[ 8 ] === "TRWAGMYFPDXBNJZSQVHLCKE".charAt( value.substring( 8, 1 ) % 23 ) );
- }
-
- return false;
-
-}, "Please specify a valid NIF number." );
-
-/*
- * Numer identyfikacji podatkowej ( NIP ) is the way tax identification used in Poland for companies
- */
-$.validator.addMethod( "nipPL", function( value ) {
- "use strict";
-
- value = value.replace( /[^0-9]/g, "" );
-
- if ( value.length !== 10 ) {
- return false;
- }
-
- var arrSteps = [ 6, 5, 7, 2, 3, 4, 5, 6, 7 ];
- var intSum = 0;
- for ( var i = 0; i < 9; i++ ) {
- intSum += arrSteps[ i ] * value[ i ];
- }
- var int2 = intSum % 11;
- var intControlNr = ( int2 === 10 ) ? 0 : int2;
-
- return ( intControlNr === parseInt( value[ 9 ], 10 ) );
-}, "Please specify a valid NIP number." );
-
-$.validator.addMethod( "notEqualTo", function( value, element, param ) {
- return this.optional( element ) || !$.validator.methods.equalTo.call( this, value, element, param );
-}, "Please enter a different value, values must not be the same." );
-
-$.validator.addMethod( "nowhitespace", function( value, element ) {
- return this.optional( element ) || /^\S+$/i.test( value );
-}, "No white space please" );
-
-/**
-* Return true if the field value matches the given format RegExp
-*
-* @example $.validator.methods.pattern("AR1004",element,/^AR\d{4}$/)
-* @result true
-*
-* @example $.validator.methods.pattern("BR1004",element,/^AR\d{4}$/)
-* @result false
-*
-* @name $.validator.methods.pattern
-* @type Boolean
-* @cat Plugins/Validate/Methods
-*/
-$.validator.addMethod( "pattern", function( value, element, param ) {
- if ( this.optional( element ) ) {
- return true;
- }
- if ( typeof param === "string" ) {
- param = new RegExp( "^(?:" + param + ")$" );
- }
- return param.test( value );
-}, "Invalid format." );
-
-/**
- * Dutch phone numbers have 10 digits (or 11 and start with +31).
- */
-$.validator.addMethod( "phoneNL", function( value, element ) {
- return this.optional( element ) || /^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test( value );
-}, "Please specify a valid phone number." );
-
-/* For UK phone functions, do the following server side processing:
- * Compare original input with this RegEx pattern:
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
- * Extract $1 and set $prefix to '+44' if $1 is '44', otherwise set $prefix to '0'
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
- */
-
-// Matches UK landline + mobile, accepting only 01-3 for landline or 07 for mobile to exclude many premium numbers
-$.validator.addMethod( "phonesUK", function( phone_number, element ) {
- phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
- return this.optional( element ) || phone_number.length > 9 &&
- phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/ );
-}, "Please specify a valid uk phone number" );
-
-/* For UK phone functions, do the following server side processing:
- * Compare original input with this RegEx pattern:
- * ^\(?(?:(?:00\)?[\s\-]?\(?|\+)(44)\)?[\s\-]?\(?(?:0\)?[\s\-]?\(?)?|0)([1-9]\d{1,4}\)?[\s\d\-]+)$
- * Extract $1 and set $prefix to '+44' if $1 is '44', otherwise set $prefix to '0'
- * Extract $2 and remove hyphens, spaces and parentheses. Phone number is combined $prefix and $2.
- * A number of very detailed GB telephone number RegEx patterns can also be found at:
- * http://www.aa-asterisk.org.uk/index.php/Regular_Expressions_for_Validating_and_Formatting_GB_Telephone_Numbers
- */
-$.validator.addMethod( "phoneUK", function( phone_number, element ) {
- phone_number = phone_number.replace( /\(|\)|\s+|-/g, "" );
- return this.optional( element ) || phone_number.length > 9 &&
- phone_number.match( /^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/ );
-}, "Please specify a valid phone number" );
-
-/**
- * Matches US phone number format
- *
- * where the area code may not start with 1 and the prefix may not start with 1
- * allows '-' or ' ' as a separator and allows parens around area code
- * some people may want to put a '1' in front of their number
- *
- * 1(212)-999-2345 or
- * 212 999 2344 or
- * 212-999-0983
- *
- * but not
- * 111-123-5434
- * and not
- * 212 123 4567
- */
-$.validator.addMethod( "phoneUS", function( phone_number, element ) {
- phone_number = phone_number.replace( /\s+/g, "" );
- return this.optional( element ) || phone_number.length > 9 &&
- phone_number.match( /^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/ );
-}, "Please specify a valid phone number" );
-
-/*
-* Valida CEPs do brasileiros:
-*
-* Formatos aceitos:
-* 99999-999
-* 99.999-999
-* 99999999
-*/
-$.validator.addMethod( "postalcodeBR", function( cep_value, element ) {
- return this.optional( element ) || /^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test( cep_value );
-}, "Informe um CEP válido." );
-
-/**
- * Matches a valid Canadian Postal Code
- *
- * @example jQuery.validator.methods.postalCodeCA( "H0H 0H0", element )
- * @result true
- *
- * @example jQuery.validator.methods.postalCodeCA( "H0H0H0", element )
- * @result false
- *
- * @name jQuery.validator.methods.postalCodeCA
- * @type Boolean
- * @cat Plugins/Validate/Methods
- */
-$.validator.addMethod( "postalCodeCA", function( value, element ) {
- return this.optional( element ) || /^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test( value );
-}, "Please specify a valid postal code" );
-
-/* Matches Italian postcode (CAP) */
-$.validator.addMethod( "postalcodeIT", function( value, element ) {
- return this.optional( element ) || /^\d{5}$/.test( value );
-}, "Please specify a valid postal code" );
-
-$.validator.addMethod( "postalcodeNL", function( value, element ) {
- return this.optional( element ) || /^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test( value );
-}, "Please specify a valid postal code" );
-
-// Matches UK postcode. Does not match to UK Channel Islands that have their own postcodes (non standard UK)
-$.validator.addMethod( "postcodeUK", function( value, element ) {
- return this.optional( element ) || /^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test( value );
-}, "Please specify a valid UK postcode" );
-
-/*
- * Lets you say "at least X inputs that match selector Y must be filled."
- *
- * The end result is that neither of these inputs:
- *
- *
- *
- *
- * ...will validate unless at least one of them is filled.
- *
- * partnumber: {require_from_group: [1,".productinfo"]},
- * description: {require_from_group: [1,".productinfo"]}
- *
- * options[0]: number of fields that must be filled in the group
- * options[1]: CSS selector that defines the group of conditionally required fields
- */
-$.validator.addMethod( "require_from_group", function( value, element, options ) {
- var $fields = $( options[ 1 ], element.form ),
- $fieldsFirst = $fields.eq( 0 ),
- validator = $fieldsFirst.data( "valid_req_grp" ) ? $fieldsFirst.data( "valid_req_grp" ) : $.extend( {}, this ),
- isValid = $fields.filter( function() {
- return validator.elementValue( this );
- } ).length >= options[ 0 ];
-
- // Store the cloned validator for future validation
- $fieldsFirst.data( "valid_req_grp", validator );
-
- // If element isn't being validated, run each require_from_group field's validation rules
- if ( !$( element ).data( "being_validated" ) ) {
- $fields.data( "being_validated", true );
- $fields.each( function() {
- validator.element( this );
- } );
- $fields.data( "being_validated", false );
- }
- return isValid;
-}, $.validator.format( "Please fill at least {0} of these fields." ) );
-
-/*
- * Lets you say "either at least X inputs that match selector Y must be filled,
- * OR they must all be skipped (left blank)."
- *
- * The end result, is that none of these inputs:
- *
- *
- *
- *
- *
- * ...will validate unless either at least two of them are filled,
- * OR none of them are.
- *
- * partnumber: {skip_or_fill_minimum: [2,".productinfo"]},
- * description: {skip_or_fill_minimum: [2,".productinfo"]},
- * color: {skip_or_fill_minimum: [2,".productinfo"]}
- *
- * options[0]: number of fields that must be filled in the group
- * options[1]: CSS selector that defines the group of conditionally required fields
- *
- */
-$.validator.addMethod( "skip_or_fill_minimum", function( value, element, options ) {
- var $fields = $( options[ 1 ], element.form ),
- $fieldsFirst = $fields.eq( 0 ),
- validator = $fieldsFirst.data( "valid_skip" ) ? $fieldsFirst.data( "valid_skip" ) : $.extend( {}, this ),
- numberFilled = $fields.filter( function() {
- return validator.elementValue( this );
- } ).length,
- isValid = numberFilled === 0 || numberFilled >= options[ 0 ];
-
- // Store the cloned validator for future validation
- $fieldsFirst.data( "valid_skip", validator );
-
- // If element isn't being validated, run each skip_or_fill_minimum field's validation rules
- if ( !$( element ).data( "being_validated" ) ) {
- $fields.data( "being_validated", true );
- $fields.each( function() {
- validator.element( this );
- } );
- $fields.data( "being_validated", false );
- }
- return isValid;
-}, $.validator.format( "Please either skip these fields or fill at least {0} of them." ) );
-
-/* Validates US States and/or Territories by @jdforsythe
- * Can be case insensitive or require capitalization - default is case insensitive
- * Can include US Territories or not - default does not
- * Can include US Military postal abbreviations (AA, AE, AP) - default does not
- *
- * Note: "States" always includes DC (District of Colombia)
- *
- * Usage examples:
- *
- * This is the default - case insensitive, no territories, no military zones
- * stateInput: {
- * caseSensitive: false,
- * includeTerritories: false,
- * includeMilitary: false
- * }
- *
- * Only allow capital letters, no territories, no military zones
- * stateInput: {
- * caseSensitive: false
- * }
- *
- * Case insensitive, include territories but not military zones
- * stateInput: {
- * includeTerritories: true
- * }
- *
- * Only allow capital letters, include territories and military zones
- * stateInput: {
- * caseSensitive: true,
- * includeTerritories: true,
- * includeMilitary: true
- * }
- *
- */
-$.validator.addMethod( "stateUS", function( value, element, options ) {
- var isDefault = typeof options === "undefined",
- caseSensitive = ( isDefault || typeof options.caseSensitive === "undefined" ) ? false : options.caseSensitive,
- includeTerritories = ( isDefault || typeof options.includeTerritories === "undefined" ) ? false : options.includeTerritories,
- includeMilitary = ( isDefault || typeof options.includeMilitary === "undefined" ) ? false : options.includeMilitary,
- regex;
-
- if ( !includeTerritories && !includeMilitary ) {
- regex = "^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
- } else if ( includeTerritories && includeMilitary ) {
- regex = "^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
- } else if ( includeTerritories ) {
- regex = "^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$";
- } else {
- regex = "^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$";
- }
-
- regex = caseSensitive ? new RegExp( regex ) : new RegExp( regex, "i" );
- return this.optional( element ) || regex.test( value );
-}, "Please specify a valid state" );
-
-// TODO check if value starts with <, otherwise don't try stripping anything
-$.validator.addMethod( "strippedminlength", function( value, element, param ) {
- return $( value ).text().length >= param;
-}, $.validator.format( "Please enter at least {0} characters" ) );
-
-$.validator.addMethod( "time", function( value, element ) {
- return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value );
-}, "Please enter a valid time, between 00:00 and 23:59" );
-
-$.validator.addMethod( "time12h", function( value, element ) {
- return this.optional( element ) || /^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test( value );
-}, "Please enter a valid time in 12-hour am/pm format" );
-
-// Same as url, but TLD is optional
-$.validator.addMethod( "url2", function( value, element ) {
- return this.optional( element ) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test( value );
-}, $.validator.messages.url );
-
-/**
- * Return true, if the value is a valid vehicle identification number (VIN).
- *
- * Works with all kind of text inputs.
- *
- * @example
- * @desc Declares a required input element whose value must be a valid vehicle identification number.
- *
- * @name $.validator.methods.vinUS
- * @type Boolean
- * @cat Plugins/Validate/Methods
- */
-$.validator.addMethod( "vinUS", function( v ) {
- if ( v.length !== 17 ) {
- return false;
- }
-
- var LL = [ "A", "B", "C", "D", "E", "F", "G", "H", "J", "K", "L", "M", "N", "P", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" ],
- VL = [ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 7, 9, 2, 3, 4, 5, 6, 7, 8, 9 ],
- FL = [ 8, 7, 6, 5, 4, 3, 2, 10, 0, 9, 8, 7, 6, 5, 4, 3, 2 ],
- rs = 0,
- i, n, d, f, cd, cdv;
-
- for ( i = 0; i < 17; i++ ) {
- f = FL[ i ];
- d = v.slice( i, i + 1 );
- if ( i === 8 ) {
- cdv = d;
- }
- if ( !isNaN( d ) ) {
- d *= f;
- } else {
- for ( n = 0; n < LL.length; n++ ) {
- if ( d.toUpperCase() === LL[ n ] ) {
- d = VL[ n ];
- d *= f;
- if ( isNaN( cdv ) && n === 8 ) {
- cdv = LL[ n ];
- }
- break;
- }
- }
- }
- rs += d;
- }
- cd = rs % 11;
- if ( cd === 10 ) {
- cd = "X";
- }
- if ( cd === cdv ) {
- return true;
- }
- return false;
-}, "The specified vehicle identification number (VIN) is invalid." );
-
-$.validator.addMethod( "zipcodeUS", function( value, element ) {
- return this.optional( element ) || /^\d{5}(-\d{4})?$/.test( value );
-}, "The specified US ZIP Code is invalid" );
-
-$.validator.addMethod( "ziprange", function( value, element ) {
- return this.optional( element ) || /^90[2-5]\d\{2\}-\d{4}$/.test( value );
-}, "Your ZIP-code must be in the range 902xx-xxxx to 905xx-xxxx" );
-return $;
-}));
\ No newline at end of file
diff --git a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/additional-methods.min.js b/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
deleted file mode 100644
index 5d127b85..00000000
--- a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/additional-methods.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery Validation Plugin - v1.17.0 - 7/29/2017
- * https://jqueryvalidation.org/
- * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */
-!function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){return function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g,h="string"==typeof d?d.replace(/\s/g,""):"image/*",i=this.optional(c);if(i)return i;if("file"===a(c).attr("type")&&(h=h.replace(/[\-\[\]\/\{\}\(\)\+\?\.\\\^\$\|]/g,"\\$&").replace(/,/g,"|").replace(/\/\*/g,"/.*"),c.files&&c.files.length))for(g=new RegExp(".?("+h+")$","i"),e=0;e9?"0":f,g="JABCDEFGHI".substr(f,1).toString(),i.match(/[ABEH]/)?k===f:i.match(/[KPQS]/)?k===g:k===f||k===g},"Please specify a valid CIF number."),a.validator.addMethod("cpfBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f=0;if(b=parseInt(a.substring(9,10),10),c=parseInt(a.substring(10,11),10),d=function(a,b){var c=10*a%11;return 10!==c&&11!==c||(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(e=1;e<=9;e++)f+=parseInt(a.substring(e-1,e),10)*(11-e);if(d(f,b)){for(f=0,e=1;e<=10;e++)f+=parseInt(a.substring(e-1,e),10)*(12-e);return d(f,c)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcard",function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},"Please enter a valid credit card number."),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:!!(128&d)},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=!!e||c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="",q=5;if(l.length9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("netmask",function(a,b){return this.optional(b)||/^(254|252|248|240|224|192|128)\.0\.0\.0|255\.(254|252|248|240|224|192|128|0)\.0\.0|255\.255\.(254|252|248|240|224|192|128|0)\.0|255\.255\.255\.(254|252|248|240|224|192|128|0)/i.test(a)},"Please enter a valid netmask."),a.validator.addMethod("nieES",function(a,b){"use strict";if(this.optional(b))return!0;var c,d=new RegExp(/^[MXYZ]{1}[0-9]{7,8}[TRWAGMYFPDXBNJZSQVHLCKET]{1}$/gi),e="TRWAGMYFPDXBNJZSQVHLCKET",f=a.substr(a.length-1).toUpperCase();return a=a.toString().toUpperCase(),!(a.length>10||a.length<9||!d.test(a))&&(a=a.replace(/^[X]/,"0").replace(/^[Y]/,"1").replace(/^[Z]/,"2"),c=9===a.length?a.substr(0,8):a.substr(0,9),e.charAt(parseInt(c,10)%23)===f)},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a,b){"use strict";return!!this.optional(b)||(a=a.toUpperCase(),!!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")&&(/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):!!/^[KLM]{1}/.test(a)&&a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,1)%23)))},"Please specify a valid NIF number."),a.validator.addMethod("nipPL",function(a){"use strict";if(a=a.replace(/[^0-9]/g,""),10!==a.length)return!1;for(var b=[6,5,7,2,3,4,5,6,7],c=0,d=0;d<9;d++)c+=b[d]*a[d];var e=c%11,f=10===e?0:e;return f===parseInt(a[9],10)},"Please specify a valid NIP number."),a.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return!!this.optional(b)||("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ] *\d[ABCEGHJKLMNPRSTVWXYZ]\d$/i.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=!e&&"undefined"!=typeof c.caseSensitive&&c.caseSensitive,g=!e&&"undefined"!=typeof c.includeTerritories&&c.includeTerritories,h=!e&&"undefined"!=typeof c.includeMilitary&&c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;b<17;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c" )
- .attr( "name", validator.submitButton.name )
- .val( $( validator.submitButton ).val() )
- .appendTo( validator.currentForm );
- }
-
- if ( validator.settings.submitHandler ) {
- result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
- if ( hidden ) {
-
- // And clean up afterwards; thanks to no-block-scope, hidden can be referenced
- hidden.remove();
- }
- if ( result !== undefined ) {
- return result;
- }
- return false;
- }
- return true;
- }
-
- // Prevent submit for invalid forms or custom submit handlers
- if ( validator.cancelSubmit ) {
- validator.cancelSubmit = false;
- return handle();
- }
- if ( validator.form() ) {
- if ( validator.pendingRequest ) {
- validator.formSubmitted = true;
- return false;
- }
- return handle();
- } else {
- validator.focusInvalid();
- return false;
- }
- } );
- }
-
- return validator;
- },
-
- // https://jqueryvalidation.org/valid/
- valid: function() {
- var valid, validator, errorList;
-
- if ( $( this[ 0 ] ).is( "form" ) ) {
- valid = this.validate().form();
- } else {
- errorList = [];
- valid = true;
- validator = $( this[ 0 ].form ).validate();
- this.each( function() {
- valid = validator.element( this ) && valid;
- if ( !valid ) {
- errorList = errorList.concat( validator.errorList );
- }
- } );
- validator.errorList = errorList;
- }
- return valid;
- },
-
- // https://jqueryvalidation.org/rules/
- rules: function( command, argument ) {
- var element = this[ 0 ],
- settings, staticRules, existingRules, data, param, filtered;
-
- // If nothing is selected, return empty object; can't chain anyway
- if ( element == null ) {
- return;
- }
-
- if ( !element.form && element.hasAttribute( "contenteditable" ) ) {
- element.form = this.closest( "form" )[ 0 ];
- element.name = this.attr( "name" );
- }
-
- if ( element.form == null ) {
- return;
- }
-
- if ( command ) {
- settings = $.data( element.form, "validator" ).settings;
- staticRules = settings.rules;
- existingRules = $.validator.staticRules( element );
- switch ( command ) {
- case "add":
- $.extend( existingRules, $.validator.normalizeRule( argument ) );
-
- // Remove messages from rules, but allow them to be set separately
- delete existingRules.messages;
- staticRules[ element.name ] = existingRules;
- if ( argument.messages ) {
- settings.messages[ element.name ] = $.extend( settings.messages[ element.name ], argument.messages );
- }
- break;
- case "remove":
- if ( !argument ) {
- delete staticRules[ element.name ];
- return existingRules;
- }
- filtered = {};
- $.each( argument.split( /\s/ ), function( index, method ) {
- filtered[ method ] = existingRules[ method ];
- delete existingRules[ method ];
- } );
- return filtered;
- }
- }
-
- data = $.validator.normalizeRules(
- $.extend(
- {},
- $.validator.classRules( element ),
- $.validator.attributeRules( element ),
- $.validator.dataRules( element ),
- $.validator.staticRules( element )
- ), element );
-
- // Make sure required is at front
- if ( data.required ) {
- param = data.required;
- delete data.required;
- data = $.extend( { required: param }, data );
- }
-
- // Make sure remote is at back
- if ( data.remote ) {
- param = data.remote;
- delete data.remote;
- data = $.extend( data, { remote: param } );
- }
-
- return data;
- }
-} );
-
-// Custom selectors
-$.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
-
- // https://jqueryvalidation.org/blank-selector/
- blank: function( a ) {
- return !$.trim( "" + $( a ).val() );
- },
-
- // https://jqueryvalidation.org/filled-selector/
- filled: function( a ) {
- var val = $( a ).val();
- return val !== null && !!$.trim( "" + val );
- },
-
- // https://jqueryvalidation.org/unchecked-selector/
- unchecked: function( a ) {
- return !$( a ).prop( "checked" );
- }
-} );
-
-// Constructor for validator
-$.validator = function( options, form ) {
- this.settings = $.extend( true, {}, $.validator.defaults, options );
- this.currentForm = form;
- this.init();
-};
-
-// https://jqueryvalidation.org/jQuery.validator.format/
-$.validator.format = function( source, params ) {
- if ( arguments.length === 1 ) {
- return function() {
- var args = $.makeArray( arguments );
- args.unshift( source );
- return $.validator.format.apply( this, args );
- };
- }
- if ( params === undefined ) {
- return source;
- }
- if ( arguments.length > 2 && params.constructor !== Array ) {
- params = $.makeArray( arguments ).slice( 1 );
- }
- if ( params.constructor !== Array ) {
- params = [ params ];
- }
- $.each( params, function( i, n ) {
- source = source.replace( new RegExp( "\\{" + i + "\\}", "g" ), function() {
- return n;
- } );
- } );
- return source;
-};
-
-$.extend( $.validator, {
-
- defaults: {
- messages: {},
- groups: {},
- rules: {},
- errorClass: "error",
- pendingClass: "pending",
- validClass: "valid",
- errorElement: "label",
- focusCleanup: false,
- focusInvalid: true,
- errorContainer: $( [] ),
- errorLabelContainer: $( [] ),
- onsubmit: true,
- ignore: ":hidden",
- ignoreTitle: false,
- onfocusin: function( element ) {
- this.lastActive = element;
-
- // Hide error label and remove error class on focus if enabled
- if ( this.settings.focusCleanup ) {
- if ( this.settings.unhighlight ) {
- this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
- }
- this.hideThese( this.errorsFor( element ) );
- }
- },
- onfocusout: function( element ) {
- if ( !this.checkable( element ) && ( element.name in this.submitted || !this.optional( element ) ) ) {
- this.element( element );
- }
- },
- onkeyup: function( element, event ) {
-
- // Avoid revalidate the field when pressing one of the following keys
- // Shift => 16
- // Ctrl => 17
- // Alt => 18
- // Caps lock => 20
- // End => 35
- // Home => 36
- // Left arrow => 37
- // Up arrow => 38
- // Right arrow => 39
- // Down arrow => 40
- // Insert => 45
- // Num lock => 144
- // AltGr key => 225
- var excludedKeys = [
- 16, 17, 18, 20, 35, 36, 37,
- 38, 39, 40, 45, 144, 225
- ];
-
- if ( event.which === 9 && this.elementValue( element ) === "" || $.inArray( event.keyCode, excludedKeys ) !== -1 ) {
- return;
- } else if ( element.name in this.submitted || element.name in this.invalid ) {
- this.element( element );
- }
- },
- onclick: function( element ) {
-
- // Click on selects, radiobuttons and checkboxes
- if ( element.name in this.submitted ) {
- this.element( element );
-
- // Or option elements, check parent select in that case
- } else if ( element.parentNode.name in this.submitted ) {
- this.element( element.parentNode );
- }
- },
- highlight: function( element, errorClass, validClass ) {
- if ( element.type === "radio" ) {
- this.findByName( element.name ).addClass( errorClass ).removeClass( validClass );
- } else {
- $( element ).addClass( errorClass ).removeClass( validClass );
- }
- },
- unhighlight: function( element, errorClass, validClass ) {
- if ( element.type === "radio" ) {
- this.findByName( element.name ).removeClass( errorClass ).addClass( validClass );
- } else {
- $( element ).removeClass( errorClass ).addClass( validClass );
- }
- }
- },
-
- // https://jqueryvalidation.org/jQuery.validator.setDefaults/
- setDefaults: function( settings ) {
- $.extend( $.validator.defaults, settings );
- },
-
- messages: {
- required: "This field is required.",
- remote: "Please fix this field.",
- email: "Please enter a valid email address.",
- url: "Please enter a valid URL.",
- date: "Please enter a valid date.",
- dateISO: "Please enter a valid date (ISO).",
- number: "Please enter a valid number.",
- digits: "Please enter only digits.",
- equalTo: "Please enter the same value again.",
- maxlength: $.validator.format( "Please enter no more than {0} characters." ),
- minlength: $.validator.format( "Please enter at least {0} characters." ),
- rangelength: $.validator.format( "Please enter a value between {0} and {1} characters long." ),
- range: $.validator.format( "Please enter a value between {0} and {1}." ),
- max: $.validator.format( "Please enter a value less than or equal to {0}." ),
- min: $.validator.format( "Please enter a value greater than or equal to {0}." ),
- step: $.validator.format( "Please enter a multiple of {0}." )
- },
-
- autoCreateRanges: false,
-
- prototype: {
-
- init: function() {
- this.labelContainer = $( this.settings.errorLabelContainer );
- this.errorContext = this.labelContainer.length && this.labelContainer || $( this.currentForm );
- this.containers = $( this.settings.errorContainer ).add( this.settings.errorLabelContainer );
- this.submitted = {};
- this.valueCache = {};
- this.pendingRequest = 0;
- this.pending = {};
- this.invalid = {};
- this.reset();
-
- var groups = ( this.groups = {} ),
- rules;
- $.each( this.settings.groups, function( key, value ) {
- if ( typeof value === "string" ) {
- value = value.split( /\s/ );
- }
- $.each( value, function( index, name ) {
- groups[ name ] = key;
- } );
- } );
- rules = this.settings.rules;
- $.each( rules, function( key, value ) {
- rules[ key ] = $.validator.normalizeRule( value );
- } );
-
- function delegate( event ) {
-
- // Set form expando on contenteditable
- if ( !this.form && this.hasAttribute( "contenteditable" ) ) {
- this.form = $( this ).closest( "form" )[ 0 ];
- this.name = $( this ).attr( "name" );
- }
-
- var validator = $.data( this.form, "validator" ),
- eventType = "on" + event.type.replace( /^validate/, "" ),
- settings = validator.settings;
- if ( settings[ eventType ] && !$( this ).is( settings.ignore ) ) {
- settings[ eventType ].call( validator, this, event );
- }
- }
-
- $( this.currentForm )
- .on( "focusin.validate focusout.validate keyup.validate",
- ":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], " +
- "[type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], " +
- "[type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], " +
- "[type='radio'], [type='checkbox'], [contenteditable], [type='button']", delegate )
-
- // Support: Chrome, oldIE
- // "select" is provided as event.target when clicking a option
- .on( "click.validate", "select, option, [type='radio'], [type='checkbox']", delegate );
-
- if ( this.settings.invalidHandler ) {
- $( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
- }
- },
-
- // https://jqueryvalidation.org/Validator.form/
- form: function() {
- this.checkForm();
- $.extend( this.submitted, this.errorMap );
- this.invalid = $.extend( {}, this.errorMap );
- if ( !this.valid() ) {
- $( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
- }
- this.showErrors();
- return this.valid();
- },
-
- checkForm: function() {
- this.prepareForm();
- for ( var i = 0, elements = ( this.currentElements = this.elements() ); elements[ i ]; i++ ) {
- this.check( elements[ i ] );
- }
- return this.valid();
- },
-
- // https://jqueryvalidation.org/Validator.element/
- element: function( element ) {
- var cleanElement = this.clean( element ),
- checkElement = this.validationTargetFor( cleanElement ),
- v = this,
- result = true,
- rs, group;
-
- if ( checkElement === undefined ) {
- delete this.invalid[ cleanElement.name ];
- } else {
- this.prepareElement( checkElement );
- this.currentElements = $( checkElement );
-
- // If this element is grouped, then validate all group elements already
- // containing a value
- group = this.groups[ checkElement.name ];
- if ( group ) {
- $.each( this.groups, function( name, testgroup ) {
- if ( testgroup === group && name !== checkElement.name ) {
- cleanElement = v.validationTargetFor( v.clean( v.findByName( name ) ) );
- if ( cleanElement && cleanElement.name in v.invalid ) {
- v.currentElements.push( cleanElement );
- result = v.check( cleanElement ) && result;
- }
- }
- } );
- }
-
- rs = this.check( checkElement ) !== false;
- result = result && rs;
- if ( rs ) {
- this.invalid[ checkElement.name ] = false;
- } else {
- this.invalid[ checkElement.name ] = true;
- }
-
- if ( !this.numberOfInvalids() ) {
-
- // Hide error containers on last error
- this.toHide = this.toHide.add( this.containers );
- }
- this.showErrors();
-
- // Add aria-invalid status for screen readers
- $( element ).attr( "aria-invalid", !rs );
- }
-
- return result;
- },
-
- // https://jqueryvalidation.org/Validator.showErrors/
- showErrors: function( errors ) {
- if ( errors ) {
- var validator = this;
-
- // Add items to error list and map
- $.extend( this.errorMap, errors );
- this.errorList = $.map( this.errorMap, function( message, name ) {
- return {
- message: message,
- element: validator.findByName( name )[ 0 ]
- };
- } );
-
- // Remove items from success list
- this.successList = $.grep( this.successList, function( element ) {
- return !( element.name in errors );
- } );
- }
- if ( this.settings.showErrors ) {
- this.settings.showErrors.call( this, this.errorMap, this.errorList );
- } else {
- this.defaultShowErrors();
- }
- },
-
- // https://jqueryvalidation.org/Validator.resetForm/
- resetForm: function() {
- if ( $.fn.resetForm ) {
- $( this.currentForm ).resetForm();
- }
- this.invalid = {};
- this.submitted = {};
- this.prepareForm();
- this.hideErrors();
- var elements = this.elements()
- .removeData( "previousValue" )
- .removeAttr( "aria-invalid" );
-
- this.resetElements( elements );
- },
-
- resetElements: function( elements ) {
- var i;
-
- if ( this.settings.unhighlight ) {
- for ( i = 0; elements[ i ]; i++ ) {
- this.settings.unhighlight.call( this, elements[ i ],
- this.settings.errorClass, "" );
- this.findByName( elements[ i ].name ).removeClass( this.settings.validClass );
- }
- } else {
- elements
- .removeClass( this.settings.errorClass )
- .removeClass( this.settings.validClass );
- }
- },
-
- numberOfInvalids: function() {
- return this.objectLength( this.invalid );
- },
-
- objectLength: function( obj ) {
- /* jshint unused: false */
- var count = 0,
- i;
- for ( i in obj ) {
-
- // This check allows counting elements with empty error
- // message as invalid elements
- if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
- count++;
- }
- }
- return count;
- },
-
- hideErrors: function() {
- this.hideThese( this.toHide );
- },
-
- hideThese: function( errors ) {
- errors.not( this.containers ).text( "" );
- this.addWrapper( errors ).hide();
- },
-
- valid: function() {
- return this.size() === 0;
- },
-
- size: function() {
- return this.errorList.length;
- },
-
- focusInvalid: function() {
- if ( this.settings.focusInvalid ) {
- try {
- $( this.findLastActive() || this.errorList.length && this.errorList[ 0 ].element || [] )
- .filter( ":visible" )
- .focus()
-
- // Manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
- .trigger( "focusin" );
- } catch ( e ) {
-
- // Ignore IE throwing errors when focusing hidden elements
- }
- }
- },
-
- findLastActive: function() {
- var lastActive = this.lastActive;
- return lastActive && $.grep( this.errorList, function( n ) {
- return n.element.name === lastActive.name;
- } ).length === 1 && lastActive;
- },
-
- elements: function() {
- var validator = this,
- rulesCache = {};
-
- // Select all valid inputs inside the form (no submit or reset buttons)
- return $( this.currentForm )
- .find( "input, select, textarea, [contenteditable]" )
- .not( ":submit, :reset, :image, :disabled" )
- .not( this.settings.ignore )
- .filter( function() {
- var name = this.name || $( this ).attr( "name" ); // For contenteditable
- if ( !name && validator.settings.debug && window.console ) {
- console.error( "%o has no name assigned", this );
- }
-
- // Set form expando on contenteditable
- if ( this.hasAttribute( "contenteditable" ) ) {
- this.form = $( this ).closest( "form" )[ 0 ];
- this.name = name;
- }
-
- // Select only the first element for each name, and only those with rules specified
- if ( name in rulesCache || !validator.objectLength( $( this ).rules() ) ) {
- return false;
- }
-
- rulesCache[ name ] = true;
- return true;
- } );
- },
-
- clean: function( selector ) {
- return $( selector )[ 0 ];
- },
-
- errors: function() {
- var errorClass = this.settings.errorClass.split( " " ).join( "." );
- return $( this.settings.errorElement + "." + errorClass, this.errorContext );
- },
-
- resetInternals: function() {
- this.successList = [];
- this.errorList = [];
- this.errorMap = {};
- this.toShow = $( [] );
- this.toHide = $( [] );
- },
-
- reset: function() {
- this.resetInternals();
- this.currentElements = $( [] );
- },
-
- prepareForm: function() {
- this.reset();
- this.toHide = this.errors().add( this.containers );
- },
-
- prepareElement: function( element ) {
- this.reset();
- this.toHide = this.errorsFor( element );
- },
-
- elementValue: function( element ) {
- var $element = $( element ),
- type = element.type,
- val, idx;
-
- if ( type === "radio" || type === "checkbox" ) {
- return this.findByName( element.name ).filter( ":checked" ).val();
- } else if ( type === "number" && typeof element.validity !== "undefined" ) {
- return element.validity.badInput ? "NaN" : $element.val();
- }
-
- if ( element.hasAttribute( "contenteditable" ) ) {
- val = $element.text();
- } else {
- val = $element.val();
- }
-
- if ( type === "file" ) {
-
- // Modern browser (chrome & safari)
- if ( val.substr( 0, 12 ) === "C:\\fakepath\\" ) {
- return val.substr( 12 );
- }
-
- // Legacy browsers
- // Unix-based path
- idx = val.lastIndexOf( "/" );
- if ( idx >= 0 ) {
- return val.substr( idx + 1 );
- }
-
- // Windows-based path
- idx = val.lastIndexOf( "\\" );
- if ( idx >= 0 ) {
- return val.substr( idx + 1 );
- }
-
- // Just the file name
- return val;
- }
-
- if ( typeof val === "string" ) {
- return val.replace( /\r/g, "" );
- }
- return val;
- },
-
- check: function( element ) {
- element = this.validationTargetFor( this.clean( element ) );
-
- var rules = $( element ).rules(),
- rulesCount = $.map( rules, function( n, i ) {
- return i;
- } ).length,
- dependencyMismatch = false,
- val = this.elementValue( element ),
- result, method, rule, normalizer;
-
- // Prioritize the local normalizer defined for this element over the global one
- // if the former exists, otherwise user the global one in case it exists.
- if ( typeof rules.normalizer === "function" ) {
- normalizer = rules.normalizer;
- } else if ( typeof this.settings.normalizer === "function" ) {
- normalizer = this.settings.normalizer;
- }
-
- // If normalizer is defined, then call it to retreive the changed value instead
- // of using the real one.
- // Note that `this` in the normalizer is `element`.
- if ( normalizer ) {
- val = normalizer.call( element, val );
-
- if ( typeof val !== "string" ) {
- throw new TypeError( "The normalizer should return a string value." );
- }
-
- // Delete the normalizer from rules to avoid treating it as a pre-defined method.
- delete rules.normalizer;
- }
-
- for ( method in rules ) {
- rule = { method: method, parameters: rules[ method ] };
- try {
- result = $.validator.methods[ method ].call( this, val, element, rule.parameters );
-
- // If a method indicates that the field is optional and therefore valid,
- // don't mark it as valid when there are no other rules
- if ( result === "dependency-mismatch" && rulesCount === 1 ) {
- dependencyMismatch = true;
- continue;
- }
- dependencyMismatch = false;
-
- if ( result === "pending" ) {
- this.toHide = this.toHide.not( this.errorsFor( element ) );
- return;
- }
-
- if ( !result ) {
- this.formatAndAdd( element, rule );
- return false;
- }
- } catch ( e ) {
- if ( this.settings.debug && window.console ) {
- console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
- }
- if ( e instanceof TypeError ) {
- e.message += ". Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.";
- }
-
- throw e;
- }
- }
- if ( dependencyMismatch ) {
- return;
- }
- if ( this.objectLength( rules ) ) {
- this.successList.push( element );
- }
- return true;
- },
-
- // Return the custom message for the given element and validation method
- // specified in the element's HTML5 data attribute
- // return the generic message if present and no method specific message is present
- customDataMessage: function( element, method ) {
- return $( element ).data( "msg" + method.charAt( 0 ).toUpperCase() +
- method.substring( 1 ).toLowerCase() ) || $( element ).data( "msg" );
- },
-
- // Return the custom message for the given element name and validation method
- customMessage: function( name, method ) {
- var m = this.settings.messages[ name ];
- return m && ( m.constructor === String ? m : m[ method ] );
- },
-
- // Return the first defined argument, allowing empty strings
- findDefined: function() {
- for ( var i = 0; i < arguments.length; i++ ) {
- if ( arguments[ i ] !== undefined ) {
- return arguments[ i ];
- }
- }
- return undefined;
- },
-
- // The second parameter 'rule' used to be a string, and extended to an object literal
- // of the following form:
- // rule = {
- // method: "method name",
- // parameters: "the given method parameters"
- // }
- //
- // The old behavior still supported, kept to maintain backward compatibility with
- // old code, and will be removed in the next major release.
- defaultMessage: function( element, rule ) {
- if ( typeof rule === "string" ) {
- rule = { method: rule };
- }
-
- var message = this.findDefined(
- this.customMessage( element.name, rule.method ),
- this.customDataMessage( element, rule.method ),
-
- // 'title' is never undefined, so handle empty string as undefined
- !this.settings.ignoreTitle && element.title || undefined,
- $.validator.messages[ rule.method ],
- "Warning: No message defined for " + element.name + ""
- ),
- theregex = /\$?\{(\d+)\}/g;
- if ( typeof message === "function" ) {
- message = message.call( this, rule.parameters, element );
- } else if ( theregex.test( message ) ) {
- message = $.validator.format( message.replace( theregex, "{$1}" ), rule.parameters );
- }
-
- return message;
- },
-
- formatAndAdd: function( element, rule ) {
- var message = this.defaultMessage( element, rule );
-
- this.errorList.push( {
- message: message,
- element: element,
- method: rule.method
- } );
-
- this.errorMap[ element.name ] = message;
- this.submitted[ element.name ] = message;
- },
-
- addWrapper: function( toToggle ) {
- if ( this.settings.wrapper ) {
- toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
- }
- return toToggle;
- },
-
- defaultShowErrors: function() {
- var i, elements, error;
- for ( i = 0; this.errorList[ i ]; i++ ) {
- error = this.errorList[ i ];
- if ( this.settings.highlight ) {
- this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
- }
- this.showLabel( error.element, error.message );
- }
- if ( this.errorList.length ) {
- this.toShow = this.toShow.add( this.containers );
- }
- if ( this.settings.success ) {
- for ( i = 0; this.successList[ i ]; i++ ) {
- this.showLabel( this.successList[ i ] );
- }
- }
- if ( this.settings.unhighlight ) {
- for ( i = 0, elements = this.validElements(); elements[ i ]; i++ ) {
- this.settings.unhighlight.call( this, elements[ i ], this.settings.errorClass, this.settings.validClass );
- }
- }
- this.toHide = this.toHide.not( this.toShow );
- this.hideErrors();
- this.addWrapper( this.toShow ).show();
- },
-
- validElements: function() {
- return this.currentElements.not( this.invalidElements() );
- },
-
- invalidElements: function() {
- return $( this.errorList ).map( function() {
- return this.element;
- } );
- },
-
- showLabel: function( element, message ) {
- var place, group, errorID, v,
- error = this.errorsFor( element ),
- elementID = this.idOrName( element ),
- describedBy = $( element ).attr( "aria-describedby" );
-
- if ( error.length ) {
-
- // Refresh error/success class
- error.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
-
- // Replace message on existing label
- error.html( message );
- } else {
-
- // Create error element
- error = $( "<" + this.settings.errorElement + ">" )
- .attr( "id", elementID + "-error" )
- .addClass( this.settings.errorClass )
- .html( message || "" );
-
- // Maintain reference to the element to be placed into the DOM
- place = error;
- if ( this.settings.wrapper ) {
-
- // Make sure the element is visible, even in IE
- // actually showing the wrapped element is handled elsewhere
- place = error.hide().show().wrap( "<" + this.settings.wrapper + "/>" ).parent();
- }
- if ( this.labelContainer.length ) {
- this.labelContainer.append( place );
- } else if ( this.settings.errorPlacement ) {
- this.settings.errorPlacement.call( this, place, $( element ) );
- } else {
- place.insertAfter( element );
- }
-
- // Link error back to the element
- if ( error.is( "label" ) ) {
-
- // If the error is a label, then associate using 'for'
- error.attr( "for", elementID );
-
- // If the element is not a child of an associated label, then it's necessary
- // to explicitly apply aria-describedby
- } else if ( error.parents( "label[for='" + this.escapeCssMeta( elementID ) + "']" ).length === 0 ) {
- errorID = error.attr( "id" );
-
- // Respect existing non-error aria-describedby
- if ( !describedBy ) {
- describedBy = errorID;
- } else if ( !describedBy.match( new RegExp( "\\b" + this.escapeCssMeta( errorID ) + "\\b" ) ) ) {
-
- // Add to end of list if not already present
- describedBy += " " + errorID;
- }
- $( element ).attr( "aria-describedby", describedBy );
-
- // If this element is grouped, then assign to all elements in the same group
- group = this.groups[ element.name ];
- if ( group ) {
- v = this;
- $.each( v.groups, function( name, testgroup ) {
- if ( testgroup === group ) {
- $( "[name='" + v.escapeCssMeta( name ) + "']", v.currentForm )
- .attr( "aria-describedby", error.attr( "id" ) );
- }
- } );
- }
- }
- }
- if ( !message && this.settings.success ) {
- error.text( "" );
- if ( typeof this.settings.success === "string" ) {
- error.addClass( this.settings.success );
- } else {
- this.settings.success( error, element );
- }
- }
- this.toShow = this.toShow.add( error );
- },
-
- errorsFor: function( element ) {
- var name = this.escapeCssMeta( this.idOrName( element ) ),
- describer = $( element ).attr( "aria-describedby" ),
- selector = "label[for='" + name + "'], label[for='" + name + "'] *";
-
- // 'aria-describedby' should directly reference the error element
- if ( describer ) {
- selector = selector + ", #" + this.escapeCssMeta( describer )
- .replace( /\s+/g, ", #" );
- }
-
- return this
- .errors()
- .filter( selector );
- },
-
- // See https://api.jquery.com/category/selectors/, for CSS
- // meta-characters that should be escaped in order to be used with JQuery
- // as a literal part of a name/id or any selector.
- escapeCssMeta: function( string ) {
- return string.replace( /([\\!"#$%&'()*+,./:;<=>?@\[\]^`{|}~])/g, "\\$1" );
- },
-
- idOrName: function( element ) {
- return this.groups[ element.name ] || ( this.checkable( element ) ? element.name : element.id || element.name );
- },
-
- validationTargetFor: function( element ) {
-
- // If radio/checkbox, validate first element in group instead
- if ( this.checkable( element ) ) {
- element = this.findByName( element.name );
- }
-
- // Always apply ignore filter
- return $( element ).not( this.settings.ignore )[ 0 ];
- },
-
- checkable: function( element ) {
- return ( /radio|checkbox/i ).test( element.type );
- },
-
- findByName: function( name ) {
- return $( this.currentForm ).find( "[name='" + this.escapeCssMeta( name ) + "']" );
- },
-
- getLength: function( value, element ) {
- switch ( element.nodeName.toLowerCase() ) {
- case "select":
- return $( "option:selected", element ).length;
- case "input":
- if ( this.checkable( element ) ) {
- return this.findByName( element.name ).filter( ":checked" ).length;
- }
- }
- return value.length;
- },
-
- depend: function( param, element ) {
- return this.dependTypes[ typeof param ] ? this.dependTypes[ typeof param ]( param, element ) : true;
- },
-
- dependTypes: {
- "boolean": function( param ) {
- return param;
- },
- "string": function( param, element ) {
- return !!$( param, element.form ).length;
- },
- "function": function( param, element ) {
- return param( element );
- }
- },
-
- optional: function( element ) {
- var val = this.elementValue( element );
- return !$.validator.methods.required.call( this, val, element ) && "dependency-mismatch";
- },
-
- startRequest: function( element ) {
- if ( !this.pending[ element.name ] ) {
- this.pendingRequest++;
- $( element ).addClass( this.settings.pendingClass );
- this.pending[ element.name ] = true;
- }
- },
-
- stopRequest: function( element, valid ) {
- this.pendingRequest--;
-
- // Sometimes synchronization fails, make sure pendingRequest is never < 0
- if ( this.pendingRequest < 0 ) {
- this.pendingRequest = 0;
- }
- delete this.pending[ element.name ];
- $( element ).removeClass( this.settings.pendingClass );
- if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
- $( this.currentForm ).submit();
-
- // Remove the hidden input that was used as a replacement for the
- // missing submit button. The hidden input is added by `handle()`
- // to ensure that the value of the used submit button is passed on
- // for scripted submits triggered by this method
- if ( this.submitButton ) {
- $( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
- }
-
- this.formSubmitted = false;
- } else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
- $( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
- this.formSubmitted = false;
- }
- },
-
- previousValue: function( element, method ) {
- method = typeof method === "string" && method || "remote";
-
- return $.data( element, "previousValue" ) || $.data( element, "previousValue", {
- old: null,
- valid: true,
- message: this.defaultMessage( element, { method: method } )
- } );
- },
-
- // Cleans up all forms and elements, removes validator-specific events
- destroy: function() {
- this.resetForm();
-
- $( this.currentForm )
- .off( ".validate" )
- .removeData( "validator" )
- .find( ".validate-equalTo-blur" )
- .off( ".validate-equalTo" )
- .removeClass( "validate-equalTo-blur" );
- }
-
- },
-
- classRuleSettings: {
- required: { required: true },
- email: { email: true },
- url: { url: true },
- date: { date: true },
- dateISO: { dateISO: true },
- number: { number: true },
- digits: { digits: true },
- creditcard: { creditcard: true }
- },
-
- addClassRules: function( className, rules ) {
- if ( className.constructor === String ) {
- this.classRuleSettings[ className ] = rules;
- } else {
- $.extend( this.classRuleSettings, className );
- }
- },
-
- classRules: function( element ) {
- var rules = {},
- classes = $( element ).attr( "class" );
-
- if ( classes ) {
- $.each( classes.split( " " ), function() {
- if ( this in $.validator.classRuleSettings ) {
- $.extend( rules, $.validator.classRuleSettings[ this ] );
- }
- } );
- }
- return rules;
- },
-
- normalizeAttributeRule: function( rules, type, method, value ) {
-
- // Convert the value to a number for number inputs, and for text for backwards compability
- // allows type="date" and others to be compared as strings
- if ( /min|max|step/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
- value = Number( value );
-
- // Support Opera Mini, which returns NaN for undefined minlength
- if ( isNaN( value ) ) {
- value = undefined;
- }
- }
-
- if ( value || value === 0 ) {
- rules[ method ] = value;
- } else if ( type === method && type !== "range" ) {
-
- // Exception: the jquery validate 'range' method
- // does not test for the html5 'range' type
- rules[ method ] = true;
- }
- },
-
- attributeRules: function( element ) {
- var rules = {},
- $element = $( element ),
- type = element.getAttribute( "type" ),
- method, value;
-
- for ( method in $.validator.methods ) {
-
- // Support for in both html5 and older browsers
- if ( method === "required" ) {
- value = element.getAttribute( method );
-
- // Some browsers return an empty string for the required attribute
- // and non-HTML5 browsers might have required="" markup
- if ( value === "" ) {
- value = true;
- }
-
- // Force non-HTML5 browsers to return bool
- value = !!value;
- } else {
- value = $element.attr( method );
- }
-
- this.normalizeAttributeRule( rules, type, method, value );
- }
-
- // 'maxlength' may be returned as -1, 2147483647 ( IE ) and 524288 ( safari ) for text inputs
- if ( rules.maxlength && /-1|2147483647|524288/.test( rules.maxlength ) ) {
- delete rules.maxlength;
- }
-
- return rules;
- },
-
- dataRules: function( element ) {
- var rules = {},
- $element = $( element ),
- type = element.getAttribute( "type" ),
- method, value;
-
- for ( method in $.validator.methods ) {
- value = $element.data( "rule" + method.charAt( 0 ).toUpperCase() + method.substring( 1 ).toLowerCase() );
- this.normalizeAttributeRule( rules, type, method, value );
- }
- return rules;
- },
-
- staticRules: function( element ) {
- var rules = {},
- validator = $.data( element.form, "validator" );
-
- if ( validator.settings.rules ) {
- rules = $.validator.normalizeRule( validator.settings.rules[ element.name ] ) || {};
- }
- return rules;
- },
-
- normalizeRules: function( rules, element ) {
-
- // Handle dependency check
- $.each( rules, function( prop, val ) {
-
- // Ignore rule when param is explicitly false, eg. required:false
- if ( val === false ) {
- delete rules[ prop ];
- return;
- }
- if ( val.param || val.depends ) {
- var keepRule = true;
- switch ( typeof val.depends ) {
- case "string":
- keepRule = !!$( val.depends, element.form ).length;
- break;
- case "function":
- keepRule = val.depends.call( element, element );
- break;
- }
- if ( keepRule ) {
- rules[ prop ] = val.param !== undefined ? val.param : true;
- } else {
- $.data( element.form, "validator" ).resetElements( $( element ) );
- delete rules[ prop ];
- }
- }
- } );
-
- // Evaluate parameters
- $.each( rules, function( rule, parameter ) {
- rules[ rule ] = $.isFunction( parameter ) && rule !== "normalizer" ? parameter( element ) : parameter;
- } );
-
- // Clean number parameters
- $.each( [ "minlength", "maxlength" ], function() {
- if ( rules[ this ] ) {
- rules[ this ] = Number( rules[ this ] );
- }
- } );
- $.each( [ "rangelength", "range" ], function() {
- var parts;
- if ( rules[ this ] ) {
- if ( $.isArray( rules[ this ] ) ) {
- rules[ this ] = [ Number( rules[ this ][ 0 ] ), Number( rules[ this ][ 1 ] ) ];
- } else if ( typeof rules[ this ] === "string" ) {
- parts = rules[ this ].replace( /[\[\]]/g, "" ).split( /[\s,]+/ );
- rules[ this ] = [ Number( parts[ 0 ] ), Number( parts[ 1 ] ) ];
- }
- }
- } );
-
- if ( $.validator.autoCreateRanges ) {
-
- // Auto-create ranges
- if ( rules.min != null && rules.max != null ) {
- rules.range = [ rules.min, rules.max ];
- delete rules.min;
- delete rules.max;
- }
- if ( rules.minlength != null && rules.maxlength != null ) {
- rules.rangelength = [ rules.minlength, rules.maxlength ];
- delete rules.minlength;
- delete rules.maxlength;
- }
- }
-
- return rules;
- },
-
- // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
- normalizeRule: function( data ) {
- if ( typeof data === "string" ) {
- var transformed = {};
- $.each( data.split( /\s/ ), function() {
- transformed[ this ] = true;
- } );
- data = transformed;
- }
- return data;
- },
-
- // https://jqueryvalidation.org/jQuery.validator.addMethod/
- addMethod: function( name, method, message ) {
- $.validator.methods[ name ] = method;
- $.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
- if ( method.length < 3 ) {
- $.validator.addClassRules( name, $.validator.normalizeRule( name ) );
- }
- },
-
- // https://jqueryvalidation.org/jQuery.validator.methods/
- methods: {
-
- // https://jqueryvalidation.org/required-method/
- required: function( value, element, param ) {
-
- // Check if dependency is met
- if ( !this.depend( param, element ) ) {
- return "dependency-mismatch";
- }
- if ( element.nodeName.toLowerCase() === "select" ) {
-
- // Could be an array for select-multiple or a string, both are fine this way
- var val = $( element ).val();
- return val && val.length > 0;
- }
- if ( this.checkable( element ) ) {
- return this.getLength( value, element ) > 0;
- }
- return value.length > 0;
- },
-
- // https://jqueryvalidation.org/email-method/
- email: function( value, element ) {
-
- // From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
- // Retrieved 2014-01-14
- // If you have a problem with this implementation, report a bug against the above spec
- // Or use custom methods to implement your own email validation
- return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
- },
-
- // https://jqueryvalidation.org/url-method/
- url: function( value, element ) {
-
- // Copyright (c) 2010-2013 Diego Perini, MIT licensed
- // https://gist.github.com/dperini/729294
- // see also https://mathiasbynens.be/demo/url-regex
- // modified to allow protocol-relative URLs
- return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
- },
-
- // https://jqueryvalidation.org/date-method/
- date: function( value, element ) {
- return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
- },
-
- // https://jqueryvalidation.org/dateISO-method/
- dateISO: function( value, element ) {
- return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
- },
-
- // https://jqueryvalidation.org/number-method/
- number: function( value, element ) {
- return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
- },
-
- // https://jqueryvalidation.org/digits-method/
- digits: function( value, element ) {
- return this.optional( element ) || /^\d+$/.test( value );
- },
-
- // https://jqueryvalidation.org/minlength-method/
- minlength: function( value, element, param ) {
- var length = $.isArray( value ) ? value.length : this.getLength( value, element );
- return this.optional( element ) || length >= param;
- },
-
- // https://jqueryvalidation.org/maxlength-method/
- maxlength: function( value, element, param ) {
- var length = $.isArray( value ) ? value.length : this.getLength( value, element );
- return this.optional( element ) || length <= param;
- },
-
- // https://jqueryvalidation.org/rangelength-method/
- rangelength: function( value, element, param ) {
- var length = $.isArray( value ) ? value.length : this.getLength( value, element );
- return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
- },
-
- // https://jqueryvalidation.org/min-method/
- min: function( value, element, param ) {
- return this.optional( element ) || value >= param;
- },
-
- // https://jqueryvalidation.org/max-method/
- max: function( value, element, param ) {
- return this.optional( element ) || value <= param;
- },
-
- // https://jqueryvalidation.org/range-method/
- range: function( value, element, param ) {
- return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
- },
-
- // https://jqueryvalidation.org/step-method/
- step: function( value, element, param ) {
- var type = $( element ).attr( "type" ),
- errorMessage = "Step attribute on input type " + type + " is not supported.",
- supportedTypes = [ "text", "number", "range" ],
- re = new RegExp( "\\b" + type + "\\b" ),
- notSupported = type && !re.test( supportedTypes.join() ),
- decimalPlaces = function( num ) {
- var match = ( "" + num ).match( /(?:\.(\d+))?$/ );
- if ( !match ) {
- return 0;
- }
-
- // Number of digits right of decimal point.
- return match[ 1 ] ? match[ 1 ].length : 0;
- },
- toInt = function( num ) {
- return Math.round( num * Math.pow( 10, decimals ) );
- },
- valid = true,
- decimals;
-
- // Works only for text, number and range input types
- // TODO find a way to support input types date, datetime, datetime-local, month, time and week
- if ( notSupported ) {
- throw new Error( errorMessage );
- }
-
- decimals = decimalPlaces( param );
-
- // Value can't have too many decimals
- if ( decimalPlaces( value ) > decimals || toInt( value ) % toInt( param ) !== 0 ) {
- valid = false;
- }
-
- return this.optional( element ) || valid;
- },
-
- // https://jqueryvalidation.org/equalTo-method/
- equalTo: function( value, element, param ) {
-
- // Bind to the blur event of the target in order to revalidate whenever the target field is updated
- var target = $( param );
- if ( this.settings.onfocusout && target.not( ".validate-equalTo-blur" ).length ) {
- target.addClass( "validate-equalTo-blur" ).on( "blur.validate-equalTo", function() {
- $( element ).valid();
- } );
- }
- return value === target.val();
- },
-
- // https://jqueryvalidation.org/remote-method/
- remote: function( value, element, param, method ) {
- if ( this.optional( element ) ) {
- return "dependency-mismatch";
- }
-
- method = typeof method === "string" && method || "remote";
-
- var previous = this.previousValue( element, method ),
- validator, data, optionDataString;
-
- if ( !this.settings.messages[ element.name ] ) {
- this.settings.messages[ element.name ] = {};
- }
- previous.originalMessage = previous.originalMessage || this.settings.messages[ element.name ][ method ];
- this.settings.messages[ element.name ][ method ] = previous.message;
-
- param = typeof param === "string" && { url: param } || param;
- optionDataString = $.param( $.extend( { data: value }, param.data ) );
- if ( previous.old === optionDataString ) {
- return previous.valid;
- }
-
- previous.old = optionDataString;
- validator = this;
- this.startRequest( element );
- data = {};
- data[ element.name ] = value;
- $.ajax( $.extend( true, {
- mode: "abort",
- port: "validate" + element.name,
- dataType: "json",
- data: data,
- context: validator.currentForm,
- success: function( response ) {
- var valid = response === true || response === "true",
- errors, message, submitted;
-
- validator.settings.messages[ element.name ][ method ] = previous.originalMessage;
- if ( valid ) {
- submitted = validator.formSubmitted;
- validator.resetInternals();
- validator.toHide = validator.errorsFor( element );
- validator.formSubmitted = submitted;
- validator.successList.push( element );
- validator.invalid[ element.name ] = false;
- validator.showErrors();
- } else {
- errors = {};
- message = response || validator.defaultMessage( element, { method: method, parameters: value } );
- errors[ element.name ] = previous.message = message;
- validator.invalid[ element.name ] = true;
- validator.showErrors( errors );
- }
- previous.valid = valid;
- validator.stopRequest( element, valid );
- }
- }, param ) );
- return "pending";
- }
- }
-
-} );
-
-// Ajax mode: abort
-// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
-// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
-
-var pendingRequests = {},
- ajax;
-
-// Use a prefilter if available (1.5+)
-if ( $.ajaxPrefilter ) {
- $.ajaxPrefilter( function( settings, _, xhr ) {
- var port = settings.port;
- if ( settings.mode === "abort" ) {
- if ( pendingRequests[ port ] ) {
- pendingRequests[ port ].abort();
- }
- pendingRequests[ port ] = xhr;
- }
- } );
-} else {
-
- // Proxy ajax
- ajax = $.ajax;
- $.ajax = function( settings ) {
- var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
- port = ( "port" in settings ? settings : $.ajaxSettings ).port;
- if ( mode === "abort" ) {
- if ( pendingRequests[ port ] ) {
- pendingRequests[ port ].abort();
- }
- pendingRequests[ port ] = ajax.apply( this, arguments );
- return pendingRequests[ port ];
- }
- return ajax.apply( this, arguments );
- };
-}
-return $;
-}));
\ No newline at end of file
diff --git a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js b/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
deleted file mode 100644
index 20402da5..00000000
--- a/integration/testdata/fdd_6/wwwroot/lib/jquery-validation/dist/jquery.validate.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-/*! jQuery Validation Plugin - v1.17.0 - 7/29/2017
- * https://jqueryvalidation.org/
- * Copyright (c) 2017 Jörn Zaefferer; Licensed MIT */
-!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):"object"==typeof module&&module.exports?module.exports=a(require("jquery")):a(jQuery)}(function(a){a.extend(a.fn,{validate:function(b){if(!this.length)return void(b&&b.debug&&window.console&&console.warn("Nothing selected, can't validate, returning nothing."));var c=a.data(this[0],"validator");return c?c:(this.attr("novalidate","novalidate"),c=new a.validator(b,this[0]),a.data(this[0],"validator",c),c.settings.onsubmit&&(this.on("click.validate",":submit",function(b){c.submitButton=b.currentTarget,a(this).hasClass("cancel")&&(c.cancelSubmit=!0),void 0!==a(this).attr("formnovalidate")&&(c.cancelSubmit=!0)}),this.on("submit.validate",function(b){function d(){var d,e;return c.submitButton&&(c.settings.submitHandler||c.formSubmitted)&&(d=a("").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),!c.settings.submitHandler||(e=c.settings.submitHandler.call(c,c.currentForm,b),d&&d.remove(),void 0!==e&&e)}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,b||(d=d.concat(c.errorList))}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(null!=j&&(!j.form&&j.hasAttribute("contenteditable")&&(j.form=this.closest("form")[0],j.name=this.attr("name")),null!=j.form)){if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(a,b){i[b]=f[b],delete f[b]}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g)),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}}),a.extend(a.expr.pseudos||a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){var c=a(b).val();return null!==c&&!!a.trim(""+c)},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:void 0===c?b:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",pendingClass:"pending",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||a.inArray(c.keyCode,d)!==-1||(b.name in this.submitted||b.name in this.invalid)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",number:"Please enter a valid number.",digits:"Please enter only digits.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}."),step:a.validator.format("Please enter a multiple of {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){!this.form&&this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=a(this).attr("name"));var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox'], [contenteditable], [type='button']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler)},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c,d,e=this.clean(b),f=this.validationTargetFor(e),g=this,h=!0;return void 0===f?delete this.invalid[e.name]:(this.prepareElement(f),this.currentElements=a(f),d=this.groups[f.name],d&&a.each(this.groups,function(a,b){b===d&&a!==f.name&&(e=g.validationTargetFor(g.clean(g.findByName(a))),e&&e.name in g.invalid&&(g.currentElements.push(e),h=g.check(e)&&h))}),c=this.check(f)!==!1,h=h&&c,c?this.invalid[f.name]=!1:this.invalid[f.name]=!0,this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),a(b).attr("aria-invalid",!c)),h},showErrors:function(b){if(b){var c=this;a.extend(this.errorMap,b),this.errorList=a.map(this.errorMap,function(a,b){return{message:a,element:c.findByName(b)[0]}}),this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.invalid={},this.submitted={},this.prepareForm(),this.hideErrors();var b=this.elements().removeData("previousValue").removeAttr("aria-invalid");this.resetElements(b)},resetElements:function(a){var b;if(this.settings.unhighlight)for(b=0;a[b];b++)this.settings.unhighlight.call(this,a[b],this.settings.errorClass,""),this.findByName(a[b].name).removeClass(this.settings.validClass);else a.removeClass(this.settings.errorClass).removeClass(this.settings.validClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)void 0!==a[b]&&null!==a[b]&&a[b]!==!1&&c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea, [contenteditable]").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){var d=this.name||a(this).attr("name");return!d&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.hasAttribute("contenteditable")&&(this.form=a(this).closest("form")[0],this.name=d),!(d in c||!b.objectLength(a(this).rules()))&&(c[d]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},resetInternals:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([])},reset:function(){this.resetInternals(),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d,e=a(b),f=b.type;return"radio"===f||"checkbox"===f?this.findByName(b.name).filter(":checked").val():"number"===f&&"undefined"!=typeof b.validity?b.validity.badInput?"NaN":e.val():(c=b.hasAttribute("contenteditable")?e.text():e.val(),"file"===f?"C:\\fakepath\\"===c.substr(0,12)?c.substr(12):(d=c.lastIndexOf("/"),d>=0?c.substr(d+1):(d=c.lastIndexOf("\\"),d>=0?c.substr(d+1):c)):"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f,g=a(b).rules(),h=a.map(g,function(a,b){return b}).length,i=!1,j=this.elementValue(b);if("function"==typeof g.normalizer?f=g.normalizer:"function"==typeof this.settings.normalizer&&(f=this.settings.normalizer),f){if(j=f.call(b,j),"string"!=typeof j)throw new TypeError("The normalizer should return a string value.");delete g.normalizer}for(d in g){e={method:d,parameters:g[d]};try{if(c=a.validator.methods[d].call(this,j,b,e.parameters),"dependency-mismatch"===c&&1===h){i=!0;continue}if(i=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(k){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",k),k instanceof TypeError&&(k.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),k}}if(!i)return this.objectLength(g)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+""),e=/\$?\{(\d+)\}/g;return"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),d},formatAndAdd:function(a,b){var c=this.defaultMessage(a,b);this.errorList.push({message:c,element:a,method:b.method}),this.errorMap[a.name]=c,this.submitted[a.name]=c},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g,h=this.errorsFor(b),i=this.idOrName(b),j=a(b).attr("aria-describedby");h.length?(h.removeClass(this.settings.validClass).addClass(this.settings.errorClass),h.html(c)):(h=a("<"+this.settings.errorElement+">").attr("id",i+"-error").addClass(this.settings.errorClass).html(c||""),d=h,this.settings.wrapper&&(d=h.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement.call(this,d,a(b)):d.insertAfter(b),h.is("label")?h.attr("for",i):0===h.parents("label[for='"+this.escapeCssMeta(i)+"']").length&&(f=h.attr("id"),j?j.match(new RegExp("\\b"+this.escapeCssMeta(f)+"\\b"))||(j+=" "+f):j=f,a(b).attr("aria-describedby",j),e=this.groups[b.name],e&&(g=this,a.each(g.groups,function(b,c){c===e&&a("[name='"+g.escapeCssMeta(b)+"']",g.currentForm).attr("aria-describedby",h.attr("id"))})))),!c&&this.settings.success&&(h.text(""),"string"==typeof this.settings.success?h.addClass(this.settings.success):this.settings.success(h,b)),this.toShow=this.toShow.add(h)},errorsFor:function(b){var c=this.escapeCssMeta(this.idOrName(b)),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+this.escapeCssMeta(d).replace(/\s+/g,", #")),this.errors().filter(e)},escapeCssMeta:function(a){return a.replace(/([\\!"#$%&'()*+,.\/:;<=>?@\[\]^`{|}~])/g,"\\$1")},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+this.escapeCssMeta(b)+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return!this.dependTypes[typeof a]||this.dependTypes[typeof a](a,b)},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(b){this.pending[b.name]||(this.pendingRequest++,a(b).addClass(this.settings.pendingClass),this.pending[b.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],a(b).removeClass(this.settings.pendingClass),c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.submitButton&&a("input:hidden[name='"+this.submitButton.name+"']",this.currentForm).remove(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b,c){return c="string"==typeof c&&c||"remote",a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,{method:c})})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator").find(".validate-equalTo-blur").off(".validate-equalTo").removeClass("validate-equalTo-blur")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max|step/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0===e.param||e.param:(a.data(c.form,"validator").resetElements(a(c)),delete b[d])}}),a.each(b,function(d,e){b[d]=a.isFunction(e)&&"normalizer"!==d?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[\/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e<=d},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||a<=c},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},step:function(b,c,d){var e,f=a(c).attr("type"),g="Step attribute on input type "+f+" is not supported.",h=["text","number","range"],i=new RegExp("\\b"+f+"\\b"),j=f&&!i.test(h.join()),k=function(a){var b=(""+a).match(/(?:\.(\d+))?$/);return b&&b[1]?b[1].length:0},l=function(a){return Math.round(a*Math.pow(10,e))},m=!0;if(j)throw new Error(g);return e=k(d),(k(b)>e||l(b)%l(d)!==0)&&(m=!1),this.optional(c)||m},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.not(".validate-equalTo-blur").length&&e.addClass("validate-equalTo-blur").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d,e){if(this.optional(c))return"dependency-mismatch";e="string"==typeof e&&e||"remote";var f,g,h,i=this.previousValue(c,e);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),i.originalMessage=i.originalMessage||this.settings.messages[c.name][e],this.settings.messages[c.name][e]=i.message,d="string"==typeof d&&{url:d}||d,h=a.param(a.extend({data:b},d.data)),i.old===h?i.valid:(i.old=h,f=this,this.startRequest(c),g={},g[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:g,context:f.currentForm,success:function(a){var d,g,h,j=a===!0||"true"===a;f.settings.messages[c.name][e]=i.originalMessage,j?(h=f.formSubmitted,f.resetInternals(),f.toHide=f.errorsFor(c),f.formSubmitted=h,f.successList.push(c),f.invalid[c.name]=!1,f.showErrors()):(d={},g=a||f.defaultMessage(c,{method:e,parameters:b}),d[c.name]=i.message=g,f.invalid[c.name]=!0,f.showErrors(d)),i.valid=j,f.stopRequest(c,j)}},d)),"pending")}}});var b,c={};return a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)}),a});
\ No newline at end of file
diff --git a/integration/testdata/fdd_6/wwwroot/lib/jquery/LICENSE.txt b/integration/testdata/fdd_6/wwwroot/lib/jquery/LICENSE.txt
deleted file mode 100644
index 10108aa8..00000000
--- a/integration/testdata/fdd_6/wwwroot/lib/jquery/LICENSE.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-Copyright JS Foundation and other contributors, https://js.foundation/
-
-This software consists of voluntary contributions made by many
-individuals. For exact contribution history, see the revision history
-available at https://github.com/jquery/jquery
-
-The following license applies to all parts of this software except as
-documented below:
-
-====
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-====
-
-All files located in the node_modules and external directories are
-externally maintained libraries used by this software which have their
-own licenses; we recommend you read them, as their terms may differ from
-the terms above.
diff --git a/integration/testdata/fdd_6/wwwroot/lib/jquery/dist/jquery.js b/integration/testdata/fdd_6/wwwroot/lib/jquery/dist/jquery.js
deleted file mode 100644
index 50937333..00000000
--- a/integration/testdata/fdd_6/wwwroot/lib/jquery/dist/jquery.js
+++ /dev/null
@@ -1,10872 +0,0 @@
-/*!
- * jQuery JavaScript Library v3.5.1
- * https://jquery.com/
- *
- * Includes Sizzle.js
- * https://sizzlejs.com/
- *
- * Copyright JS Foundation and other contributors
- * Released under the MIT license
- * https://jquery.org/license
- *
- * Date: 2020-05-04T22:49Z
- */
-( function( global, factory ) {
-
- "use strict";
-
- if ( typeof module === "object" && typeof module.exports === "object" ) {
-
- // For CommonJS and CommonJS-like environments where a proper `window`
- // is present, execute the factory and get jQuery.
- // For environments that do not have a `window` with a `document`
- // (such as Node.js), expose a factory as module.exports.
- // This accentuates the need for the creation of a real `window`.
- // e.g. var jQuery = require("jquery")(window);
- // See ticket #14549 for more info.
- module.exports = global.document ?
- factory( global, true ) :
- function( w ) {
- if ( !w.document ) {
- throw new Error( "jQuery requires a window with a document" );
- }
- return factory( w );
- };
- } else {
- factory( global );
- }
-
-// Pass this if window is not defined yet
-} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
-
-// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
-// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
-// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
-// enough that all such attempts are guarded in a try block.
-"use strict";
-
-var arr = [];
-
-var getProto = Object.getPrototypeOf;
-
-var slice = arr.slice;
-
-var flat = arr.flat ? function( array ) {
- return arr.flat.call( array );
-} : function( array ) {
- return arr.concat.apply( [], array );
-};
-
-
-var push = arr.push;
-
-var indexOf = arr.indexOf;
-
-var class2type = {};
-
-var toString = class2type.toString;
-
-var hasOwn = class2type.hasOwnProperty;
-
-var fnToString = hasOwn.toString;
-
-var ObjectFunctionString = fnToString.call( Object );
-
-var support = {};
-
-var isFunction = function isFunction( obj ) {
-
- // Support: Chrome <=57, Firefox <=52
- // In some browsers, typeof returns "function" for HTML