1.27.7 • Published 9 months ago

@fishertsau/moonlight v1.27.7

Weekly downloads
1
License
ISC
Repository
github
Last release
9 months ago

moonlight

  • 提供JavaScript常用的功能,類似helper或是utility,讓javascript專案使用
  • 可用於Server-side專案,如node.js,或是Client-side專案,如vue,react中
  • 發佈於npm中,使用時當作一個package使用
  • 可用於es6與commonjs中

Main functions

  1. Validator
  2. time
  3. array
  4. hostname
  5. Checker
  6. Utils
  7. MoonUse
  8. Model

Input Validator

  • check the input validity with specified rules
  • only the validated attribute(s) are returned
  • convert data type on validating, e.g '100' to 100 for 'type:number'
  • rules

  • validator:: obj -> obj -> obj

  • examples

       const rules = {
            foo: 'required|type:null', // null
            boo: 'type:bool',  // true, false, 'true', 'false'
            boo: 'type:boolean',  // true, false, 'true', 'false'
    
           // string 
            moo: 'type:string', // string
            moo: 'required|type:emptyString',  // ''
            moo: 'required|type:nonEmptyString',  // non empty string 
            moo: 'required|type:lowerCaseOrNumberString',  // lower case or number string (e.g. 'abc123')
            moo: 'required|type:isNumberString',  // number string  (e.g. '123')
     
            // object 
            boo: 'type:object',  // object
            boo: 'type:emptyObject',  // {}
    
            // same content 
            bar: 'required|same:foo',
    
            // valid values
            loo: 'validValues:[v1,v2,v3]',
    
            aoo: 'type:array', // array
            aoo: 'type:emptyArray', // []
            aoo: 'type:arrayOfString', // ['a','b']
            aoo: 'type:arrayOfInt', // [1,2]
            aoo: 'type:arrayOfNull', // [null, null]
    
            // multiple types 
            soo: 'type:[number,null,nonEmptyString]', // number, null, non empty string
    
           // number & integer 
            foo: 'required|type:number', // number (e.g. 1.2)
            aoo: 'type:int', // integer (e.g. 1)
            aoo: 'type:positiveInt', // > 0
    
            // date & datetime 
            too: 'type:datetime',  // yyyy-mm-dd hh:mm:ss (e.g. '2000-01-01 12:00:00')
            too: 'type:isoDatetime',  // yyyy-mm-ddThh:mm:ss+08:00 (e.g. '2000-01-01T12:00:00+08:00')
            too: 'type:date', // yyyy-mm-dd (e.g. '2000-01-01')
            too: 'type:yearMonthDay', // {year:1, month: 1, day: 1}
    
            // length: same length
            foo: 'sameLength:bar', // same length as bar (e.g. '123' and 'abc')
            foo: 'minLen:3', // min length  (e.g. '123')
            foo: 'maxLen:5', // max length  (e.g. '12345')
    
            // range
            foo: 'range:1,10', // 1 <= foo <= 10 (for int only)
    
            // requiredWhenExists
            foo: 'requiredWhenExists:boo', // required when boo is not empty  (e.g. 'foo' is required when 'boo' is not empty)
            foo: 'requiredIfValueIs:bar:1', // required when bar is 1  (e.g. 'foo' is required when 'bar' is 1)
    
            // requiredIfValueIs
            foo: 'requiredIfValueIs:bar:true', // required when bar is true  (e.g. 'foo' is required when 'bar' is 1)
            foo: 'requiredIfValueIs:bar:10', // required when bar is 10  (e.g. 'foo' is required when 'bar' is 10)
     
            // app types 
            koo: 'type:email', // email
            koo: 'type:hostname', // hostname (e.g. 'www.google.com')
            koo: 'type:hostnameWithPath', // hostname with path (e.g. 'www.google.com/path')
            koo: 'type:lineId', // line id (e.g. 'U1234567890abcdef1234567890abcdef')
            koo: 'type:twTaxId', // Taiwan tax id  (8 digits) (e.g. '12345678')
            koo: 'type:twMobileNo', // Taiwan mobile number (10 digits) (e.g. '0912345678')
            koo: 'type:twLandPhoneNo', // Taiwan land phone number (9 digits) (e.g. '022345678')
            koo: 'type:addressWithDefault', // address with default value (e.g. {city:1, area:1, street:'abc'})
       };
    
      const validatedData = { foo: 123, bar: 123, koo: '2000-01-01', loo: 'invalidValue', moo: '', aoo:'notArray'};
      let result = validator(rules)(validatedData);
      // => { validated: true ,  values:{foo:123, bar:123,koo:'2000-01-01'}}
      // => { validated: false ,
      //      errors: {
      //         foo: ['foo should be a number.'], 
      //         koo: ['koo should be a string.']
      //         loo: ['loo should be in one of the values: v1,v2,v3.']
      //         moo: ['moo should be an non empty string.']
      //         aoo: ['aoo should be in array format.']
      //      }
      //    }

