You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@openwhisk.apache.org by GitBox <gi...@apache.org> on 2018/01/31 18:35:35 UTC

[GitHub] dubeejw closed pull request #170: Initial code checkin for path parameter support

dubeejw closed pull request #170: Initial code checkin for path parameter support
URL: https://github.com/apache/incubator-openwhisk-cli/pull/170
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/.gitignore b/.gitignore
index de768504..55423b34 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,7 @@ Godeps/_workspace
 build
 /release/
 /vendor/
+incubator-openwhisk-cli.iml
+wski18n/i18n_resources.go
+bin/
+tests/build/
diff --git a/build.gradle b/build.gradle
index 08fc2380..29bedf25 100644
--- a/build.gradle
+++ b/build.gradle
@@ -24,7 +24,7 @@ dependencies {
         build(['name':'golang.org/x/sys/unix', 'version':'7f918dd405547ecb864d14a8ecbbfe205b5f930f', 'transitive':false])
         build(['name':'gopkg.in/yaml.v2', 'version':'cd8b52f8269e0feb286dfeef29f8fe4d5b397e0b', 'transitive':false])
         build(['name':'github.com/ghodss/yaml', 'version':'0ca9ea5df5451ffdf184b4428c902747c2c11cd7', 'transitive':false])
-        build(['name':'github.com/apache/incubator-openwhisk-client-go/whisk','version':'ba3bbee442357a239667ef6de378d5b7d33e0ceb','transitive':false])
+        build(['name':'github.com/apache/incubator-openwhisk-client-go/whisk','version':'a0864455f7c18db70d93d4dd2bc0b43d2334ed90','transitive':false])
         // END - Imported from Godeps
         test name:'github.com/stretchr/testify', version:'b91bfb9ebec76498946beb6af7c0230c7cc7ba6c', transitive:false //, tag: 'v1.2.0'
         test name:'github.com/spf13/viper', version:'aafc9e6bc7b7bb53ddaa75a5ef49a17d6e654be5', transitive:false
diff --git a/commands/api.go b/commands/api.go
index 41346836..468fb058 100644
--- a/commands/api.go
+++ b/commands/api.go
@@ -33,6 +33,7 @@ import (
 	"github.com/fatih/color"
 	"github.com/ghodss/yaml"
 	"github.com/spf13/cobra"
+	"regexp"
 )
 
 const (
@@ -41,6 +42,8 @@ const (
 
 	formatOptionYaml = "yaml"
 	formatOptionJson = "json"
+
+	pathParamRegex = `/\{([^/]+)}/|/\{([^/]+)}$`
 )
 
 var apiCmd = &cobra.Command{
@@ -93,6 +96,34 @@ func isValidRelpath(relpath string) (error, bool) {
 	return nil, true
 }
 
+func hasPathParameters(path string) (bool, error) {
+	matched, err := regexp.MatchString(pathParamRegex, path)
+	hasBracket := strings.ContainsRune(path, '{') || strings.ContainsRune(path, '}')
+	if err != nil {
+		whisk.Debug(whisk.DbgInfo, "Unable to compile Regex '%s' to test against path '%s'\n", pathParamRegex, path)
+	}
+	if hasBracket && !matched {
+		errMsg := wski18n.T("Relative path '{{.path}}' does not include valid path parameters. Each parameter must be enclosed in curly braces '{}'.",
+			map[string]interface{}{"path": path})
+		whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
+			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+		return false, whiskErr
+	}
+	return matched, nil
+}
+
+func isBasepathParameterized(basepath string) (error, bool) {
+	hasParams, err := hasPathParameters(basepath)
+	if hasParams || err != nil {
+		errMsg := wski18n.T("The base path '{{.path}}' cannot have parameters. Only the relative path supports path parameters.",
+			map[string]interface{}{"path": basepath})
+		whiskErr := whisk.MakeWskError(errors.New(errMsg), whisk.EXIT_CODE_ERR_GENERAL,
+			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+		return whiskErr, false
+	}
+	return nil, true
+}
+
 /*
  * Pull the managedUrl (external API URL) from the API configuration
  */
@@ -103,7 +134,7 @@ func getManagedUrl(api *whisk.RetApi, relpath string, operation string) (url str
 		whisk.Debug(whisk.DbgInfo, "getManagedUrl: comparing api relpath: '%s'\n", path)
 		if path == relpath {
 			whisk.Debug(whisk.DbgInfo, "getManagedUrl: relpath matches '%s'\n", relpath)
-			for op := range api.Swagger.Paths[path] {
+			for op := range api.Swagger.Paths[path].MakeOperationMap() {
 				whisk.Debug(whisk.DbgInfo, "getManagedUrl: comparing operation: '%s'\n", op)
 				if strings.ToLower(op) == strings.ToLower(operation) {
 					whisk.Debug(whisk.DbgInfo, "getManagedUrl: operation matches: '%s'\n", operation)
@@ -208,7 +239,7 @@ var apiCreateCmd = &cobra.Command{
 			for path := range retApi.Swagger.Paths {
 				managedUrl := strings.TrimSuffix(baseUrl, "/") + path
 				whisk.Debug(whisk.DbgInfo, "Managed path: '%s'\n", managedUrl)
-				for op, opv := range retApi.Swagger.Paths[path] {
+				for op, opv := range retApi.Swagger.Paths[path].MakeOperationMap() {
 					whisk.Debug(whisk.DbgInfo, "Path operation: '%s'\n", op)
 					var fqActionName string
 					if opv.XOpenWhisk == nil {
@@ -577,7 +608,7 @@ func genFilteredList(resultApi *whisk.RetApi, apiPath string, apiVerb string) []
 			whisk.Debug(whisk.DbgInfo, "genFilteredApi: comparing api relpath: '%s'\n", path)
 			if len(apiPath) == 0 || path == apiPath {
 				whisk.Debug(whisk.DbgInfo, "genFilteredList: relpath matches\n")
-				for op, opv := range resultApi.Swagger.Paths[path] {
+				for op, opv := range resultApi.Swagger.Paths[path].MakeOperationMap() {
 					whisk.Debug(whisk.DbgInfo, "genFilteredList: comparing operation: '%s'\n", op)
 					if len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb) {
 						whisk.Debug(whisk.DbgInfo, "genFilteredList: operation matches: %#v\n", opv)
@@ -615,7 +646,7 @@ func genFilteredRow(resultApi *whisk.RetApi, apiPath string, apiVerb string, max
 			whisk.Debug(whisk.DbgInfo, "genFilteredRow: comparing api relpath: '%s'\n", path)
 			if len(apiPath) == 0 || path == apiPath {
 				whisk.Debug(whisk.DbgInfo, "genFilteredRow: relpath matches\n")
-				for op, opv := range resultApi.Swagger.Paths[path] {
+				for op, opv := range resultApi.Swagger.Paths[path].MakeOperationMap() {
 					whisk.Debug(whisk.DbgInfo, "genFilteredRow: comparing operation: '%s'\n", op)
 					if len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb) {
 						whisk.Debug(whisk.DbgInfo, "genFilteredRow: operation matches: %#v\n", opv)
@@ -678,7 +709,7 @@ func getLargestActionNameSize(retApiArray *whisk.RetApiArray, apiPath string, ap
 				whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: comparing api relpath: '%s'\n", path)
 				if len(apiPath) == 0 || path == apiPath {
 					whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: relpath matches\n")
-					for op, opv := range resultApi.Swagger.Paths[path] {
+					for op, opv := range resultApi.Swagger.Paths[path].MakeOperationMap() {
 						whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: comparing operation: '%s'\n", op)
 						if len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb) {
 							whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: operation matches: %#v\n", opv)
@@ -712,7 +743,7 @@ func getLargestApiNameSize(retApiArray *whisk.RetApiArray, apiPath string, apiVe
 				whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: comparing api relpath: '%s'\n", path)
 				if len(apiPath) == 0 || path == apiPath {
 					whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: relpath matches\n")
-					for op, opv := range resultApi.Swagger.Paths[path] {
+					for op, opv := range resultApi.Swagger.Paths[path].MakeOperationMap() {
 						whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: comparing operation: '%s'\n", op)
 						if len(apiVerb) == 0 || strings.ToLower(op) == strings.ToLower(apiVerb) {
 							whisk.Debug(whisk.DbgInfo, "getLargestActionNameSize: operation matches: %#v\n", opv)
@@ -728,6 +759,28 @@ func getLargestApiNameSize(retApiArray *whisk.RetApiArray, apiPath string, apiVe
 	return maxNameSize
 }
 
+func generatePathParameters(relativePath string) []whisk.ApiParameter {
+	pathParams := []whisk.ApiParameter{}
+	regexObj, err := regexp.Compile(pathParamRegex)
+	if err != nil {
+		whisk.Debug(whisk.DbgError, "Failed to match path '%s' to regular expressions `%s`\n", relativePath, pathParamRegex)
+	}
+	matches := regexObj.FindAllString(relativePath, -1)
+	if matches != nil {
+		for _, paramName := range matches {
+			//The next 3 lines clean up the paramName, as the matches are something like `/{param}`
+			openIdx := strings.IndexRune(paramName, '{')
+			closeIdx := strings.IndexRune(paramName, '}')
+			paramName = string([]rune(paramName)[openIdx+1 : closeIdx])
+			param := whisk.ApiParameter{Name: paramName, In: "path", Required: true, Type: "string",
+				Description: wski18n.T("Default description for '{{.name}}'", map[string]interface{}{"name": paramName})}
+			pathParams = append(pathParams, param)
+		}
+	}
+
+	return pathParams
+}
+
 /*
  * if # args = 4
  * args[0] = API base path
@@ -754,6 +807,9 @@ func parseApi(cmd *cobra.Command, args []string) (*whisk.Api, *QualifiedName, er
 			whisk.Debug(whisk.DbgInfo, "Treating '%s' as an API name; as it does not begin with '/'\n", args[0])
 			basepathArgIsApiName = true
 		}
+		if err, _ := isBasepathParameterized(args[0]); err != nil {
+			return nil, nil, err
+		}
 		basepath = args[0]
 
 		// Shift the args so the remaining code works with or without the explicit base path arg
@@ -768,6 +824,19 @@ func parseApi(cmd *cobra.Command, args []string) (*whisk.Api, *QualifiedName, er
 		api.GatewayRelPath = args[0] // Maintain case as URLs may be case-sensitive
 	}
 
+	// Attempting to use path parameters, lets validate that they provided them correctly.
+	hasPathParams, err := hasPathParameters(api.GatewayRelPath)
+	if err != nil {
+		return nil, nil, err
+	}
+	// If they provided path Parameters, the response type better be http as its the only one that supports path parameters right now.
+	if hasPathParams && Flags.api.resptype != "http" {
+		errMsg := wski18n.T("A response type of 'http' is required when using path parameters.")
+		whiskErr := whisk.MakeWskErrorFromWskError(errors.New(errMsg), err, whisk.EXIT_CODE_ERR_GENERAL,
+			whisk.DISPLAY_MSG, whisk.DISPLAY_USAGE)
+		return nil, nil, whiskErr
+	}
+
 	// Is the API verb valid?
 	if len(args) > 1 {
 		if whiskErr, ok := IsValidApiVerb(args[1]); !ok {
@@ -827,6 +896,7 @@ func parseApi(cmd *cobra.Command, args []string) (*whisk.Api, *QualifiedName, er
 	if !basepathArgIsApiName {
 		api.Id = "API:" + api.Namespace + ":" + api.GatewayBasePath
 	}
+	api.PathParameters = generatePathParameters(api.GatewayRelPath)
 
 	whisk.Debug(whisk.DbgInfo, "Parsed api struct: %#v\n", api)
 	return api, qName, nil
diff --git a/tests/src/test/scala/whisk/core/cli/test/ApiGwCliTests.scala b/tests/src/test/scala/whisk/core/cli/test/ApiGwCliTests.scala
index ba886c0f..13ffc6ac 100644
--- a/tests/src/test/scala/whisk/core/cli/test/ApiGwCliTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/ApiGwCliTests.scala
@@ -17,17 +17,236 @@
 
 package whisk.core.cli.test
 
+import com.jayway.restassured.RestAssured
+
+import common.{TestUtils, Wsk}
+import common.TestUtils._
+
 import org.junit.runner.RunWith
 import org.scalatest.junit.JUnitRunner
 
-import common.Wsk
-import common.TestUtils.SUCCESS_EXIT
+import scala.concurrent.duration.DurationInt
+import scala.util.parsing.json.JSON
 
 /**
- * Tests for basic CLI usage. Some of these tests require a deployed backend.
- */
+  * Tests for basic CLI usage. Some of these tests require a deployed backend.
+  */
 @RunWith(classOf[JUnitRunner])
 class ApiGwCliTests extends ApiGwTests {
   override lazy val wsk: common.Wsk = new Wsk
   override lazy val createCode = SUCCESS_EXIT
+  behavior of "Cli Wsk api creation with path parameters no swagger"
+
+  it should "fail to create an API if the relative path contains invalid path parameters" in withAssetCleaner(wskprops) {(wp, assetHelper) =>
+    val actionName = "APIGWTEST_BAD_RELATIVE_PATH_ACTION"
+    val basePath = "/mybase/path"
+    val file = TestUtils.getTestActionFilename(s"echo-web-http.js")
+    assetHelper.withCleaner(wsk.action, actionName, confirmDelete = true) {
+      (action, _) =>
+        action.create(actionName, Some(file), web = Some("true"))
+    }
+    var relPath = "/bad/{path/value"
+    var rr = apiCreate(basepath = Some(basePath),
+      relpath = Some(relPath),
+      operation = Some("GET"),
+      action = Some(actionName),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(
+      s"Relative path '${relPath}' does not include valid path parameters. Each parameter must be enclosed in curly braces '{}'.")
+
+    relPath = "/bad/path}/value"
+    rr = apiCreate(basepath = Some(basePath),
+      relpath = Some(relPath),
+      operation = Some("GET"),
+      action = Some(actionName),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(
+      s"Relative path '${relPath}' does not include valid path parameters. Each parameter must be enclosed in curly braces '{}'.")
+
+    relPath = "/bad/{path/va}lue"
+    rr = apiCreate(basepath = Some(basePath),
+      relpath = Some(relPath),
+      operation = Some("GET"),
+      action = Some(actionName),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(
+      s"Relative path '${relPath}' does not include valid path parameters. Each parameter must be enclosed in curly braces '{}'.")
+
+    relPath = "/ba}d/{path/value"
+    rr = apiCreate(basepath = Some(basePath),
+      relpath = Some(relPath),
+      operation = Some("GET"),
+      action = Some(actionName),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(
+      s"Relative path '${relPath}' does not include valid path parameters. Each parameter must be enclosed in curly braces '{}'.")
+
+    relPath = "/ba}d/{p{at}h/value"
+    rr = apiCreate(basepath = Some(basePath),
+      relpath = Some(relPath),
+      operation = Some("GET"),
+      action = Some(actionName),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(
+      s"Relative path '${relPath}' does not include valid path parameters. Each parameter must be enclosed in curly braces '{}'.")
+  }
+
+  it should "fail to create an API if the base path contains path parameters" in withAssetCleaner(wskprops) {(wp, assetHelper) =>
+    val actionName = "APIGWTEST_BAD_BASE_PATH_ACTION"
+    val basePath = "/mybase/{path}"
+    val file = TestUtils.getTestActionFilename(s"echo-web-http.js")
+    assetHelper.withCleaner(wsk.action, actionName, confirmDelete = true) {
+      (action, _) =>
+        action.create(actionName, Some(file), web = Some("true"))
+    }
+    val relPath = "/bad/{path}/value"
+    val rr = apiCreate(basepath = Some(basePath),
+      relpath = Some(relPath),
+      operation = Some("GET"),
+      action = Some(actionName),
+      expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(
+      s"The base path '${basePath}' cannot have parameters. Only the relative path supports path parameters.")
+  }
+
+  it should "fail to create an Api if path parameters are specified but http response type is not given" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val actionName = "CLI_APIGWTEST_PATH_param_fail1_action"
+    val file = TestUtils.getTestActionFilename(s"echo-web-http.js")
+    assetHelper.withCleaner(wsk.action, actionName, confirmDelete = true) {
+      (action, _) =>
+        action.create(actionName, Some(file), web = Some("true"))
+    }
+    val relPath = "/bad/{path}/value"
+    val rr = apiCreate(basepath = Some("/mybase"),
+                       relpath = Some(relPath),
+                       operation = Some("GET"),
+                       action = Some(actionName),
+                       expectedExitCode = ANY_ERROR_EXIT)
+    rr.stderr should include(
+      s"A response type of 'http' is required when using path parameters.")
+  }
+
+  it should "create api with path parameters for the verb" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val testName = "CLI_APIGWTEST_PATH_PARAMS1"
+    val testBasePath = s"/${testName}_bp"
+    val testUrlName1 = "scooby"
+    val testUrlName2 = "doo"
+    val testRelPath = "/path/{with}/some/{path}/params"
+    val testRelPathGet = s"/path/${testUrlName1}/some/${testUrlName2}/params"
+    val testUrlOp = "get"
+    val testApiName = testName + " API Name"
+    val actionName = testName + "_action"
+    var exception: Throwable = null
+    val reqPath = "\\$\\(request.path\\)"
+
+    // Create the action for the API.  It must be a "web-action" action.
+    val file = TestUtils.getTestActionFilename(s"echo-web-http.js")
+    assetHelper.withCleaner(wsk.action, actionName, confirmDelete = true) {
+      (action, _) =>
+        action.create(actionName, Some(file), web = Some("true"))
+    }
+    try {
+      var rr = apiCreate(
+        basepath = Some(testBasePath),
+        relpath = Some(testRelPath),
+        operation = Some(testUrlOp),
+        action = Some(actionName),
+        apiname = Some(testApiName),
+        responsetype = Some("http")
+      )
+      verifyApiCreated(rr)
+      val swaggerApiUrl = getSwaggerUrl(rr).replace("{with}", testUrlName1).replace("{path}", testUrlName2)
+
+      //Validate the api created contained parameters and they were correct
+      rr = apiGet(basepathOrApiName = Some(testApiName))
+      rr.stdout should include(testBasePath)
+      rr.stdout should include(s"${actionName}")
+      rr.stdout should include regex (""""cors":\s*\{\s*\n\s*"enabled":\s*true""")
+      rr.stdout should include regex (s"""target-url.*${actionName}.http${reqPath}""")
+      val params = getParametersFromJson(rr, testRelPath)
+      params.size should be(2)
+      validateParameter(params(0), "with", "path", true, "string", "Default description for 'with'")
+      validateParameter(params(1), "path", "path", true, "string", "Default description for 'path'")
+
+      //Lets call the swagger url so we can make sure the response is valid and contains our path in the ow path
+      val apiToInvoke = s"$swaggerApiUrl"
+      println(s"Invoking: '${apiToInvoke}'")
+      val response = whisk.utils.retry({
+        val response = RestAssured.given().config(getSslConfig()).get(s"$apiToInvoke")
+        response.statusCode should be(200)
+        response
+      }, 6, Some(2.second))
+      val jsonReponse = JSON.parseFull(response.asString()).asInstanceOf[Option[Map[String, String]]].get
+      jsonReponse.get("__ow_path").get should not be ("")
+      jsonReponse.get("__ow_path").get should include (testRelPathGet)
+    } catch {
+      case unknown: Throwable => exception = unknown
+    } finally {
+      apiDelete(basepathOrApiName = testBasePath)
+    }
+    assert(exception == null)
+  }
+
+  it should "create api with path parameters and pass them into the action bound to the api" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val testName = "CLI_APIGWTEST_PATH_PARAMS2"
+    val testBasePath = "/" + testName + "_bp"
+    val testRelPath = "/path/{with}/some/{path}"
+    val testUrlName1 = "scooby"
+    val testUrlName2 = "doo"
+    val testRelPathGet = s"/path/${testUrlName1}/some/$testUrlName2"
+    val testUrlOp = "get"
+    val testApiName = testName + " API Name"
+    val actionName = testName + "_action"
+    var exception: Throwable = null
+    val reqPath = "\\$\\(request.path\\)"
+    // Create the action for the API.  It must be a "web-action" action.
+    val file = TestUtils.getTestActionFilename(s"echo-web-http.js")
+    assetHelper.withCleaner(wsk.action, actionName, confirmDelete = true) {
+      (action, _) =>
+        action.create(actionName, Some(file), web = Some("true"))
+    }
+    try {
+      var rr = apiCreate(
+        basepath = Some(testBasePath),
+        relpath = Some(testRelPath),
+        operation = Some(testUrlOp),
+        action = Some(actionName),
+        apiname = Some(testApiName),
+        responsetype = Some("http")
+      )
+      verifyApiCreated(rr)
+      val swaggerApiUrl = getSwaggerUrl(rr).replace("{with}", testUrlName1).replace("{path}", testUrlName2)
+
+      //Validate the api created contained parameters and they were correct
+      rr = apiGet(basepathOrApiName = Some(testApiName))
+      rr.stdout should include(testBasePath)
+      rr.stdout should include(s"${actionName}")
+      rr.stdout should include regex (""""cors":\s*\{\s*\n\s*"enabled":\s*true""")
+      rr.stdout should include regex (s"""target-url.*${actionName}.http${reqPath}""")
+      val params = getParametersFromJson(rr, testRelPath)
+      params.size should be(2)
+      validateParameter(params(0), "with", "path", true, "string", "Default description for 'with'")
+      validateParameter(params(1), "path", "path", true, "string", "Default description for 'path'")
+
+      //Lets call the swagger url so we can make sure the response is valid and contains our path in the ow path
+      val apiToInvoke = s"$swaggerApiUrl"
+      println(s"Invoking: '${apiToInvoke}'")
+      val response = whisk.utils.retry({
+        val response = RestAssured.given().config(getSslConfig()).get(s"$apiToInvoke")
+        response.statusCode should be(200)
+        response
+      }, 6, Some(2.second))
+      val jsonReponse = JSON.parseFull(response.asString()).asInstanceOf[Option[Map[String, String]]].get
+      jsonReponse.get("__ow_path").get should not be ("")
+      jsonReponse.get("__ow_path").get should include (testRelPathGet)
+    } catch {
+      case unknown: Throwable => exception = unknown
+    } finally {
+      apiDelete(basepathOrApiName = testBasePath)
+    }
+    assert(exception == null)
+  }
 }
diff --git a/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala b/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala
index ce384499..4bbe3957 100644
--- a/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/ApiGwTests.scala
@@ -17,6 +17,8 @@
 
 package whisk.core.cli.test
 
+import com.jayway.restassured.RestAssured
+
 import java.io.File
 import java.io.BufferedWriter
 import java.io.FileWriter
@@ -25,9 +27,19 @@ import org.junit.runner.RunWith
 
 import org.scalatest.junit.JUnitRunner
 
+import com.jayway.restassured.config.RestAssuredConfig
+import com.jayway.restassured.config.SSLConfig
+
 import common.TestUtils._
-import common.TestCLIUtils
-import common.WskProps
+import common.TestUtils
+import common.WhiskProperties
+import common.{TestCLIUtils, WhiskProperties, WskProps}
+
+import scala.concurrent.duration.DurationInt
+import scala.util.parsing.json.JSON
+import scala.util.matching.Regex
+
+import org.apache.commons.io.FileUtils
 
 /**
  * Tests for testing the CLI "api" subcommand.  Most of these tests require a deployed backend.
@@ -163,8 +175,125 @@ abstract class ApiGwTests extends BaseApiGwTests {
     rr.stderr should include("The supplied authentication is invalid")
   }
 
+  def writeSwaggerFile(rr: RunResult): File = {
+    val swaggerfile = File.createTempFile("api", ".json")
+    swaggerfile.deleteOnExit()
+    val bw = new BufferedWriter(new FileWriter(swaggerfile))
+    bw.write(rr.stdout)
+    bw.close()
+    return swaggerfile
+  }
+
+  def getSwaggerUrl(rr: RunResult) : String = {
+    rr.stdout.split("\n")(1)
+  }
+
+  def replaceStringInFile(fileName: String, replacements: Map[Regex, String]): String = {
+    val encoding = "UTF-8"
+
+    val contents = FileUtils.readFileToString(new File(fileName), encoding)
+    var newContents = contents
+    replacements foreach ((regex) => newContents = regex._1.replaceAllIn(newContents, regex._2))
+    val tmpFileName = fileName + "-" + System.currentTimeMillis() + ".tmp"
+    val tmpFile = new File(tmpFileName)
+    if (tmpFile.exists()) {
+      FileUtils.forceDelete(tmpFile)
+    }
+    FileUtils.writeStringToFile(new File(tmpFileName), newContents, encoding)
+    tmpFileName
+  }
+
+  def getParametersFromJson(rr: RunResult, pathName: String): List[Map[String, Any]] = {
+    val parsed = JSON.parseFull(rr.stdout).asInstanceOf[Option[Map[String, Map[String, Map[String, Map[String, List[Map[String, String]]]]]]]]
+    parsed.get("paths").get(pathName).get("get").get("parameters").get
+  }
+
+  def getSslConfig(): RestAssuredConfig = {
+    // force RestAssured to allow all hosts in SSL certificates
+    new RestAssuredConfig().sslConfig(new SSLConfig().keystore("keystore", WhiskProperties.getSslCertificateChallenge).allowAllHostnames())
+  }
+
+  def validateParameter(parameter: Map[String, Any], name: String, in: String, required: Boolean, pType: String, description: String): Unit = {
+    parameter.get("name").get should be(name)
+    parameter.get("in").get should be(in)
+    parameter.get("required") should be(Some(required))
+    parameter.get("type").get should be(pType)
+    parameter.get("description").get should be(description)
+  }
+
   behavior of "Wsk api"
 
+  behavior of "Cli Wsk api creation with path parameters with swagger"
+
+  it should "create the API when swagger file contains path parameters" in withAssetCleaner(
+    wskprops) { (wp, assetHelper) =>
+    val actionName = "cli_apigwtest_path_param_swagger_action"
+    var exception: Throwable = null
+    val apiName = "/guest/v1"
+    val reqPath = "\\$\\(request.path\\)"
+    val testRelPath = "/api2/greeting2/{name}"
+    val testUrlName = "scooby"
+    val testRelPathGet = s"/api2/greeting2/$testUrlName"
+    val testUrlOp = "get"
+    var file = TestUtils.getTestActionFilename(s"echo-web-http.js")
+    val hostRegex = "%HOST%".r
+    assetHelper.withCleaner(wsk.action, actionName, confirmDelete = true) {
+      (action, _) =>
+        action.create(actionName, Some(file), web = Some("true"))
+    }
+    try {
+      //Create the API
+      var rr : RunResult = apiCreate(
+        basepath = Some(apiName),
+        relpath = Some(testRelPath),
+        operation = Some(testUrlOp),
+        action = Some(actionName),
+        responsetype = Some("http")
+      )
+      verifyApiCreated(rr)
+
+      //Get the api so we can create the swagger from the returned output
+      rr = apiGet(basepathOrApiName = Some(apiName))
+      rr.stdout should include regex (s"""target-url.*${actionName}.http${reqPath}""")
+      val swaggerFile = writeSwaggerFile(rr)
+
+      //Delete the api so we can re-create it using the swagger
+      rr = apiDelete(basepathOrApiName = apiName)
+      verifyApiDeleted(rr)
+
+      //Create the api using the swagger file.
+
+      rr = apiCreate(swagger = Some(swaggerFile.getAbsolutePath()), expectedExitCode = SUCCESS_EXIT)
+      verifyApiCreated(rr)
+      val swaggerApiUrl = getSwaggerUrl(rr).replace("{name}", testUrlName)
+
+      //Lets validate that the swagger we get from the create contains the correct info.
+      rr = apiGet(basepathOrApiName = Some(apiName))
+      rr.stdout should include regex (s"""target-url.*${actionName}.http${reqPath}""")
+      val params = getParametersFromJson(rr, testRelPath)
+      params.size should be(1)
+      validateParameter(params(0), "name", "path", true, "string", "Default description for 'name'")
+
+      //Lets call the swagger url so we can make sure the response is valid and contains our path in the ow path
+      val apiToInvoke = s"$swaggerApiUrl"
+      println(s"Invoking: '${apiToInvoke}'")
+      val response = whisk.utils.retry({
+        val response = RestAssured.given().config(getSslConfig()).get(s"$apiToInvoke")
+        response.statusCode should be(200)
+        response
+      }, 6, Some(2.second))
+      val jsonReponse = JSON.parseFull(response.asString()).asInstanceOf[Option[Map[String, String]]].get
+      jsonReponse.get("__ow_path").get should not be ("")
+      jsonReponse.get("__ow_path").get should include (testRelPathGet)
+
+    } catch {
+      case unknown: Throwable => exception = unknown
+    } finally {
+      apiDelete(basepathOrApiName = apiName)
+    }
+    assert(exception == null)
+  }
+
   it should "reject an api commands with an invalid path parameter" in {
     val badpath = "badpath"
 
diff --git a/wski18n/i18n_resources.go b/wski18n/i18n_resources.go
deleted file mode 100644
index bf3bbae4..00000000
--- a/wski18n/i18n_resources.go
+++ /dev/null
@@ -1,463 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file 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.
- */
-
-// Code generated by go-bindata.
-// sources:
-// wski18n/resources/de_DE.all.json
-// wski18n/resources/en_US.all.json
-// wski18n/resources/es_ES.all.json
-// wski18n/resources/fr_FR.all.json
-// wski18n/resources/it_IT.all.json
-// wski18n/resources/ja_JA.all.json
-// wski18n/resources/ko_KR.all.json
-// wski18n/resources/pt_BR.all.json
-// wski18n/resources/zh_Hans.all.json
-// wski18n/resources/zh_Hant.all.json
-// DO NOT EDIT!
-
-package wski18n
-
-import (
-	"bytes"
-	"compress/gzip"
-	"fmt"
-	"io"
-	"io/ioutil"
-	"os"
-	"path/filepath"
-	"strings"
-	"time"
-)
-
-func bindataRead(data []byte, name string) ([]byte, error) {
-	gz, err := gzip.NewReader(bytes.NewBuffer(data))
-	if err != nil {
-		return nil, fmt.Errorf("Read %q: %v", name, err)
-	}
-
-	var buf bytes.Buffer
-	_, err = io.Copy(&buf, gz)
-	clErr := gz.Close()
-
-	if err != nil {
-		return nil, fmt.Errorf("Read %q: %v", name, err)
-	}
-	if clErr != nil {
-		return nil, err
-	}
-
-	return buf.Bytes(), nil
-}
-
-type asset struct {
-	bytes []byte
-	info  os.FileInfo
-}
-
-type bindataFileInfo struct {
-	name    string
-	size    int64
-	mode    os.FileMode
-	modTime time.Time
-}
-
-func (fi bindataFileInfo) Name() string {
-	return fi.name
-}
-func (fi bindataFileInfo) Size() int64 {
-	return fi.size
-}
-func (fi bindataFileInfo) Mode() os.FileMode {
-	return fi.mode
-}
-func (fi bindataFileInfo) ModTime() time.Time {
-	return fi.modTime
-}
-func (fi bindataFileInfo) IsDir() bool {
-	return false
-}
-func (fi bindataFileInfo) Sys() interface{} {
-	return nil
-}
-
-var _wski18nResourcesDe_deAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func wski18nResourcesDe_deAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesDe_deAllJson,
-		"wski18n/resources/de_DE.all.json",
-	)
-}
-
-func wski18nResourcesDe_deAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesDe_deAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/de_DE.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesEn_usAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x5d\x4f\x73\xdb\x38\xb2\xbf\xcf\xa7\xe8\xca\xc5\xce\x2b\xd9\xd9\x3d\xbd\x7a\x49\xcd\x41\x13\x7b\x36\xde\x49\x6c\x57\xec\xcc\xee\xd4\x66\x6b\x04\x91\x90\x85\x35\x05\x70\x00\xd0\xb2\x92\xf1\x77\x7f\x05\x80\xa4\x48\x09\x7f\x49\x39\xd9\x53\x1c\xb1\xfb\xd7\x0d\xa0\x01\x34\x1a\x0d\xe0\x5f\x3f\x00\x7c\xfd\x01\x00\xe0\x05\xc9\x5f\xbc\x86\x17\xd3\xb2\x2c\x48\x86\x24\x61\x14\xf0\x23\x91\x38\x87\x8a\xe2\xc7\x12\x67\x12\xe7\xc5\xe6\xc5\xc4\x10\x4b\x8e\xa8\x28\x34\x59\x0c\xd7\x0f\x00\x4f\x93\x5d\x51\x1f\x2b\x0a\x47\x5f\xbf\x9e\x5e\xa2\x15\x7e\x7a\x82\x93\x93\x25\x2e\xca\x23\x58\x30\x0e\x95\x40\x77\xf8\xf4\x33\x75\x88\x8b\xe1\xb4\x8a\xc4\x9c\x33\xfe\x1a\x1c\xb0\xcd\x57\x2b\x2b\x65\x12\x04\x96\x0e\xd6\xe6\xab\x95\xf5\xaa\xc4\xf4\x1f\x4b\x22\xee\x21\x2b\x58\x95\x43\xc6\x56\x65\x25\x09\xbd\x53\x7f\xad\x10\xcd\xa1\x20\x14\x03\xa1\x12\xf3\x05\xca\xf0\xa9\x43\x48\x3a\x8e\x55\x9d\x07\xcc\xe7\x4c\x60\x60\x95\x2c\x2b\
 x57\x81\x76\x88\xac\x40\x39\x9e\x57\x77\x50\xe0\x07\x5c\xf8\xc1\x2c\x84\x56\x40\x54\xc9\x25\xe3\xe4\x8b\x31\xa4\xd9\x2f\xe7\xbf\xcd\x1c\x88\x36\x4a\x2b\xe4\x5a\xd7\xd7\xf4\xfa\x02\x66\xef\xae\x6e\x6e\x5d\x78\x7b\x64\x21\xb0\x5f\xcf\x3f\xde\x5c\x5c\x5d\x46\xe0\xb5\x94\x56\xc8\xf9\xa6\x44\x42\x40\x86\xb9\x24\x0b\xd5\x85\x30\x64\x4b\x9c\xdd\x13\x7a\xe7\x80\xf6\x71\x58\x45\x7c\xa2\x68\x5e\x60\x90\x0c\x08\x25\x92\xa0\x82\x7c\xc1\x20\x30\x7f\xc0\x1c\x32\x46\x29\xce\x14\xf4\x6b\xf8\xfa\xf5\x14\x73\xfe\xf4\xe4\x90\x9b\x0c\x63\x55\xe6\x1a\x71\xb4\xc2\x12\x73\x40\xfc\xae\x5a\x61\x2a\x05\xac\x2a\x21\x61\x8e\x01\xc1\x3d\xde\xc0\x03\x2a\x2a\x0c\x25\x22\x5c\x63\x21\x7e\x27\x9c\x3a\x0d\x45\xb3\xaa\x36\xa5\x94\x49\x63\x50\x87\xd0\x6d\x30\x9c\x55\xb9\x9f\x11\x29\x70\xae\x6a\xbf\x44\x5c\xe0\x2d\x64\xb0\xdd\x62\x38\xed\xd6\xce\xf8\x3d\xac\x89\x5c\x02\x45\x2b\x2c\x4a\x94\x61\xe1\x32\x77\x1b\xa9\x15\xb4\x20\x42\x02\xa6\x92\x48\x82\x05\x10\x0a\x72\x89\x21\xab\x38\xc7\x54\x6e\x99\x1d\x62\x22\x99\x03\xbd\x
 80\xcd\x25\xaa\x79\x35\x20\x5b\x00\x7a\x40\xa4\xd0\xdf\xb7\xfa\x27\x74\x88\x74\x44\xab\x8a\x77\x58\x82\xe4\xe4\xee\x0e\x73\x31\x01\xa4\xfb\x93\xfa\x83\xe6\xc0\xab\x62\x5b\x62\x8e\xef\x88\x90\x7c\xa3\x27\x3c\x14\xac\xb5\xd1\xb0\x56\x65\xd5\xfc\x4b\xf5\xfc\x7b\x04\x44\x80\x9a\x00\x91\x32\x68\x92\xc3\x1f\x15\x2a\xc8\x82\xe0\x5c\x63\x04\xeb\x71\x08\x52\x7a\x13\xb7\x66\xa3\x4a\xd7\x96\x0d\x1a\xe1\xfa\x7f\x4f\x4f\x47\xe3\x5a\x3d\x5d\x88\xb5\x20\xe7\x1d\x13\x6f\xf9\x34\x53\x07\xc5\xe9\x1d\xc5\x72\xbb\xfb\xa7\xcd\x78\x7d\x5d\xd2\x4a\x1f\x18\x53\x4a\x94\xdd\xa3\xbb\x88\x11\xa5\x25\xb4\xcf\x9f\x84\xe6\x6a\x60\x33\xd3\x80\x50\xed\x82\x1a\x16\xd7\x04\xea\x63\xb1\x0a\xb9\xa0\xc6\x1c\xcb\xbd\xe9\x46\x37\xad\xfe\x39\xc6\x76\xd2\x71\xbc\xea\xa0\xfd\x19\x46\xe3\x6c\x7f\x4f\x51\x2a\x15\xcd\xaa\xda\x4f\x84\xe6\xda\x21\xe5\xd8\x40\x2d\xf4\xec\x13\x54\x22\xcc\x67\x15\xf7\xf5\xeb\x29\xbb\x7f\x7a\x32\x6c\x38\x87\x79\x0d\xd3\x8e\x28\xce\x4e\x12\xc3\x69\x15\x69\x18\xd4\xf8\x88\xd7\x01\x43\xb3\x92\x06\x46\xa
 e\x9a\xa7\xa6\x86\xce\xd8\x98\x30\x32\x45\x81\x44\x55\x68\x03\x91\x5e\xa1\x36\x4e\xab\xc8\xaa\xcc\x75\x2d\xe9\x95\xa3\xd0\xcb\x99\x9a\x77\x02\x8c\x43\x5b\x89\x0d\x20\x59\x00\x91\x90\x33\x6c\xa6\x0a\xcd\xe4\xd0\xe9\x20\xd0\x0e\x37\xd6\x70\xd4\x12\x22\xad\x3c\xc4\xe5\x6d\x12\xc3\x34\xa4\x49\x7c\x9c\x4e\x47\xc4\x6f\xda\x5d\x8a\x80\x45\x77\x48\x07\x9a\x73\x18\xc1\x5b\x71\x77\x4c\x0e\xa8\x34\x17\x97\x63\x25\x5c\xe0\x6d\x87\x73\xae\x82\x7b\x44\x81\x6a\xeb\x53\x0f\xac\xb9\x28\x10\x6f\xe5\x19\x84\x21\x56\xe7\xe3\xf4\xb8\x1e\x45\x11\x72\x0d\xf6\xe9\xac\x70\x97\xac\x76\x22\xb7\x7e\x58\x8e\xa5\x8e\x48\x9d\x82\x8e\x20\xad\xc5\x3d\x94\x9c\x95\x98\xcb\x0d\x08\x2c\xe1\xe4\xa4\xa5\x3d\x52\x03\x04\xa6\xa2\xe2\x58\x7b\x78\xea\xc3\x76\x5e\x24\x02\x4a\x8e\x33\x9c\xab\x99\x63\x03\x08\x3e\xbf\x78\xf5\xf9\x85\x43\xdf\xef\xa0\x48\xba\x7b\xdc\xd4\xa5\xc3\x73\x1d\xed\x19\x27\xe1\x5b\xd5\xe7\x78\xc1\xb1\x68\xfd\xc1\x66\xc6\x76\x59\x89\x93\xdc\x3b\x9e\x37\x5c\x4e\x2d\x53\x87\xfa\x01\x80\xc1\xe5\x56\x8d\x89\x73
 \x10\x55\x96\x61\x21\x16\x55\x51\x6c\x9c\x1d\x32\x8a\xd5\xe3\xeb\xb4\xce\x91\x78\xed\x75\x74\xba\x74\x9e\x99\x3e\x0c\xb7\x4f\xe7\x19\x74\xc3\x70\xfb\x74\x56\xb8\xdb\xe5\x76\xa0\x6c\x5b\x0d\x23\xa9\x3a\x5e\xbd\x2c\x25\xab\xb2\xc0\xaa\xdf\xe1\xbc\x59\x34\x4b\xc4\xd5\xf4\x94\xe3\xb2\x60\x1b\xf5\xc9\xa1\xc4\xa1\xd0\x0f\x62\xbd\x90\x57\xba\x9f\x6e\x63\xf4\xf0\xee\xf6\xf6\x1a\x84\x44\xb2\x12\x90\xb1\xdc\xac\x17\xd5\x1f\x07\xb3\xf0\x44\xa1\xf6\x00\xf1\x76\x8d\xa2\x63\x67\x7a\x8d\x3b\xfb\xe5\xfc\x37\xf8\x75\xfa\xfe\xd3\xf9\x4c\x29\xb1\x42\xae\x36\x88\xe5\xb6\x8a\x9e\xfd\x7c\xf1\xfe\x7c\x06\x19\xa3\x6a\x6c\x53\xae\xa4\x15\xee\xef\x37\x57\x97\x7e\x2d\x06\x00\xed\x28\x44\x99\xc4\x27\x92\x9d\x34\xc0\x8c\x0b\x05\x7c\x76\x05\x97\x57\xb7\x70\xfb\x71\x7a\x79\xf3\x7e\x7a\x7b\x0e\xb7\xef\xce\xe1\x68\x83\xc5\x11\x4c\x2f\xcf\xe0\x88\xb2\xa3\x53\x80\xdb\x77\x57\x37\xe7\x30\xfd\x78\x0e\x3f\x5f\xfc\xf3\xfc\x0c\xde\xbe\xbf\x80\xe9\xc7\xbf\x7d\xfa\x70\x7e\x79\x6b\xea\xe1\xa6\x51\xdc\x14\xbc\xb1\xda\x07\x22\
 xc8\x9c\x14\x44\x6e\x60\x76\xf3\xf6\xea\xfa\x7c\xf6\x06\x36\x58\xc0\x8f\x20\x96\x88\xe3\x7c\x02\x94\xc1\x8f\x50\x72\xf2\x80\xa4\xcb\x07\x1a\x08\x66\x6d\x11\x51\xad\x56\x88\x93\x2f\xdb\x8e\x95\x63\x89\x48\x21\xde\x74\x57\xf7\x26\x86\xc0\xf1\x82\x3c\xc2\xe7\x17\xff\xf3\xf9\x05\x20\x8e\x61\xce\x2a\x9a\x3b\x74\x1c\x8f\x6b\x55\x97\xd0\xac\xa8\x72\x0c\x65\x35\x2f\x48\x56\x6c\xea\x92\xee\xc5\x33\x39\x16\x55\xe1\x32\x9e\x44\x10\xfb\x26\xd8\xa3\xc1\x50\x74\x0b\xc2\x85\x84\xd9\xcd\x2f\x17\xd7\x33\xa0\xd5\x6a\x8e\x79\x7f\xb6\xe6\x6c\x15\xd6\x6a\x0c\xa2\x55\x45\x46\x8b\x0d\x70\x2c\x2b\x4e\x61\xf6\xfe\xe2\xc3\xc5\xad\x1f\x2b\x63\x45\x61\xf6\x1f\x1c\x1a\x8e\x00\xb4\x2a\xd8\x78\x6b\x2e\x33\x6f\x3e\x07\x82\x60\x66\x9b\xa8\xa6\x26\x11\xc1\xb0\x3d\x06\x7b\xcf\x50\x0b\x26\xbf\x86\x3d\x92\x80\xbb\xa8\x68\x55\xa5\xb4\x2e\xaa\x1e\xa5\x12\xfc\xc1\x20\x80\x3f\x16\x51\x10\xe5\xea\x66\x98\xeb\x3d\x56\x9b\xcf\x7c\xa7\x7d\x66\x45\x71\x64\xe4\xd5\xbe\x32\x5e\x1b\x51\xee\xad\xe4\x03\x0b\x89\x29\xc8\x3d\xde\xf8\x
 45\xdc\xe3\xcd\xc8\x62\x8c\x13\xe1\x2d\x84\xb1\x40\x54\xc9\xa5\x5f\x82\xa2\x18\x5a\x8a\xc3\xc8\x88\xb0\xea\xe9\xf5\x05\x2c\x99\x90\x86\xe9\x8d\xc6\xe8\xff\x66\x42\xa0\x25\x51\xbf\xd4\x1b\x14\xc4\x04\x4c\x13\xed\xff\x40\xa2\x22\xda\xa6\x45\xd5\xdd\x8e\x29\x5e\x03\x19\x59\xef\x3e\xfe\x48\xf1\x0f\x98\x0b\xe5\xce\x6c\x11\xea\x5f\x92\x94\xf0\xa3\xd8\xf7\x70\x2b\xb9\x54\x73\x61\xa6\x17\x10\x95\xc0\x7c\x1b\xce\x5b\xa2\x07\x6c\xf7\x50\xdf\x68\x11\x4d\x12\x45\xe4\x0a\xef\x59\x44\xd9\x23\x19\x56\xaf\xba\x59\x35\x58\x76\xa0\x0a\x9c\x87\x77\x6e\xc6\xa2\x46\x98\xc2\xb6\x06\xb6\x4d\x18\x19\x3d\x8a\x00\x18\x34\x6b\x1d\x8b\x97\xa3\x27\xae\x3e\x86\x7d\xa9\x4b\x23\xe6\xe0\x1d\xa2\x40\x79\x0c\xf5\xa8\x79\x38\x02\x22\x7a\x26\xd6\x58\x69\xf3\x6a\xcb\x12\x3b\x4b\xa6\xc9\xe8\x71\xc4\xce\x61\x91\x22\x6c\x1c\x49\x1d\x40\x73\x25\xda\xbc\xe1\x49\x19\xf1\x93\x4a\xb3\xcf\x95\x38\xba\xc7\x97\x69\x9f\xcb\x2a\xca\xcc\x8a\x39\x5e\xa0\xaa\x68\x26\x45\xb6\x50\xc6\x59\xff\xa6\x00\x49\x51\xc0\x1c\xab\x01\x37\x77\x97\x7
 4\x08\x92\x5b\xa5\x26\x46\xb3\x03\x28\x97\x48\x42\x86\x68\xa4\x3a\x09\x28\xee\x5d\x19\xff\x88\x72\x17\x1c\x4f\x3a\xfd\xd1\x15\xcc\xeb\x50\xf8\x20\xee\xb1\x4b\x8b\x0e\x81\x27\x8d\x4e\x75\x26\x6f\xf6\x9c\x26\x08\xe4\xe1\x29\xfb\x0d\xa6\xe0\x69\xa2\x00\x50\x6d\x9d\x41\xac\x86\xce\x03\x17\xca\xc7\xd9\xa5\xf2\x40\xbd\x7d\x1f\xa7\x59\x97\xce\x31\x8d\xdc\x53\xb6\x76\x81\x34\x5f\x03\x75\x34\xaf\x48\xe1\x0a\x9a\xec\x52\xc5\x40\xd5\x2b\xf0\x38\xc4\x86\x38\x6e\x6b\x63\xcb\x46\xa8\x09\xa2\xa5\xa5\x38\x46\xc2\x44\x64\xb1\xba\xbb\xc9\x3e\x5d\x54\xa5\xc5\x5a\x6a\x9f\xda\xae\x69\x51\x84\x83\x0f\x3b\x44\x1e\x1d\x67\x97\xd3\x0f\xe7\x37\xd7\xd3\xb7\xe7\xfe\xb4\xd8\x2e\x5d\xa0\x39\x0b\xa6\x13\x5c\xb7\xf2\x61\x41\x0a\xe3\xb1\xaa\x3f\xd2\xb7\xa6\x92\x01\x03\x0a\x72\x8c\xf2\xae\x47\x75\x00\x15\x07\x40\x06\x94\x44\x7a\xab\x07\x32\x46\x17\xe4\xae\xe2\xc6\xe0\xb6\xe8\x09\xba\xc5\x23\x79\x33\x97\xb4\xdb\x81\xf2\x9c\x2b\xb0\xa3\x76\x81\x19\x9f\xac\x14\x01\x60\x55\xe0\x1f\x3b\xf1\x33\x53\xb1\x6b\x4e\xea\x74\x8c
 \x8a\x87\xfd\xe9\x34\x8c\x40\x04\x50\x67\x60\x06\xc3\x7e\x86\xca\x1e\xcd\x35\x6d\xa3\x28\x5c\xd1\xd9\x0e\x45\xc0\x50\x3a\xa4\x03\xb7\x7e\xc3\x08\x5e\x27\xd3\xb0\x9b\xc4\xd4\x84\xd5\xa2\x93\xcd\xbe\x71\x48\x44\xa8\xce\x7a\x24\xa1\x4c\x8d\x0e\xed\xd0\x3c\x8d\x30\x84\x3f\x4b\xc3\xf0\x27\xd7\x9b\x9b\xcf\xe9\x81\x6a\x4a\xb3\x67\xe7\x71\x42\xbb\x54\x11\xf9\x41\x23\xaa\x2e\xc0\x1e\x21\xbc\xde\x80\x64\x8b\xb1\x6a\x44\x01\x79\xdb\xb1\xdf\x0c\x6a\xb9\xf0\xf5\xeb\xa9\x81\x8d\x68\xcd\x10\xb7\x2f\x9f\x91\xe2\xb5\xaf\x3f\xec\x52\xc5\x65\x31\x8e\xa8\xcf\x30\x42\x54\xfe\x62\x62\x7f\x70\xb2\xc5\x66\x2e\x2a\xc6\x7e\x6e\xa1\x86\x1a\x97\xb3\x98\x02\x1a\x0a\x22\x19\xf4\x11\x0d\x13\x46\x88\xca\x62\x4c\x6c\x18\x27\x9b\x77\x9c\x0a\x0c\x50\x61\xdf\x4e\x72\x82\x1f\x46\x55\x57\x0c\x46\x30\x7b\x31\xb1\xb2\xac\x2c\xbe\xbc\x45\xdf\x44\xd8\xa1\x88\xcb\x58\x1c\x33\x0d\x06\x11\xa2\x72\x15\x53\x27\x41\x17\x9b\x3f\x4b\xd1\xe7\xb9\xed\x10\xa5\x45\xf5\xf7\x36\x7d\x9c\x25\x48\x82\x48\xcf\x09\x34\xa7\x83\x9e\x29\x21\x30\
 x1e\xfc\xbb\x66\xbf\x68\xa3\x38\x48\xea\xcb\x10\x24\x57\x7c\x81\xad\x90\x24\x19\x2a\x8a\x4d\xcf\xe1\x46\x0b\x89\xeb\x59\x42\xcd\x1b\xc4\x99\x08\x95\x80\x10\xa1\x42\xcf\x7b\x9d\xe3\x05\xe3\xd8\x74\xaa\x04\x25\x42\x18\x81\x0c\x20\xcd\x56\xa7\xe9\x04\xd3\x7a\x7a\xc4\x81\xf5\x99\x32\x59\x91\xdf\x07\x57\x68\x0d\x9d\x23\xf5\x47\x48\x35\x1a\xdc\x9c\xfd\x02\x88\x4b\xb2\x40\x99\x74\xa9\x69\xa7\x8d\x87\x9d\xc0\x5a\x87\x9a\xcd\x3a\xf9\xed\xd5\x87\xeb\xab\x4b\x65\xdc\x75\x66\x19\x52\xf5\xca\xb2\x7b\xcc\x27\x40\x58\x7d\x0c\x70\x8e\xc4\x52\x35\x47\x8a\x4a\x29\x72\xae\x6e\x76\xe4\x38\x13\x30\x95\x88\x8c\xad\x4a\x46\x31\x95\xbd\x34\xe7\x15\x11\x82\xd0\xbb\x53\xb8\xa2\xb8\x43\x72\xdc\x2b\x0c\xe3\xad\x8c\x97\xed\x59\x5b\x51\xe2\x4c\x1f\x22\xf4\xa4\x66\x3e\xaf\xdc\xe0\x22\x84\x62\xae\x9c\xaa\xa1\x4b\x0f\x2f\xbb\xfd\xd8\x1c\x12\xcb\xdf\x55\x69\x54\x0f\x63\xf4\xf7\x95\x70\x1d\x37\x57\xb5\xa3\xa8\x41\x15\xee\x64\xcb\x02\x22\xe3\xa4\x94\x70\xdc\x0a\x7d\x69\x66\x1e\x6d\x2b\xdb\x14\xd6\xe6\x78\x6e\x4e\x38\x
 ce\x24\xe3\x9b\xd3\xcf\xf4\xb6\x8d\x13\xf4\x2e\x2e\xe8\x80\xb3\x05\xac\xc5\x7d\xf3\x59\x4c\x40\xb0\x8a\x67\x26\xc9\x43\x29\x02\xfb\x8a\x10\x2a\x19\x6c\x58\x65\x9a\x02\x30\x7d\x20\x9c\x51\xd5\x8c\xae\xc9\xcf\xd3\xf0\x47\x3a\x11\xb5\xfe\xb9\x3f\xa9\x9e\xc2\xaf\xda\xe4\xdb\xcf\x7b\x9d\x2a\xa6\x4f\x7d\x1b\xd9\xce\x62\xb7\xf1\xc4\xc6\x69\x40\x05\xc7\x28\xdf\x98\x55\x84\x38\x05\x38\x33\xbe\x18\x91\xe6\xa0\x30\x96\x7c\xe3\xba\x97\x62\x04\xa0\x53\xc1\x7e\x1d\xe8\xaa\xaa\x4d\x2b\xe9\x5c\xe1\x20\x28\xa7\x52\xa6\x9e\x41\xdc\xab\xa2\x30\x6a\xb6\xf3\xd6\x1d\x9b\x47\xd2\x61\xf3\x1e\xf5\x46\x80\x5a\x15\x3d\x63\x6b\x5a\x30\x94\xe3\x1c\xb6\x17\x86\x90\xab\x1b\x10\x12\x71\x7d\xe6\xb4\x2c\x4f\xe1\x13\xfd\x42\xca\x7e\x83\xd1\x1c\x58\x89\x69\x13\x7a\xfe\x0f\xce\x74\x1e\xc8\x3f\x33\x96\x7b\x72\xb6\x9e\x4d\x5c\xec\xe2\x4c\x81\x56\xbc\x28\x91\x5c\x2a\xdc\x9b\xb3\x5f\x86\x2c\xcf\xbc\x28\x56\x55\x6e\xcc\xd5\x17\x8b\xf6\x7a\x05\x81\xa9\x89\xdb\xef\x75\xe0\x18\x9d\x06\xc3\xd9\x4f\x90\x73\xce\x3a\x7e\x9c\xb2\xf
 9\xdd\x1e\x1a\xd4\x28\x0d\xc3\xa7\x06\x2b\x37\x0a\xa1\xbe\x2c\x84\x63\x51\x32\x2a\xb0\x19\xb1\x15\x64\xac\x2a\x09\x38\xee\x3e\xdc\x74\x9f\x83\x0e\x7f\x63\x50\x3d\x35\x57\xd1\xbf\x7d\x21\x65\xa9\x0a\x3d\xb0\xf9\xe2\x10\xbc\x2a\x48\xc4\xf9\x28\x0d\x22\x00\x42\x5e\x78\x7d\x7d\x45\xd8\x0d\x6f\x08\xad\x80\x0b\xc2\x71\x43\x02\xf8\xc1\x7d\x5a\xc7\x42\x18\x18\x8e\x7a\x1c\xc3\xfc\xb8\x08\x08\x6f\xf8\xa3\x66\xc5\x39\xbc\xea\xdf\xf5\xf0\x6a\x1b\x13\xd6\x95\x44\x72\x85\x48\xf2\x88\xd8\xc8\x30\xcc\x50\xa0\xb9\x46\x0d\xc7\x9a\x1b\xc2\xef\x1a\x02\x68\xf6\x1c\x4f\x4e\xea\xc3\x16\xad\xa7\xd6\x49\xdb\xe5\x77\x0f\xa8\xd0\xf9\x9d\x86\xb8\xb3\x0c\x32\x1a\x30\xae\x15\x08\xec\x6b\x1e\x46\x46\x5c\x74\x7e\x9c\xb5\x46\x81\x44\xc5\xe8\x1b\x88\xf4\x30\xbd\x8d\x33\x36\x52\x5f\xf3\xf6\xe3\xea\x0d\xe0\xb8\x78\x3d\xa2\x03\xd0\xe3\x02\xf7\xe3\xda\x2c\x0a\x24\x2a\x7c\x9f\xde\x66\x3e\x4e\x67\x10\xdf\x3f\x50\x74\x29\x22\xf6\xf9\xc6\xd5\x5d\x18\x21\x18\xc6\x4f\xaf\x34\x17\x97\x2f\x98\xef\xaf\xb3\x1d\xa2\xb8\x90\xfe\xb8
 \x9a\x8b\x02\x89\x0a\xec\xa7\x57\xa0\x8f\xd3\x1f\xde\x0f\xb8\x1c\xfb\x74\xe9\xf1\xf5\x86\xf5\xb9\x42\xec\x49\xf8\x01\xf5\x09\x7d\x60\xf7\xfd\x46\x54\x7f\xb7\x47\x7c\xb1\x9a\xb3\xf4\x81\x39\x93\xa6\x84\x71\xde\x9e\x78\xd0\x1f\xeb\x83\x05\x4d\xe6\x50\xc4\xda\xfd\x1b\x09\xff\xae\xbe\x45\x53\xa4\x83\xec\x30\x0c\x04\xb3\xb6\x7c\x83\xa5\xab\x6f\x36\x7d\x7b\x7b\x71\x75\xf9\xfb\xe5\xf4\x83\x33\xb5\xcf\xc3\x10\x88\xdd\x37\x9c\x87\x3e\xbd\x3b\x14\xd7\x7e\xe0\xb3\xbd\xb2\x6b\xc0\xc1\xf3\x48\xe6\xc8\x73\xe7\x36\xb4\x21\xc7\xce\x43\x38\xf6\x03\x56\x7b\x57\x59\xea\x18\x2d\x08\xac\xe0\xa4\x32\x2e\xb5\xb4\x6d\x3e\xfe\x51\x31\x7d\x9d\xc1\x42\x0d\x4c\x9b\x46\x3a\x98\x23\x44\xae\x05\xf5\x61\x65\x38\x23\x01\xad\x8b\x3d\x33\xce\xf5\xd3\xd3\x2c\xe5\x78\x5f\x12\xc4\x40\x25\x74\x7b\x1c\x40\x93\x5d\x1c\xc7\x99\x66\xef\xc9\x7d\xef\x51\x7c\x3d\xae\xb8\x7a\xa4\xf9\x68\x65\xfc\x79\x37\x6c\xbc\x73\x01\xa4\x0e\x19\x30\x1e\xed\x8d\x0f\xc7\x8b\x09\xa3\x99\x60\xca\xe8\x48\x5a\x18\xc6\xa3\x0c\x2b\xb1\xee\xbd\x63\x34\
 x89\xc5\x08\x9e\x48\x1b\xa4\x43\x02\x40\xc8\xa7\x2a\x31\x15\xfd\xab\x46\x74\xc0\xa9\x8e\x78\xa5\x78\x4f\xd1\x48\x71\x6b\xeb\x7e\x3c\x30\x27\x5c\x41\xae\x97\xaa\xa4\x2d\xe8\xb8\x85\xf7\x08\x09\x11\xb5\x0a\x0a\x01\xe7\xfd\xbc\xf3\xc3\x95\xe1\x00\x22\xe2\xda\xe1\x99\xf4\x1f\x87\x1e\xd1\xbb\x25\xe2\x63\x3b\x77\x00\xc2\xa3\x04\xc7\x28\x1f\xa9\x44\x24\xc4\x01\x3a\x53\x13\x5c\x7e\xbe\xce\xe4\x97\x30\xd2\x0e\x0f\xa2\xfe\x40\xf4\xe0\xf0\x3e\xc8\x00\x12\x00\xa2\x14\xe8\x0e\xca\xfb\x57\x48\xb5\x12\xe4\xa6\xc4\xce\x70\xc0\x38\xcc\xc0\xe6\x44\x7d\xa3\x76\x70\x6f\xa2\xa1\xf3\x45\xc7\xcd\x5d\xb1\xc8\x77\x95\x8d\x8d\x32\x50\x91\xf5\xc5\xef\x66\x85\xdc\xa4\x5c\xc4\xdf\x20\x3f\x00\x28\xae\x57\x74\xd6\xec\x83\x6d\xdf\x8b\x11\x15\x7f\xae\x11\xd2\xc3\xcf\x16\xc6\xd8\xe8\xb3\x61\xed\x85\x87\x69\x83\x37\x32\xf8\x9c\x8a\x1c\x17\x78\x46\xa9\x8f\x44\xb8\xf8\xa2\xc2\xcb\xc9\x4d\xe2\x61\x74\xa4\xce\xe9\x88\x92\xb7\xa3\xf5\x69\xe2\xe2\x63\xa3\x2c\x3a\x06\xc3\x5b\x7d\x06\xe0\x90\xfb\x7f\x43\x10\x9d\xd1\x7c\x6f\x
 6d\x77\x08\x22\x62\xf9\xc9\xe6\x68\x65\xb2\xe7\xb6\xfa\xb4\xf4\x69\xd8\x0d\xda\x27\x1b\xb0\x83\xc9\x17\xe8\xf7\x2a\xda\xa7\x89\x0b\xf3\x8f\x32\xde\x18\x8c\xa8\x20\x7f\x72\xd5\x79\x18\xfd\x21\xfe\x7a\x42\x06\x42\xbb\xcf\x5d\xa8\x91\xb3\xf9\x52\xc7\x92\x4c\x36\x63\xe8\x5d\x81\xf1\xb8\xe9\x5b\x08\x0d\xe0\x33\xed\x20\xa4\xc0\x5b\x95\x7f\xcb\xaa\x22\xd7\x93\xcd\x82\xd0\x1c\x8e\x56\x88\xd0\x23\x58\x61\xb9\x64\xba\xec\x1d\x28\x87\x7e\x29\x08\xd1\x03\xc7\x88\x3d\xc0\x74\x03\xb7\x9c\xec\x1e\xe1\x54\xc7\x60\x58\xd5\xb0\x46\xc5\x44\x55\x96\x8c\x77\x7a\x0f\xaf\xa8\x24\x2b\x97\x89\xa7\x61\xb8\x1d\xdd\x7a\x97\xbc\xa6\xd7\xb7\x2e\x22\x38\xfd\x42\xca\x36\xbf\x1c\x38\xfe\xa3\x22\x1c\x8b\x3a\x8d\x5a\x27\x7e\xe9\xec\x5f\xc3\x73\xaf\x8c\x01\x3f\x96\x05\xc9\x88\x74\xbe\x4b\xf7\x4c\xc2\xac\x05\xfb\x3b\x7a\x40\x6d\x87\xa9\x01\xe1\xe4\x64\xa5\xfb\x14\x6b\x90\x4d\xd3\x55\x45\xb1\x39\xe9\x3f\x6e\xa3\x37\xec\x96\x18\x34\x7d\x56\x20\xe1\x5a\x50\x1c\x5e\x8e\x63\x03\x08\x23\x09\x66\x1f\x07\x90\x00\x8a\x24\x79\x6
 8\x6b\xe4\xb8\x0d\xdc\x95\x9c\x3d\x90\x1c\x0b\x40\x3a\x2b\x19\x49\xa2\x0c\x15\x3f\xe2\xac\x92\xad\xcd\x56\xf4\xa5\x73\xdb\xe8\xc0\x62\xec\x1e\xb8\x68\x11\xf2\x26\xe1\x96\xac\xd0\x1d\x86\x63\x35\xfa\xca\x25\x30\x0a\x67\xfa\xf7\x77\xd5\xfc\x65\x0d\xd6\x31\x01\x97\xff\x3d\x1a\x37\xaa\xee\xdb\x7b\xdf\xd5\x90\xbc\xe7\xeb\x47\xd6\x6c\x00\x24\x4a\x91\x9d\x7d\x18\x10\xf8\x8f\x0a\xd3\x0c\x77\xe7\x8a\xd6\x91\x8d\xd4\x2b\x0d\xd3\xae\xe6\x12\xc3\xec\x97\x8b\xcb\xb3\x59\x63\xdd\xfd\x91\x08\x8e\xf1\x23\x5a\x95\x05\x7e\x0d\x62\x4d\x16\xf2\x75\x7d\x03\xd3\x04\x28\xcb\xf1\x7f\x44\xf3\x7f\xa7\x91\x1e\x0c\xdf\xa9\x7e\xb7\x6b\xd6\xe0\x98\x4a\xbe\x81\x92\x11\x2a\xe1\x78\x51\x51\xf3\x2b\xe3\x7b\xdd\xba\x9e\x0c\x35\xc4\x7a\x89\x29\x20\xf3\x1c\xe7\xbc\xc0\xbe\x12\x3d\x9b\x48\x8f\x5b\x7d\x98\x8d\xee\x61\x58\xce\xba\x57\x4d\xc8\x2a\xd9\x5e\x0c\x4c\x28\xac\x48\x51\x10\x81\x33\x46\x73\x51\x1f\x8a\x5b\x2f\x49\xb6\xec\x56\x16\x11\x20\x31\x5f\x11\xaa\xcc\xd6\x53\xcf\x07\x81\x77\x2a\xbf\x42\x8f\x64\x55\xad\x60\x85
 \x57\x8c\x6f\xba\x42\x3e\xfc\xa4\xfd\xb6\xe0\x20\x96\x8a\x12\x54\xa5\x60\x77\x20\xc8\x17\x3c\x56\x99\x38\x1c\xfb\xf9\xa6\x82\xe9\x17\x31\xfd\x43\xd1\x2e\x55\x0c\xd4\x1b\x10\x4b\xb6\x06\x7d\xa1\xb4\xd2\xe0\xc1\x1c\x22\x31\xb7\x59\xc3\x71\x45\x0b\x2c\xc4\xf6\xba\x37\xd4\x5c\x09\xe3\xea\x89\x07\x83\xb7\x2a\x1f\x71\x33\x77\xeb\xe3\x1f\xea\xaa\x6f\x17\xa0\x55\x41\xff\xc5\xdc\x7b\x50\x23\x2f\xfa\xf6\xe1\x05\xb2\x54\xea\x5e\x99\x98\x4c\x32\x51\x3f\xf4\x7e\xd1\xa9\x0b\x0b\x42\xf5\xfb\xa9\xe1\x24\x96\x67\x12\x1b\x11\xd2\x36\x96\x17\x17\xd6\x6e\x68\x3d\xeb\xed\x20\xe2\x1e\xd9\xa0\x53\xf3\x03\x4f\xca\x0f\x5c\x7a\xd7\xaa\x3e\xe7\xf2\x3b\x45\x84\x37\xf2\x66\x80\x02\xd1\xb7\x9a\x28\x72\x21\x6d\xa8\x07\x2c\xa0\xf7\x18\x93\x04\xea\xd2\x93\x7c\xd8\xda\xdd\x03\xe1\xf4\x5b\xfa\x83\xb0\x6a\x89\x23\x67\x40\xf4\x48\x9f\x88\x6d\x6e\xdd\x01\x24\x15\xbe\x72\x01\x9e\x9e\x5e\x3a\x43\x59\x07\x16\x12\x15\x9e\xac\xe5\xc5\x46\x82\x9d\x6c\xee\xe4\x6d\x65\xc9\xec\x4e\xd4\x0b\x8e\x28\x1b\x74\xf3\x44\x58\x88\x66\x5c\
 xd4\x61\xb6\x41\xb6\xe9\x47\x18\xa6\xc2\x60\x6b\x8d\xc5\x8a\x50\xab\x63\x54\x83\xeb\x26\x84\x31\x54\x8d\xc1\xf5\x13\x8f\x66\x4f\x77\x63\x45\xa1\x03\xb1\x84\x56\xac\x12\x85\x79\xf7\x58\xf9\x9c\x2b\x2c\xc4\xf6\x39\x90\xfa\xdc\xad\x72\x2b\x2a\x4a\xb7\x2b\x66\xd7\x3c\x36\x1e\xd7\xaa\xee\xb5\x82\x0d\xae\x37\x76\xa9\xec\x59\x1e\x54\x2d\x38\xde\x4a\x5e\x9c\x64\xfa\xce\xbe\x47\x22\x5d\xb9\x98\x76\x5a\xa7\x86\xfa\x98\x5f\xbf\x41\x94\x19\x3b\x47\x17\x3f\x8f\x55\xcc\x67\x3a\xed\x98\xdf\xd1\xce\x98\xa8\x9a\xde\x3d\xce\xc6\xf1\xda\x13\x5f\x3b\xda\xa9\xe9\xb9\xdd\x45\x6d\xf2\x4d\x11\xed\x7a\xec\xee\xe4\xd6\x64\x9c\x31\x8e\x7d\xeb\x3d\x1c\xd2\xb9\x77\x81\x0e\x74\xf0\xf7\xe0\xb6\x4e\x79\xed\x61\xb6\x2b\x42\xcd\x5f\x5f\xe4\xbd\x42\x8f\x6a\xea\x0b\xfa\x95\xdf\x50\x01\xc7\x56\xb3\xa9\xd4\x45\x55\x6f\x0d\xd5\xad\x9f\x63\x73\x71\x85\x6f\x03\x3a\xcc\x69\x15\x59\x97\xb6\x5b\x36\x73\x3a\x96\xac\xb0\x90\x68\x55\x0a\xc0\x88\x17\x04\xab\x85\x34\xa2\x30\xfb\x74\x7d\x7b\x35\x7b\x03\x2b\x8c\x44\xc5\xcd\xae\x54\x
 2f\x44\x21\x08\xcd\x30\xdc\x2e\x27\xf0\x97\xbf\x4e\xe0\xef\x88\xc2\x5f\xff\xef\x7f\xff\xe2\x50\xfb\x5b\x49\x1f\x5a\xf4\x02\xc9\x56\xf4\xcd\xc5\xe5\xdb\xf3\x6f\x59\xf2\x43\x08\x8f\x58\xa9\xb6\x96\x12\x77\x23\x92\x85\xc5\x55\xbb\xfa\xba\x04\x13\x4d\x2e\x90\x88\x58\x5a\xf8\x79\xec\x65\x91\x9c\x94\xdb\x5a\xd3\x6b\x57\x21\x39\x46\xab\xee\x3d\xdc\xae\x52\xc5\x31\x3b\x04\xb3\x12\xca\x7a\x4e\x32\x71\xb9\xd9\xcd\xf9\xdb\xab\xcb\xb3\x9b\x19\xd4\xad\xe2\x14\x1b\xc1\xea\x10\x8a\xb8\x6c\x59\xfb\x33\xa1\xd8\x07\x01\x74\xe7\xba\x54\x66\x08\xd2\x10\x95\x3e\x5c\x5c\x7e\xba\x3d\xbf\x99\xc1\x8a\xd0\x4a\xe2\x11\x2a\x59\x91\x86\xa8\xf4\xee\xea\xd3\xc7\x9b\x19\x2c\x59\xc5\x47\xa8\xb3\x87\x32\x44\x95\xb3\xe9\x6f\x37\x33\xc8\xd1\x66\x84\x22\x3b\x18\x81\xa3\x38\x7a\xb1\xd8\x9c\xfb\x38\x6a\x0f\xc6\x20\xb8\xc7\x9b\x57\xe6\x00\x79\x89\x88\xeb\x48\x68\x3a\x8e\xf3\x34\xcb\xf6\x48\x51\x9b\x14\xa8\x43\x50\x29\x67\x6a\xe2\x31\xdc\x87\x6a\xb6\x0f\x6a\x0e\xd7\x23\x01\xc4\xde\x3c\xed\x96\xb3\xde\x25\x51\xc3\x50\xc6\x7
 2\xbc\xdd\x74\x56\x58\xf5\xfe\x6d\xee\xf4\x16\xd3\x40\x62\x14\x21\x22\x55\x6a\x8f\x23\x55\x04\x4c\x77\x34\x26\x02\x98\xf6\x5d\x50\x31\x40\xbe\x1f\xce\xa7\x5c\x3d\xbf\x5d\x9c\x25\xd4\x80\x83\xc7\x2e\xa6\x7d\x2e\xb4\x6d\xaa\xfa\xc5\xe1\xe6\xcd\xee\x88\xe6\x4e\xc2\x88\x51\x23\xa6\xac\x1e\x0e\x87\x08\x7d\x83\x62\x3c\xbe\x83\xdc\x03\x3e\x69\x4f\x6f\xea\x0c\xe3\x6e\x17\x88\xaa\xc6\x14\x0c\x87\x1a\x0d\x73\x7c\x31\xdd\x1c\xa9\x22\x40\xb5\xc9\xa6\x60\x28\x8f\xea\x2e\xe9\x40\xae\x8e\xd2\x50\x74\x42\xcd\xc4\x38\x6e\x7a\x19\x65\x0e\xd1\x35\xc3\xa1\xa7\xf3\x24\xe2\x58\xd5\x69\xee\x44\x69\xc8\x8e\xc5\xcb\x53\x35\xe6\x36\x85\x0b\x3e\x12\xe1\x61\x8c\x15\xa8\x07\x79\xc4\xef\xc4\xd3\xd3\x60\xd9\x1e\x0c\xc7\xd2\x1e\x65\xee\x94\xa6\xe6\xab\x3d\x58\x2d\xa1\xc0\xc8\x99\x2e\xde\x7e\xb6\x32\x53\x06\x2b\xc6\xf5\x83\x54\x2e\xdf\xba\x47\x62\xdf\x9f\x61\x3b\xb3\x65\xa8\xdb\x78\x18\x5c\xce\x97\xfb\xe9\x01\xdf\x8b\x03\xdb\x9d\xb3\xd0\x29\x6d\x07\x40\x9d\xc4\xe1\x4c\xb8\x35\x5f\x9d\x53\x50\x73\x40\xb7\xf1\xaa\xda
 \xbc\xa1\xbe\xd7\xe5\x99\x90\x62\x11\x9c\x7e\x51\xfb\xe2\x5b\x9d\xbb\x17\xef\x0c\x85\x38\x5d\xa5\x6e\xf9\x76\x75\xf6\x8c\x1d\x1e\x1e\x6f\xb7\x5d\x10\x5c\xe8\xe3\x84\x12\x77\xab\xc3\x25\x29\xc8\x36\x60\x17\x65\x02\x39\x11\x65\x81\x36\xe6\xba\x33\x05\xac\x4f\x65\xe1\x62\xf8\x16\x4b\x08\x33\x39\x17\xfd\x30\x4a\xa6\x20\x06\x55\x6c\x1c\x90\x03\xea\x98\x0c\x19\x54\xb2\x7f\x3f\xfc\x78\x0d\xd3\xf0\x82\xea\xed\x5d\x71\x33\x5e\xc3\x64\x48\xdf\x30\x50\x22\xb9\x9c\x00\xa2\xcd\x33\x7a\x73\x73\x8b\x03\xa2\xe9\xee\xdd\x70\xc0\x90\x82\x0d\x42\x03\x99\xaa\x4f\x80\xdf\x22\xde\x9e\x53\x5d\x3b\x11\xdb\x72\x04\x47\xe9\x64\x98\xe1\xba\xb8\xea\x21\x96\x3b\xee\x70\xe0\xf4\xfa\x22\xfd\x34\x60\x9f\x29\xea\xf8\x9f\x6a\xaa\xaf\x5f\x4f\xcd\xcd\xaf\x60\x1e\x99\x9e\x3f\x3d\xb5\x31\x99\xfe\x91\x12\x65\xee\x55\x51\xdf\x13\x1b\x7d\x52\x70\x9c\x8c\x31\xc5\x38\xb0\xc6\x91\xca\xed\x9d\x18\x2d\xc9\x21\xce\x9d\x06\x50\xc2\x07\x6b\xa7\xd7\x17\x31\xa7\x6a\x15\x59\xec\x49\x4e\x37\xa4\x83\x38\xee\xbc\x65\x9a\xf5\x5b\x99\xa2\
 x4e\x5a\x3e\xa7\xf5\x1f\x46\x86\x33\xbf\xc4\x5d\xf3\xcd\xd7\x88\x94\x04\xa5\xdb\xf0\xc3\x40\x6e\x6e\xef\xc1\x3d\xea\xd1\xbd\x4f\x13\x77\x70\x2f\xcd\x58\xac\x4c\x51\x47\xf3\xea\x86\x9c\x23\x81\x23\x4d\xc0\xc7\x19\x25\x72\x6b\x37\x7a\x77\x76\x98\xf4\x00\x48\xa2\x22\x1d\x03\x3e\x84\x4a\x01\x38\x77\x4a\xe5\xf4\xfa\xc2\x9b\x4b\xa9\xbf\xc7\xe7\x35\xaa\x26\x52\x7c\xc3\x52\x16\x2d\xdc\xce\x53\x68\xa6\xb8\x7b\x3e\x42\xe3\x33\x9d\x42\xfd\xca\xc1\xf6\x7e\xdb\xd7\x4d\x2d\x09\xaf\xff\x33\x12\xd8\xee\x1c\x5e\x5f\x74\xf3\x01\xf4\xdb\xb5\x33\x38\x6e\xde\xf0\x6e\x9f\xb2\x75\xe5\x77\xc7\xf3\x7b\x97\xed\xb3\x9f\xa6\x37\xe7\xbf\x5f\x4f\x6f\xdf\xcd\x54\xcd\x6f\x4f\x0b\x4c\xaf\x2f\xf4\xcf\x26\xec\x57\xe8\xe3\x53\x81\x85\x7c\x1a\x96\xb7\x77\x28\x1b\x0b\xda\x7c\x4d\xe4\x02\xaa\x78\x61\xba\x01\x2b\xb1\x79\x51\xd6\xfc\xd7\x4c\x0d\xfe\x3e\x15\xc1\xeb\x73\xf9\x55\x4f\x33\x7e\x7b\x2f\x68\x0a\xdd\x08\xa6\xa2\x6b\x2a\x63\xeb\xe3\xb7\xf2\x60\x85\x36\x80\x0a\xc1\x12\xa2\x1b\xcf\x27\xd6\xd9\xe7\x9a\x87\x0d\xea\x98\x
 ca\x1d\xa9\x53\x5b\x8e\x5e\x39\x03\x24\x41\xb6\x28\xd7\x4f\xac\x91\xb9\x17\x32\xe6\x9e\xff\x48\x66\x7b\x56\x5b\xef\xe2\xa1\x2e\xe7\x88\xfb\x8b\x22\x60\x1c\xb1\xfd\xfe\x13\xc9\xe6\x89\x60\x64\xc6\xa5\xf6\x61\x20\x77\x40\x3f\x8e\xdb\x53\x0f\xaa\xfe\x0e\x50\x0f\x09\x30\x56\x65\x6e\xba\x7c\x9d\xfb\x08\x8f\xeb\x67\x95\x74\x57\xb8\xd6\x0b\x79\x42\x17\x6c\xa2\x2d\xdd\x3c\xa8\xb4\x15\x89\x8b\x5c\xb8\x86\xd7\x03\x0a\x08\x17\xa0\xc1\x32\xdd\xc1\x6c\xe1\xd7\x09\x62\x45\x63\x30\x05\x12\x4b\x38\x7e\x15\xa5\x6f\x12\x9e\x73\x76\xea\xdf\xe7\xa2\xbd\xea\xc6\x83\xe8\x7b\x13\x9e\x19\x2a\x1e\x23\x45\x0d\xf5\xb3\x0e\xc2\xa8\x11\xb9\x24\xc6\x66\xd2\xb4\xb0\x43\xf8\xc6\x74\x4d\x9d\x21\x6a\x76\x9a\xba\xef\x70\x01\xa3\x99\x6b\x6e\x8c\x64\xb6\xdb\x48\x7d\xe4\x1a\xf5\xbb\x89\x32\xb1\xe6\xcb\xee\xb8\x6f\x5a\x39\x21\x8e\xe5\x1a\x2a\xbe\x8d\xec\xf8\xfd\xb9\xef\x59\x17\xdf\x51\x21\xfb\xe5\x17\x3a\x85\x04\x2a\x81\xfb\xaf\x38\x34\xd7\x4b\x9a\x53\xaa\xae\xd2\xc4\x72\x3b\xb3\x95\x9d\x19\x72\x53\xcf\x81\xb7\x5f\x31\x9
 f\x3b\xd8\xf4\x27\x67\xf7\xbf\x44\xce\x5b\x23\xda\xcf\x76\x87\xe1\xe3\x7b\x97\x37\xf0\xf1\xbd\x9d\xe5\xa7\xa6\xa9\x1c\x8c\xdb\xef\xf6\x44\x75\x37\xe7\xb5\x93\xa9\x0e\x7c\x9b\x64\xdc\x4e\x06\x2e\xb0\x05\x60\x94\x2d\x7d\x4b\xfa\x18\x56\x7b\xf2\x34\xcf\x31\x6f\xd7\x56\x30\xdf\xf4\x42\xdb\x26\x45\x7b\xc1\x8a\x82\xad\x71\xae\xbe\x2a\x1b\x3e\x51\x05\x7f\xc5\x71\x61\xfe\x78\x70\x37\xe8\x81\xd0\x1d\x26\xf8\x11\xff\x51\x61\x9d\xec\x99\xe1\x52\x5f\xda\x3c\xaf\xa4\x72\x55\x33\x6c\x66\x66\x93\xf4\xae\x9f\xf1\xc3\x39\x6c\xb0\x33\x9f\x60\x08\x92\x77\xd5\x12\xbc\xd5\xca\x48\x30\xa9\xed\x46\xf6\xb2\xf6\xbe\x36\x58\x5f\x44\x43\xc4\x52\xe9\x71\xf0\xeb\xb4\x86\x0b\x8e\xba\xbf\x01\xc1\x1a\xcf\xeb\x56\x9e\x00\x02\x8e\xd6\xf0\xee\xf6\xf6\xba\xf7\x33\xe3\x86\x54\x48\x44\x73\xc4\x9b\xe0\xbd\x39\x5b\xff\x27\x48\x5e\x61\xf8\xb1\xc7\xa1\x60\x7e\xb4\x83\x51\x06\x7f\xc2\x02\x15\x42\xf1\xec\x20\x46\x5e\x10\xf1\x5f\xa6\x74\xd4\x5c\xb8\x3b\x58\x9f\x9c\x28\xfc\x45\x81\xee\x9a\x27\x1c\x09\x2d\x2b\x7d\xe8\x43\xd4\x87
 \x3d\xf5\x63\x02\x13\x38\x52\xaa\xaa\x7f\x39\x5a\xab\x7f\xb4\x1a\x47\x93\xe6\x6d\x9f\xd8\xb9\xef\x19\x15\xf0\x4c\x38\xf6\xab\xb7\xb7\x55\x7b\x0a\x17\x42\xa8\xa9\x6c\x2d\xee\x9b\xc1\xa6\x8e\x5d\x7f\x7e\xb1\x8d\x01\xbf\xa8\xd5\xd5\x9a\xe8\xdd\x1d\x46\x1f\x30\x97\xdd\xeb\x11\x24\xeb\x23\x7b\xe7\xba\xef\xa9\x97\xd7\x5e\x7a\xeb\xbc\x53\xb8\x5d\x62\x78\x3c\x61\x25\xa6\x6b\xfd\x8e\xa2\xb2\xbd\x2f\xa8\xfb\x0c\x6d\xa0\xf9\xd3\xf1\x1c\xea\x49\xcc\x29\x2a\x00\xab\x55\xe0\x29\x7c\xa8\x17\x53\xc6\x11\x69\x50\x8c\x53\xd4\x5f\xaa\x36\x8f\xf2\x39\xf5\x1c\x0d\x9c\xa4\x30\x2a\x49\xce\x32\x1f\x70\xa2\xa2\x11\x80\x56\x05\x1b\xfe\x36\x80\x73\xd1\x64\x9e\x58\x4b\xbb\x30\x17\x39\xf3\x36\x13\x84\x95\xce\x95\xd3\x41\xa0\xbd\x4a\xdb\x4c\xe8\x50\x5a\x8f\xc3\x8e\x55\x7b\x3b\xdb\x1e\xba\xd6\x0f\x24\x24\xba\x20\xf5\x30\xf3\x8c\xa5\x18\x2a\x21\xba\x08\x15\x2f\x9e\x53\xff\x41\xf0\x81\x0b\x31\x3c\x7b\x2d\x3b\x44\xcf\xbf\x09\xdd\x6c\x3c\xfa\x0f\x77\xed\x52\x3d\xe7\x86\xe4\xc8\xed\xa8\x9b\xfa\xe0\xff\x76\xd6\xdc\xbe\
 xed\x7a\xfb\xdb\xf5\xf9\x29\x5c\x33\x21\xf4\x85\x6f\x9d\x27\x0f\x97\x72\x55\x4c\x60\x29\x65\x39\x81\xff\x08\xe5\xb6\x49\xfc\x28\x27\x20\x1e\x5c\x4f\x99\x1f\x5e\x8e\xdd\x15\xaa\xe4\x92\x71\xf2\xc5\x18\xd8\x3d\xde\xec\x3f\x3f\x05\xc7\x27\x27\xa8\xea\xc7\xff\x9d\x1b\x48\x43\xe1\xbc\xb1\xaa\x66\xcf\x8e\x55\x52\xb9\x81\x33\x55\xfe\xd9\x04\x30\x91\x4b\xcc\x75\x39\x95\xc3\xb7\x41\xab\x22\x10\x78\x4a\x00\x8a\xda\x2f\xf8\x6d\xfa\xe1\xbd\x25\xfc\x9d\xbc\x75\x10\xc6\x09\xa5\x21\xd5\xbe\x9d\x2a\x9c\x7e\x61\x58\x21\xa6\x64\x24\x05\xf8\xfd\xb9\xac\xfa\x9c\xa2\xbe\x80\x5e\xb3\xa8\x3f\x82\x39\xe7\x0e\x26\x57\xb0\x14\x53\x49\xe4\x46\x2f\xf6\x27\x5d\x07\x79\xa2\xb7\x1a\xda\xe4\x62\x42\x85\xc4\x28\xd7\x87\xa5\xb7\xe9\xfc\xcd\x2a\xa2\xfd\xc1\x74\x96\xfa\x3a\x39\x13\x35\xa8\x4f\xb6\xad\x90\x7c\x0d\xaf\xda\x8d\x4e\xcf\xde\xd8\x77\xd3\xc8\x39\xce\x36\x6b\x01\xee\xea\x06\x3b\x44\xa1\xed\x76\xd3\x49\xe6\x48\x2c\xdb\x4c\xa6\x3a\x70\x51\x4f\x46\x91\x1b\xef\x91\x38\xf6\x44\x78\x4e\xa8\x14\x4e\x66\x13\x9e\xd2\x
 57\x89\xca\x9c\x55\xce\x37\xcd\x12\x51\xec\xc9\xfc\x8c\x4b\xb5\x6a\xaf\xaf\x4e\x2e\x97\x68\x8e\x25\xc9\x50\x51\x6c\x60\xbe\xe9\xda\xc3\x9b\xfa\x4a\xb4\xf6\x9a\x41\x3d\xe5\xb6\xf7\x25\xad\x88\x7c\x25\xee\x49\x59\x1f\xf4\xc7\x79\xc3\xab\xaf\x57\x73\x9d\x16\xf8\x46\xd2\x87\x14\xdd\xc4\xe6\xd8\x02\xfe\xd5\x6e\xd6\xc3\x9f\x7a\x83\x5e\x99\xed\xbf\x27\xed\x5e\xfd\x44\xe9\xa0\xe7\xe6\xdf\x7f\x3d\xff\xf8\xd3\x77\xa8\xa7\xef\xa3\xea\x7f\xbd\x69\xa3\x87\xce\x4b\x19\x79\xfd\xc2\x77\x81\x21\x63\xdc\x78\x1d\x7a\x7f\xaf\xf3\x32\x88\xb6\x34\x57\x13\x0c\x44\xb3\xaa\x66\xde\x36\x61\x60\x01\x75\x88\xf7\x71\x38\xd3\x56\xf6\x5e\xa5\xe9\x3f\x87\xef\x49\x52\x09\x71\x7a\x83\xbb\x4a\xc7\x7c\xb7\xae\xe2\x6f\x93\x0f\xb2\xfb\xb6\x7a\x74\xfd\x9c\x75\xee\x01\x76\x95\xd2\x4d\x1f\x84\xaf\x55\x6b\xae\xc9\x8d\x91\xb0\xc7\xe2\x13\xb2\xfb\xa6\x50\x6c\xc2\x40\x34\xbb\x12\xfe\xc3\xbf\x7f\xf8\xff\x00\x00\x00\xff\xff\xe1\x75\x4d\x49\x7b\xca\x00\x00")
-
-func wski18nResourcesEn_usAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesEn_usAllJson,
-		"wski18n/resources/en_US.all.json",
-	)
-}
-
-func wski18nResourcesEn_usAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesEn_usAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/en_US.all.json", size: 51835, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesEs_esAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func wski18nResourcesEs_esAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesEs_esAllJson,
-		"wski18n/resources/es_ES.all.json",
-	)
-}
-
-func wski18nResourcesEs_esAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesEs_esAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/es_ES.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesFr_frAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x8a\xe6\x52\x50\xa8\xe6\x52\x50\x50\x50\x50\xca\x4c\x51\xb2\x52\x50\x4a\xaa\x2c\x48\x2c\x2e\x56\x48\x4e\x2d\x2a\xc9\x4c\xcb\x4c\x4e\x2c\x49\x55\x48\xce\x48\x4d\xce\xce\xcc\x4b\x57\xd2\x81\x28\x2c\x29\x4a\xcc\x2b\xce\x49\x2c\xc9\xcc\xcf\x03\xe9\x08\xce\xcf\x4d\x55\x40\x12\x53\xc8\xcc\x53\x70\x2b\x4a\xcd\x4b\xce\x50\xe2\x52\x50\xa8\xe5\x8a\xe5\x02\x04\x00\x00\xff\xff\x45\xa4\xe9\x62\x65\x00\x00\x00")
-
-func wski18nResourcesFr_frAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesFr_frAllJson,
-		"wski18n/resources/fr_FR.all.json",
-	)
-}
-
-func wski18nResourcesFr_frAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesFr_frAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/fr_FR.all.json", size: 101, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesIt_itAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func wski18nResourcesIt_itAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesIt_itAllJson,
-		"wski18n/resources/it_IT.all.json",
-	)
-}
-
-func wski18nResourcesIt_itAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesIt_itAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/it_IT.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesJa_jaAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func wski18nResourcesJa_jaAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesJa_jaAllJson,
-		"wski18n/resources/ja_JA.all.json",
-	)
-}
-
-func wski18nResourcesJa_jaAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesJa_jaAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/ja_JA.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesKo_krAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func wski18nResourcesKo_krAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesKo_krAllJson,
-		"wski18n/resources/ko_KR.all.json",
-	)
-}
-
-func wski18nResourcesKo_krAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesKo_krAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/ko_KR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesPt_brAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func wski18nResourcesPt_brAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesPt_brAllJson,
-		"wski18n/resources/pt_BR.all.json",
-	)
-}
-
-func wski18nResourcesPt_brAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesPt_brAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/pt_BR.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesZh_hansAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func wski18nResourcesZh_hansAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesZh_hansAllJson,
-		"wski18n/resources/zh_Hans.all.json",
-	)
-}
-
-func wski18nResourcesZh_hansAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesZh_hansAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hans.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-var _wski18nResourcesZh_hantAllJson = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x01\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00")
-
-func wski18nResourcesZh_hantAllJsonBytes() ([]byte, error) {
-	return bindataRead(
-		_wski18nResourcesZh_hantAllJson,
-		"wski18n/resources/zh_Hant.all.json",
-	)
-}
-
-func wski18nResourcesZh_hantAllJson() (*asset, error) {
-	bytes, err := wski18nResourcesZh_hantAllJsonBytes()
-	if err != nil {
-		return nil, err
-	}
-
-	info := bindataFileInfo{name: "wski18n/resources/zh_Hant.all.json", size: 0, mode: os.FileMode(420), modTime: time.Unix(1510606284, 0)}
-	a := &asset{bytes: bytes, info: info}
-	return a, nil
-}
-
-// Asset loads and returns the asset for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func Asset(name string) ([]byte, error) {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[cannonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
-		}
-		return a.bytes, nil
-	}
-	return nil, fmt.Errorf("Asset %s not found", name)
-}
-
-// MustAsset is like Asset but panics when Asset would return an error.
-// It simplifies safe initialization of global variables.
-func MustAsset(name string) []byte {
-	a, err := Asset(name)
-	if err != nil {
-		panic("asset: Asset(" + name + "): " + err.Error())
-	}
-
-	return a
-}
-
-// AssetInfo loads and returns the asset info for the given name.
-// It returns an error if the asset could not be found or
-// could not be loaded.
-func AssetInfo(name string) (os.FileInfo, error) {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	if f, ok := _bindata[cannonicalName]; ok {
-		a, err := f()
-		if err != nil {
-			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
-		}
-		return a.info, nil
-	}
-	return nil, fmt.Errorf("AssetInfo %s not found", name)
-}
-
-// AssetNames returns the names of the assets.
-func AssetNames() []string {
-	names := make([]string, 0, len(_bindata))
-	for name := range _bindata {
-		names = append(names, name)
-	}
-	return names
-}
-
-// _bindata is a table, holding each asset generator, mapped to its name.
-var _bindata = map[string]func() (*asset, error){
-	"wski18n/resources/de_DE.all.json":   wski18nResourcesDe_deAllJson,
-	"wski18n/resources/en_US.all.json":   wski18nResourcesEn_usAllJson,
-	"wski18n/resources/es_ES.all.json":   wski18nResourcesEs_esAllJson,
-	"wski18n/resources/fr_FR.all.json":   wski18nResourcesFr_frAllJson,
-	"wski18n/resources/it_IT.all.json":   wski18nResourcesIt_itAllJson,
-	"wski18n/resources/ja_JA.all.json":   wski18nResourcesJa_jaAllJson,
-	"wski18n/resources/ko_KR.all.json":   wski18nResourcesKo_krAllJson,
-	"wski18n/resources/pt_BR.all.json":   wski18nResourcesPt_brAllJson,
-	"wski18n/resources/zh_Hans.all.json": wski18nResourcesZh_hansAllJson,
-	"wski18n/resources/zh_Hant.all.json": wski18nResourcesZh_hantAllJson,
-}
-
-// AssetDir returns the file names below a certain
-// directory embedded in the file by go-bindata.
-// For example if you run go-bindata on data/... and data contains the
-// following hierarchy:
-//     data/
-//       foo.txt
-//       img/
-//         a.png
-//         b.png
-// then AssetDir("data") would return []string{"foo.txt", "img"}
-// AssetDir("data/img") would return []string{"a.png", "b.png"}
-// AssetDir("foo.txt") and AssetDir("notexist") would return an error
-// AssetDir("") will return []string{"data"}.
-func AssetDir(name string) ([]string, error) {
-	node := _bintree
-	if len(name) != 0 {
-		cannonicalName := strings.Replace(name, "\\", "/", -1)
-		pathList := strings.Split(cannonicalName, "/")
-		for _, p := range pathList {
-			node = node.Children[p]
-			if node == nil {
-				return nil, fmt.Errorf("Asset %s not found", name)
-			}
-		}
-	}
-	if node.Func != nil {
-		return nil, fmt.Errorf("Asset %s not found", name)
-	}
-	rv := make([]string, 0, len(node.Children))
-	for childName := range node.Children {
-		rv = append(rv, childName)
-	}
-	return rv, nil
-}
-
-type bintree struct {
-	Func     func() (*asset, error)
-	Children map[string]*bintree
-}
-
-var _bintree = &bintree{nil, map[string]*bintree{
-	"wski18n": {nil, map[string]*bintree{
-		"resources": {nil, map[string]*bintree{
-			"de_DE.all.json":   {wski18nResourcesDe_deAllJson, map[string]*bintree{}},
-			"en_US.all.json":   {wski18nResourcesEn_usAllJson, map[string]*bintree{}},
-			"es_ES.all.json":   {wski18nResourcesEs_esAllJson, map[string]*bintree{}},
-			"fr_FR.all.json":   {wski18nResourcesFr_frAllJson, map[string]*bintree{}},
-			"it_IT.all.json":   {wski18nResourcesIt_itAllJson, map[string]*bintree{}},
-			"ja_JA.all.json":   {wski18nResourcesJa_jaAllJson, map[string]*bintree{}},
-			"ko_KR.all.json":   {wski18nResourcesKo_krAllJson, map[string]*bintree{}},
-			"pt_BR.all.json":   {wski18nResourcesPt_brAllJson, map[string]*bintree{}},
-			"zh_Hans.all.json": {wski18nResourcesZh_hansAllJson, map[string]*bintree{}},
-			"zh_Hant.all.json": {wski18nResourcesZh_hantAllJson, map[string]*bintree{}},
-		}},
-	}},
-}}
-
-// RestoreAsset restores an asset under the given directory
-func RestoreAsset(dir, name string) error {
-	data, err := Asset(name)
-	if err != nil {
-		return err
-	}
-	info, err := AssetInfo(name)
-	if err != nil {
-		return err
-	}
-	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
-	if err != nil {
-		return err
-	}
-	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
-	if err != nil {
-		return err
-	}
-	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-// RestoreAssets restores an asset under the given directory recursively
-func RestoreAssets(dir, name string) error {
-	children, err := AssetDir(name)
-	// File
-	if err != nil {
-		return RestoreAsset(dir, name)
-	}
-	// Dir
-	for _, child := range children {
-		err = RestoreAssets(dir, filepath.Join(name, child))
-		if err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func _filePath(dir, name string) string {
-	cannonicalName := strings.Replace(name, "\\", "/", -1)
-	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
-}
diff --git a/wski18n/resources/en_US.all.json b/wski18n/resources/en_US.all.json
index 27482805..ee7d434b 100644
--- a/wski18n/resources/en_US.all.json
+++ b/wski18n/resources/en_US.all.json
@@ -1558,5 +1558,21 @@
   {
     "id": "Cannot specify both --kind and --docker at the same time.",
     "translation": "Cannot specify both --kind and --docker at the same time."
+  },
+  {
+    "id": "Relative path '{{.path}}' does not include valid path parameters. Each parameter must be enclosed in curly braces '{}'.",
+    "translation": "Relative path '{{.path}}' does not include valid path parameters. Each parameter must be enclosed in curly braces '{}'."
+  },
+  {
+    "id": "Default description for '{{.name}}'",
+    "translation": "Default description for '{{.name}}'"
+  },
+  {
+    "id": "The base path '{{.path}}' cannot have parameters. Only the relative path supports path parameters.",
+    "translation": "The base path '{{.path}}' cannot have parameters. Only the relative path supports path parameters."
+  },
+  {
+    "id": "A response type of 'http' is required when using path parameters.",
+    "translation": "A response type of 'http' is required when using path parameters."
   }
 ]


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services