i18n error parsing

common way to parse localization on errors in actions. This can help generate useful error messages.

it will take an error like `err = {app: {name: "invalid"} }` and generate `err.i18n = [{key: "app.name.invalid"}]`
it also supports 1 variable (not sure how to use more than one) 
`err = {app: {name: "invalid__bad__"} }` and generate `err.i18n = [{key: "app.name.invalid", var: "bad"}]`

For instance, I can have a validation constraint like
```ts
var constraint = {
    id: id,
    name: {
      presence: {message: "^empty"},
      length: {
        minimum: 4,
        maximum: 45,
        tooShort: "^tooShort__%{count}__",
        tooLong: "^tooLong__%{count}__"
      }
    },
  };
```
and a backend route that returns
```ts
callback(new ApplicationError(
  err,
  {
    name: "duplicate"
  }
));
```
then usage would be
```js
var self = this;
    action({
      i18nErrors: {
        keys: ["app", "validation"],
        prefix: "mailinglist::updateMailingList."
      },
      data: {
        id: !isNew ? this.state.id : undefined,
        name: this.state.name,
        description: this.state.description
      }
    }, function(err, res) {
      if(err) {
        console.log(err);
        return self.setState({
          feedback: {
            i18n: err.i18n,
            style: "danger"
          }
        })
      }
      self.setState({
        feedback: {i18n: [{key: "success"}], style: "success"},
        id: isNew ? res.id : self.state.id
      });
    });
```
and a localization file that looks like
```js
  updateMailingList: {
    application: {
      name: {
        duplicate: "This name is already used"
      }
    },
    validation: {
      name: {
        empty: "Name cannot be blank",
        tooShort: "Name must be at least __var__ characters long",
        tooLong: "Name must be at most __var__ characters long"
      }
    }
  }
```