time

  • now :: null -> DateTime

        now();
        //=> current time
  • isoStrToUtcStr:: isoDatetimeString -> utcDatetimeString

        isoStrToUtcStr('1997-07-16T19:20:35+03:00');
        //=> '1997-07-16 16:20:35'
  • isoStrToTaipeiStr :: isoDatetimeString -> taipeiDatetimeString

       isoStrToTaipeiStr('1997-07-16T19:20:35+03:00');  // utc: 1997-07-16T16:20:35
       //=> '1997-07-17 00:20:35'
{
  // base
  Dayjs,
    now,

    // string to object
    toTimeObj,
    fromIsoTimeStrToObj,
    fromTimeStrAtTZ,
    fromTpeTimeStr,

    // datetime string
    utcDatetimeStrNow, // 2000-01-01 12:00:00
    isoStrNow,

    // string to string
    isoStrToUtcStr,    // 2000-01-01T12:00:00.000Z ->  2000-01-01 12:00:00
    utcStrToIsoStr,
    isoStrToTaipeiStr, // 2000-01-01T12:00:00.000Z ->  2000-01-01 20:00:00
    datetimeStrToDateStr, // 2000-01-01 12:00:00 -> 2000-01-01
    isoStrToTpeDateStr, // 2000-01-01T12:00:00.000Z -> 2000-01-01

    // date|datetime string
    dateAtTZ,
    todayStartInTpeStr,
    todayEndInTpeStr,
    todayEndInIsoStr,
    todayInTpeStrDateOnly,

    // time obj
    todayStartInTpe,
    todayEndInTpe,

    // type check
    isIsoFormat,

    // time zone
    TZ,
    TZ_TYPE,

    // comparison
    isBefore,
    isAfter,
    isBetween,
    isSame,

    // duration
    getDuration,

    // status
    getStatusByTimeFrame,
    STATUS_BY_TIME_FRAME,
    REF_TIME_STATUS_TYPE,

    // time manipulation
    minAgoFromNow
}

array

  • shuffle :: array -> array
    • re-order the array items randomly

hostname

  • isValidHostname :: String -> Boolean
    • To validate a give hostname

Checker

  isTrue,
  isEmpty,
  isValidBool,
  isFunction,
  isUndefined,

  // object
  isObject,
  isEmptyObject,

  // string
  isString,
  isNonEmptyString,
  isNumberString,
  isEmptyString,
  isLowerCaseOrNumberString,
  isNumberOrString,
  isNumberOrNumberString,

  // number
  isIntBetween,
  isNumber,
  isValidInteger,
  isPositiveInteger,
  isUnsignedInteger,
  isSameNumOrNumStr,

  // number format
  ifOnlyNumberAndLetter,
  ifHexNumberStr,
  ifDecimalNumberStr,

  // time
  isYMDStr,
  isDatetimeStr,
  isIsoFormat,
  isIsoFormatWithZeroOffset,

  // array
  isArray,
  isEmptyArray,
  isNonEmptyArray,
  isArrayOfString,
  isArrayOfInt,
  isArrayOfArray, // [[], []]
  isArrayOfNumber,
  isArrayOfNull,

  // application
  isValidLineId,
  isValidEmail,
  isValidTwTaxId,
  isValidTwMobileNo,
  isValidTwLandPhoneNo,
  isValidTwNationalId,

  isValidHostname,
  isValidHostnameWithPath,
  • isTrue :: a -> boolean

    • To check if a given value is true
  • isEmpty :: a -> boolean

    • To check is a given value is empty
  • isIntBetween:: int a -> int b -> int c -> boolean

    • To check is a given int or value is between the specified range
  • isNumber:: a -> boolean

    • To check is given value is a number
  • isString:: a -> boolean

    • To check is given value is a string
  • isObject:: a -> boolean

    • To check is given value is an object
    • null and array are excluded
  • isValidEmail:: a -> boolean

    • To check is given value is a valid email
  • isValidBool:: a -> boolean

    • To check is given value is a valid boolean value
  • isFunction:: a -> boolean

    • To check is given value a Function
  • isValidHostname:: a -> boolean

    • To check if a given value a valid hostname
  • isYMDStr:: str a -> boolean

    • To check is given string is in date format
    • valid date format: yyyy-mm-dd (time is not included)
  • isDateTime:: str a -> boolean

    • To check is given string is in datetime format
    • valid datetime format includes: unix time (integer), date+time, UTC
  • isIsoFormat:: a -> boolean

    • To check is given value is in ISO 8601 format
  • isIsoFormatWithZeroOffset:: a -> boolean

    • To check is given value is in ISO 8601 format with zero offset

