version 0.4.0, rewrote in es6