| 
					
				 | 
			
			
				@@ -27,13 +27,14 @@ Ok, Width = 16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 Width 16  (at pos 1, update time/sec increment) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 Black on Cyan 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type WOPR struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ElapsedPanel   Panel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	Elapsed        time.Duration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	Elapsed        time.Time 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	ElapsedD       time.Duration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	RemainingPanel Panel 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	Remaining      time.Duration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	Remaining      time.Time 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	RemainingD     time.Duration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Color          string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Index          int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	Ticker         *time.Ticker 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -42,7 +43,7 @@ type WOPR struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // Initialize, Set X, Y on Panels, Animate() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 // Initialize, and create panels 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-func (w *WOPR) Init(elapsed time.Duration, remaining time.Duration, color string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+func (w *WOPR) Init(elapsed time.Time, remaining time.Time, color string) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if color == "" { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		color = ColorText("BLACK ON CYAN") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -57,7 +58,7 @@ func (w *WOPR) Init(elapsed time.Duration, remaining time.Duration, color string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var ehour Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ehour.UpdateF = func() string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var hours int = int(w.Elapsed.Hours()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var hours int = int(w.ElapsedD.Hours()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return fmt.Sprintf("     %02d HRS     ", hours%100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ehour.Text = ehour.UpdateF() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -65,8 +66,8 @@ func (w *WOPR) Init(elapsed time.Duration, remaining time.Duration, color string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var eminsec Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	eminsec.UpdateF = func() string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var mins int = int(w.Elapsed.Minutes()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var secs int = int(w.Elapsed.Seconds()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var mins int = int(w.ElapsedD.Minutes()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var secs int = int(w.ElapsedD.Seconds()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return fmt.Sprintf(" %02d MIN  %02d SEC ", mins, secs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	eminsec.Text = eminsec.UpdateF() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -96,7 +97,7 @@ func (w *WOPR) Init(elapsed time.Duration, remaining time.Duration, color string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var rhour Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	rhour.UpdateF = func() string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var hours int = int(w.Remaining.Hours()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var hours int = int(w.RemainingD.Hours()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return fmt.Sprintf("     %02d HRS     ", hours%100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	rhour.Text = rhour.UpdateF() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -104,8 +105,8 @@ func (w *WOPR) Init(elapsed time.Duration, remaining time.Duration, color string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	var rminsec Line = Line{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	rminsec.UpdateF = func() string { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var mins int = int(w.Remaining.Minutes()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		var secs int = int(w.Remaining.Seconds()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var mins int = int(w.RemainingD.Minutes()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		var secs int = int(w.RemainingD.Seconds()) % 60 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return fmt.Sprintf(" %02d MIN  %02d SEC ", mins, secs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	rminsec.Text = rminsec.UpdateF() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -131,21 +132,55 @@ func (w *WOPR) Init(elapsed time.Duration, remaining time.Duration, color string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (w *WOPR) Inc() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	w.Index++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if w.Index == 16 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		w.Remaining = time.Duration(w.Remaining.Seconds()-1) * time.Second 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		w.Elapsed = time.Duration(w.Elapsed.Seconds()+1) * time.Second 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		w.Index = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.ElapsedPanel.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.RemainingPanel.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.RemainingD = time.Duration(w.RemainingD.Seconds()-1) * time.Second 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.ElapsedD = time.Duration(w.ElapsedD.Seconds()+1) * time.Second 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 func (w *WOPR) Animate(d *Door) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-	w.Ticker = time.NewTicker(time.Microsecond * time.Duration(62500)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// til := time.Now().UnixNano() % int64(time.Second) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// w.Index = int((til / int64(time.Microsecond)) / 62500) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// either put the sync sleep in the go routine, or sleep and sync Index. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// time.Sleep(time.Duration(int64(time.Second) - til)) // time.Now().UnixMilli()%1000) * time.Millisecond) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// time.Second / 16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// w.Ticker = time.NewTicker(time.Microsecond * time.Duration(62500)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// w.Index = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Convert time.Time to time.Duration 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// This gives us consistency when resuming. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	w.ElapsedD = time.Since(w.Elapsed) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	w.RemainingD = time.Until(w.Remaining) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	go func(d *Door) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// til := time.Now().UnixNano() % int64(time.Second) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		sec16 := int64(time.Second) / 16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// tilms := til % sec16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.Index = 0 // int(til / sec16) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// log.Printf("til: %d, sec: %d, w.Index: %d\n", til, sec16, w.Index) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// either put the sync sleep in the go routine, or sleep and sync Index. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// time.Sleep(time.Second - time.Duration(til)) // sec16 - (til % sec16))) //int64(time.Second) - til)) // time.Now().UnixMilli()%1000) * time.Millisecond) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		// time.Second / 16 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		w.Ticker = time.NewTicker(time.Duration(sec16)) // time.Microsecond * time.Duration(62500)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		var output string 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		for range w.Ticker.C { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			w.ElapsedPanel.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			w.RemainingPanel.Update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			output = SavePos + w.ElapsedPanel.Output() + w.RemainingPanel.Output() + RestorePos 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			if !d.Disconnect() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				d.Write(output) 
			 |