Utils

  • clearSpace:: string -> string

    • To clear or remove space in a string
  • trim

    • To trim the string(s) in object properties and values
    • To trim string(s) in list
    • Can trim string(s) in nested objects or nested array

         trim({
            'p1  ': 'foo ',
            p2: ['  abc', ' def  '],
            p3: { p3_1: ['p31 '] },
            p4: { p4_1: ['p41 ', ' p42'], 'p4_2': {} },
            p5: 100,
           });
         //=> 
          {
            p1: 'foo',
            p2: ['abc', 'def'],
            p3: { p3_1: ['p31'] },
            p4: { p4_1: ['p41', 'p42'], 'p4_2' : {} },
            p5: 100,
          }
  • extractByPath

    • To extract a value from a structured collection object

    • Object structure

         {
            k1: {
              k1a: {}
              k1b: {}
            },
            k2: {
              k2a: {}
              k2b: {}
            }
         }
    • example:

      extractByPath(['info', 'age'])({'person1':{info:{age:10}}, 'person2':{info:{age:20}}});
      //=>  {'person1':10, 'person2':20}
  • getDirty

    • To get the values in new object which differ from that in the original object
    • The function is auto-curry

    • example:

     oriObj = {a:1, b:3}
     newObj = {a:1, b:5, c:7}
    
     getDirty(oriObj)(newObj);
      //=> {b:5, c:7}
  • renameKey

    • To change a key name

    • example:

     oriObj = {foo:1}
    
     renameKey('foo','bar')(oriObj);
      //=> {bar:1}
  • createEventEmitter

    • To create an event emitter

    • example:

    const em = createEventEmitter(); 
    
    // register event handler
    em.on('someEvent', someHandler); 
    
    // remove event handler 
    // A. remove specific handler
    em.remove('someEvent', someHandler); 
    // B. remove all handlers
    em.remove('someEvent'); 
    
    // send out event
    em.emit('someEvent', payload); 
  • pluckObjProp

    • To pluck a nested obj prop

    • example:

      // Functor f => k -> {k:v} -> {k:v}
      const obj = {
                    prop1: { foo: 123, bar: 'abc' },
                    prop2: { foo: 999, bar: 'abc' }
            }
    
      pluckObjProp('foo')(obj)
    
      //=> {prop1: 123, prop2: 999}
  • clean

    • To remove obj props if value is undefined/null/emptyString
    • Applicable to nested object
       clean({
          foo: 123,
          bar: undefined,
          koo: {
            k1: 'abc',
            k2: undefined,
          },
          poo: null,
          moo: '',
      })
       //=> { foo: 123, koo: { k1:'abc'} }
  • cleanNilUndefined

    • To remove obj props if value is undefined/null
    • Applicable to nested object
       clean({
          foo: 123,
          bar: undefined,
          koo: {
            k1: 'abc',
            k2: undefined,
          },
          poo: null,
          moo: '',
      })
       //=> { foo: 123, koo: { k1:'abc'} moo: '' }
  • hasValue

    • To check if an object has specified value
    • Applicable to simple object
       hasValue(123, { foo: 123 })
       //=> true
    
       hasValue('abc', { foo: 123 })
       //=> false 
  • rmArrSquareInReqParamsKey

       harmArrSquareInReqParamsKeys(
          {
            from: 0,
            'ids[]': [ 'abc1705548556993', 'abc1705558802725']
          });
    
       //=> 
          {
             from: 0,
             'ids': [ 'abc1705548556993' , 'abc1705558802725']
           };
  • getObjectDifference

        const obj1 = {
     a: 1,
     b: {
       c: 2,
       d: {
         e: 3,
       },
     },
     f: {
       g: 5,
     },
    };

