//Store Class { class Store{ #reducer; #state; #cbs = [] constructor(reducer){ this.#reducer=reducer this.#state= this.#reducer(undefined, {}) } get state(){ return this.#state } getState(){ return this.#state } subscribe(cb){ (this.#cbs.push(cb), () => this.#cbs = this.#cbs.filter(c => c !== cb)) } dispatch(action){ const newState = this.#reducer(this.#state, action) if (newState !== this.#state){ this.#state = newState for (let cb of this.#cbs) cb() } } } } class StoreThunk extends Store{ dispatch(action) { if (typeof action === 'function') { return action(this.dispatch.bind(this), this.state) } super.dispatch(action); } } //Password Class { class Password{ constructor(parent, open){ let input = document.createElement('input') let checkBox = document.createElement('input') checkBox.type = 'checkbox' checkBox.onchange =()=>this.open(checkBox.checked) parent.append(input, checkBox) } set value(value){ this.input.value = value } set open(open){ this.input.type = open ?'text':'password' } get value(){ this.input.value } get open(){ this.input.type } } let p = new Password(document.body, true) p.onChange = data => console.log(data) p.onOpenChange = open => console.log(open) p.value('qwerty') console.log(p.value()) p.open(false) console.log(p.open()) } class RGB{ #r #g #b get r(){ return this.#r } get g(){ return this.#g } get b(){ return this.#b } get rgb(){ return `rgb(${this.#r},${this.#g},${this.#b})` } get hex(){ return "#" + ((1 << 24) + (this.#r << 16) + (this.#g << 8) + this.#b).toString(16).slice(1) } set r(value){ if(typeof value === 'number' && value<=255 && value>=0){ return this.#r=value }else{throw new RangeError(value)} } set g(value){ if(typeof value === 'number' && value<=255 && value>=0){ return this.#g=value }else{throw new RangeError(value)} } set b(value){ if(typeof value === 'number' && value<=255 && value>=0){ return this.#b=value }else{throw new RangeError(value)} } set rgb(rgb){ var matchColors = /rgb\((\d{1,3}), (\d{1,3}), (\d{1,3})\)/; var match = matchColors.exec(rgb); if (match !== null) { this.#r = match[1] this.#g = match[2] this.#b = match[3] }else{throw new RangeError(rgb)} } set hex(hex){ var match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); if (match !== null) { this.#r = parseInt(match[1], 16) this.#g = parseInt(match[2], 16) this.#b = parseInt(match[3], 16) }else{throw new SyntaxError(hex)} } } class RGBA extends RGB{ #a get a(){ return this.#a } set a(value){ if(typeof value === 'number' && value<=1 && value>=0){ return this.#a=value }else{throw new RangeError(value)} } set hex(hex){ if(hex.length>7){ var match = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); if (match !== null) { this.r = parseInt(match[1], 16) this.g = parseInt(match[2], 16) this.b = parseInt(match[3], 16) this.#a= parseInt(match[4], 16)/255 this.#a= +this.#a.toFixed(2) }else{throw new SyntaxError(hex)} }else{return super.hex=hex} } get hex(){ debugger let transparency=((this.#a * 255) | 1 << 8).toString(16).slice(1) if (transparency.length == 1) transparency = '0' + transparency; return super.hex+transparency } set rgba(rgba){ debugger var matchColors = /^rgba\((\d{1,3}), *(\d{1,3}), *(\d{1,3})(?:, *(\d*\.?\d+))?\)$/; var match = matchColors.exec(rgba); if (match !== null) { this.r = Number(match[1]) this.g = Number(match[2]) this.b = Number(match[3]) this.#a = Number(match[4]) }else{throw new RangeError(rgba)} } get rgba(){ return `rgba(${this.r},${this.g},${this.b},${this.#a})` } set color(value){ try{ this.hex=value }catch(e){} try{ this.rgba=value }catch(e){} try{ this.rgb=value }catch(e){} } }