const obj2 = { a: 1, b: { c: 3, d: { e: 4, }, }, };

getObjectDifference(obj1, obj2);

//=> { { 'b.c' : 2, 3, 'b.d.e'; : 3, 4, f; : { g: 5 }, undefined; }

- parseObj :: obj -> QueryString
   - convert an object to query string
   - example:
     ```javascript
       parsrStr({a:'foo',b:'bar'})
       //=> a=foo&b=bar
     ```

- parseStr :: QueryString -> obj
   - convert a query string to an object
   - example:
     ```javascript
       parsrObj('a=foo&b=bar')
       //=> {a:'foo',b:'bar'}
     ``` 

- convertKeyValue :: [a] -> obj (a: 'str=str')
   - convert a key-value array to an object
 ```javascript
    convertKeyValue(['foo=bar', 'fiz=fuz']);
    //=> {foo:'bar', fiz:'fuz'}
  • convertObjToArr :: obj -> a

    • convert an object to a key-value array
       convertKeyValue({ foo: 'bar', fiz: 'fuz' });
       //=> ['foo=bar', 'fiz=fuz']
  • snakeToCamel :: str -> str

    • convert a snake-string to camel-case string
       snakeToCamel('abc_def_ghi')
       //=> 'abcDefGhi'
  • objKeyToCamel :: obj -> obj

    • convert all keys in an object from snake to camel string
    • nested object is supported
       objKeyToCamel({this_is_key: val})
       //=> {thisIsKey: val}
  • camelToSnake :: str -> str

    • convert a camel-case string to snake-case string
       camelToSnake('abcDefGhi')
       //=> 'abc_def_ghi'
  • objKeyToSnake :: obj -> obj

    • convert all keys in an object from camel to snake-case string
    • nested object is supported
       objKeyToSnake({ thisIsKey: 'someVal' })
       //=> { this_is_key: 'someVal' }
  • parseCookie :: string -> obj

    • parse a cookie string to an object
       parseCookie('foo=bar ; equation=E%3Dmc%5E2;   asd=');
       //=> { foo: 'bar', equation: 'E=mc^2', asd: '' }
  • serializeCookie :: obj -> string

    • serialize an object to cookie string
       serializeCookie({ foo: 'bar', equation: 'E=mc^2', asd: '' });
       //=> 'foo=bar;equation=E%3Dmc%5E2;asd='

MoonUse

  • useRetry

  • useLock

  • useWait

    • To make an action execution wait for a given time before execution
      useWait(1000, action);
      //=> wait for 1000ms, and then run action 
    - ```
  • useRedisCache

    • To get value from redis cache, otherwise get the value and cache it
      const foo = await useCache('someCacheKey', getter, {keyLife:100});
      //=> keyLife: key有效時間 (in second)
    - ```

Model

  • basicTypes
  YES_NO_TYPE,
  NULLABLE_YES_NO_TYPE,

  STRING_TYPE,
  NON_EMPTY_STRING_TYPE,
  NUMBER_OR_STRING_TYPE,
  NULLABLE_STRING_TYPE,

  INTEGER_TYPE,
  UNSIGNED_INTEGER_TYPE,
  NULLABLE_INTEGER_TYPE,
  POSITIVE_INTEGER_TYPE,
  NULLABLE_UNSIGNED_INTEGER_TYPE,

  BIG_INTEGER_TYPE,
  NULLABLE_BIG_INTEGER_TYPE,

  UNSIGNED_TINY_INTEGER_TYPE,

  NUMBER_TYPE,

  ARRAY_TYPE,
  ARRAY_OF_INT_TYPE,
  NULLABLE_ARRAY_TYPE,

  OBJECT_TYPE,
  NULLABLE_OBJECT_TYPE,

  FUNCTION_TYPE,
  NULLABLE_FUNCTION_TYPE,
- example
```
     Model.basicTypes.STRING_TYPE;
```
  • datetimeTypes
  DATE_TYPE,
  NULLABLE_DATE_TYPE,

  DATETIME_TYPE,
  NULLABLE_DATETIME_TYPE,

  ISO_DATETIME_TYPE,
  NULLABLE_ISO_DATETIME_TYPE,
  • appTypes
  EMAIL_TYPE,
  NULLABLE_EMAIL_TYPE,
  EMPTY_STRING_OR_EMAIL_TYPE,

  LINE_ID_TYPE,
  EMPTY_STRING_OR_LINE_ID_TYPE,

  CITY_TYPE,
  CITY_AREA_TYPE,

  MEDIA_TYPE,

  TW_TAX_ID_TYPE,
  NULLABLE_TW_TAX_ID_TYPE,
  TW_MOBILE_NO_TYPE,

  HOSTNAME_TYPE,
  NULLABLE_HOSTNAME_TYPE,
  EMPTY_STRING_OR_HOSTNAME_TYPE,
  • appTypes.CITY_TYPE (台灣城市)

    • 結構: 整數 (城市編號)

    • properties:

      • validator
      • cityList (台灣城市清單)
    • 會檢查縣市是否為合法值

  • appTypes.CITY_AREA_TYPE (台灣城市與區域)

    • 結構: {cityId: 1, areaId: 1}

    • properties:

      • validator
      • cityList (台灣城市清單)
      • areaList (台灣區域清單,含城市編號與區域號碼)
    • 會檢查縣市與區域的對應,是否為合法值

    • 城市與區域未定: {cityId:0, areaId:0}
    • 使用範例
       const someModelDef = {
         location: {
           type: CITY_AREA_TYPE,
         }
       }
  • cityList內容

  const cityList = [
   { id: 0, name: '未定義' },
   { id: 1, name: '台北市' },
   ...
  ];
  • areaList內容
  const areaList = [
    { id: 0, cityId: 0, name: '未定義', zip: 0 },
    { id: 1, cityId: 1, name: '中正區', zip: 100 },
    ...
  ];
1.27.7

9 months ago

1.27.6

9 months ago

1.26.33

10 months ago

1.26.32

10 months ago

1.26.34

10 months ago

1.27.2

10 months ago

1.27.3

10 months ago

1.27.1

10 months ago

1.27.4

10 months ago

1.27.5

10 months ago

1.26.29

10 months ago

1.26.31

10 months ago

1.26.30

10 months ago

1.26.28

10 months ago

1.26.27

10 months ago

1.26.26

10 months ago

1.26.25

10 months ago

1.26.22

10 months ago

1.26.21

10 months ago

1.26.24

10 months ago

1.26.23

10 months ago

1.26.20

10 months ago

1.26.19

10 months ago

1.26.18

10 months ago

1.26.17

10 months ago

1.26.16

10 months ago

1.26.15

11 months ago

1.26.14

11 months ago

1.26.13

11 months ago

1.26.11

11 months ago

1.26.10

11 months ago

1.26.12

11 months ago

1.26.9

11 months ago

1.25.19

1 year ago

1.25.17

1 year ago

1.25.18

1 year ago

1.25.15

1 year ago

1.25.16

1 year ago

1.25.13

1 year ago

1.25.14

1 year ago

1.25.8

1 year ago

1.25.9

1 year ago

1.25.6

1 year ago

1.25.7

1 year ago

1.25.11

1 year ago

1.25.12

1 year ago

1.25.10

1 year ago

1.25.28

1 year ago

1.25.29

1 year ago

1.25.26

1 year ago

1.25.27

1 year ago

1.25.24

1 year ago

1.25.25

1 year ago

1.25.22

1 year ago

1.25.23

1 year ago

1.25.20

1 year ago

1.25.21

1 year ago

1.26.3

12 months ago

1.26.4

12 months ago

1.26.1

12 months ago

1.25.35

12 months ago

1.26.2

12 months ago

1.26.7

11 months ago

1.26.8

11 months ago

1.26.5

12 months ago

1.26.6

11 months ago

1.25.33

12 months ago

1.25.34

12 months ago

1.25.31

12 months ago

1.25.32

12 months ago

1.25.30

12 months ago

1.25.4

1 year ago

1.25.5

1 year ago

1.25.3

1 year ago

1.24.2

1 year ago

1.24.1

1 year ago

1.23.1

1 year ago

1.22.7

1 year ago

1.22.8

1 year ago

1.22.9

1 year ago

1.22.4

1 year ago

1.22.5

1 year ago

1.22.6

1 year ago

1.22.3

1 year ago

1.22.2

1 year ago

1.22.1

1 year ago

1.21.1

1 year ago

1.21.4

1 year ago

1.21.2

1 year ago

1.21.3

1 year ago

1.20.1

1 year ago

1.20.2

1 year ago

1.19.12

1 year ago

1.19.11

1 year ago

1.19.10

1 year ago

1.19.8

1 year ago

1.19.7

1 year ago

1.19.9

1 year ago

1.19.6

1 year ago

1.19.5

1 year ago

1.19.4

1 year ago

1.19.3

1 year ago

1.19.2

1 year ago

1.19.1

1 year ago

1.18.14

1 year ago

1.18.13

1 year ago

1.18.9

1 year ago

1.18.12

1 year ago

1.18.11

1 year ago

1.18.10

1 year ago

1.18.8

1 year ago

1.18.7

1 year ago

1.18.5

1 year ago

1.18.4

1 year ago

1.18.6

1 year ago

1.18.3

1 year ago

1.18.1

1 year ago

1.18.2

1 year ago

1.17.2

1 year ago

1.17.4

1 year ago

1.17.3

1 year ago

1.16.18

1 year ago

1.16.17

1 year ago

1.17.1

1 year ago

1.16.14

1 year ago

1.16.13

1 year ago

1.16.12

1 year ago

1.16.16

1 year ago

1.16.15

1 year ago

1.16.10

1 year ago

1.16.11

1 year ago

1.16.9

1 year ago

1.16.8

1 year ago

1.16.7

1 year ago

1.15.6

1 year ago

1.15.5

1 year ago

1.15.4

1 year ago

1.15.3

1 year ago

1.15.2

1 year ago

1.15.1

1 year ago

1.14.4

1 year ago

1.14.3

1 year ago

1.14.2

1 year ago

1.14.1

1 year ago

1.13.24

1 year ago

1.13.23

1 year ago

1.13.22

1 year ago

1.13.21

1 year ago

1.13.20

1 year ago

1.13.19

1 year ago

1.13.18

1 year ago

1.13.17

1 year ago

1.13.16

1 year ago

1.13.15

1 year ago

1.13.14

1 year ago

1.13.13

1 year ago

1.13.6

2 years ago

1.13.9

2 years ago

1.13.11

2 years ago

1.13.8

2 years ago

1.13.10

2 years ago

1.13.7

2 years ago

1.13.12

2 years ago

1.13.5

2 years ago

1.13.4

2 years ago

1.13.3

2 years ago

1.12.16

2 years ago

1.12.15

2 years ago

1.12.18

2 years ago

1.12.17

2 years ago

1.13.2

2 years ago

1.13.1

2 years ago

1.12.14

2 years ago

1.10.2

2 years ago

1.9.10

2 years ago

1.11.2

2 years ago

1.11.1

2 years ago

1.12.3

2 years ago

1.12.2

2 years ago

1.12.1

2 years ago

1.12.7

2 years ago

1.12.6

2 years ago

1.12.5

2 years ago

1.12.4

2 years ago

1.8.2

2 years ago

1.8.1

2 years ago

1.12.9

2 years ago

1.12.8

2 years ago

1.12.10

2 years ago

1.9.9

2 years ago

1.9.8

2 years ago

1.9.7

2 years ago

1.9.6

2 years ago

1.12.12

2 years ago

1.9.5

2 years ago

1.12.11

2 years ago

1.9.4

2 years ago

1.9.3

2 years ago

1.12.13

2 years ago

1.7.1

2 years ago

1.10.10

2 years ago

1.8.3

2 years ago

1.6.13

2 years ago

1.6.15

2 years ago

1.6.14

2 years ago

1.6.17

2 years ago

1.6.16

2 years ago

1.6.19

2 years ago

1.6.18

2 years ago

1.6.12

2 years ago

1.6.9

2 years ago

1.6.8

2 years ago

1.6.7

2 years ago

1.6.6

2 years ago

1.6.11

2 years ago

1.6.10

2 years ago

1.6.5

2 years ago

1.6.4

2 years ago

1.6.3

2 years ago

1.6.2

2 years ago

1.5.5

2 years ago

1.5.4

2 years ago

1.5.3

2 years ago

1.5.2

2 years ago

1.5.1

2 years ago

1.5.0

2 years ago

1.4.6

2 years ago

1.4.5

2 years ago

1.5.9

2 years ago

1.5.8

2 years ago

1.5.7

2 years ago

1.5.6

2 years ago

1.5.10

2 years ago

1.5.12

2 years ago

1.5.11

2 years ago

1.5.14

2 years ago

1.5.13

2 years ago

1.5.16

2 years ago

1.5.15

2 years ago

1.5.18

2 years ago

1.5.17

2 years ago

1.5.19

2 years ago

1.5.21

2 years ago

1.5.20

2 years ago

1.4.9

2 years ago

1.5.23

2 years ago

1.4.8

2 years ago

1.5.22

2 years ago

1.4.7

2 years ago

1.4.4

2 years ago

1.4.3

2 years ago

1.4.2

2 years ago

1.4.1

2 years ago

1.4.0

2 years ago

1.3.4

2 years ago

1.3.3

2 years ago

1.3.2

2 years ago

1.3.1

2 years ago

1.3.0

2 years ago

1.2.8

3 years ago

1.2.7

3 years ago

1.2.12

3 years ago

1.2.13

3 years ago

1.2.10

3 years ago

1.2.11

3 years ago

1.2.14

3 years ago

1.2.15

3 years ago

1.2.9

3 years ago

1.2.6

3 years ago

1.2.5

3 years ago

1.2.4

3 years ago

1.2.3

3 years ago

1.2.2

3 years ago

1.1.19

3 years ago

1.1.18

3 years ago

1.1.17

3 years ago

1.1.16

3 years ago

1.1.15

3 years ago

1.1.12

3 years ago

1.1.11

3 years ago

1.1.10

3 years ago

1.1.14

3 years ago

1.1.13

3 years ago

1.1.9

4 years ago

1.1.8

4 years ago

1.1.7

4 years ago

1.1.6

4 years ago

1.1.5

4 years ago

1.1.4

4 years ago

1.1.3

4 years ago

1.1.2

4 years ago

1.1.1

4 years ago

1.0.44

4 years ago

1.0.43

4 years ago

1.0.47

4 years ago

1.0.46

4 years ago

1.0.45

4 years ago

1.0.19

4 years ago

1.0.18

4 years ago

1.0.39

4 years ago

1.0.17

4 years ago

1.0.38

4 years ago

1.0.16

4 years ago

1.0.40

4 years ago

1.0.22

4 years ago

1.0.21

4 years ago

1.0.42

4 years ago

1.0.20

4 years ago

1.0.41

4 years ago

1.0.26

4 years ago

1.0.25

4 years ago

1.0.24

4 years ago

1.0.23

4 years ago

1.0.29

4 years ago

1.0.28

4 years ago

1.0.33

4 years ago

1.0.32

4 years ago

1.0.31

4 years ago

1.0.30

4 years ago

1.0.37

4 years ago

1.0.15

4 years ago

1.0.36

4 years ago

1.0.35

4 years ago

1.0.34

4 years ago

1.0.11

4 years ago

1.0.10

4 years ago

1.0.14

4 years ago

1.0.13

4 years ago

1.0.12

4 years ago

1.0.9

4 years ago

1.0.7

5 years ago

1.0.6

5 years ago

1.0.5

5 years ago

1.0.4

5 years ago

1.0.3

5 years ago

1.0.2

5 years ago

1.0.1

5 years ago

1.0.0

5 years ago