func (rg Range) Intersect(r Range) Range {
	if rg.Max.X > r.Max.X {
		rg.Max.X = r.Max.X
	}
	if rg.Max.Y > r.Max.Y {
		rg.Max.Y = r.Max.Y
	}
	if rg.Min.X < r.Min.X {
		rg.Min.X = r.Min.X
	}
	if rg.Min.Y < r.Min.Y {
		rg.Min.Y = r.Min.Y
	}
	if rg.Min.X >= rg.Max.X || rg.Min.Y >= rg.Max.Y {
		return Range{}
	}
	return rg
}
Intersect returns the largest range contained both by rg and r. If the two
ranges do not overlap, the zero range will be returned.
package gruid
import (
	"fmt"
	"strings"
	"time"
)
type AttrMask uint32
const AttrsDefault AttrMask = 0
type Color uint32
const ColorDefault Color = 0
type Cell struct {
	Rune  rune   
	Style Style  
}
func (c Cell) WithRune(r rune) Cell {
	c.Rune = r
	return c
}
func (c Cell) WithStyle(st Style) Cell {
	c.Style = st
	return c
}
type Style struct {
	Fg    Color     
	Bg    Color     
	Attrs AttrMask  
}
func (st Style) WithFg(cl Color) Style {
	st.Fg = cl
	return st
}
func (st Style) WithBg(cl Color) Style {
	st.Bg = cl
	return st
}
func (st Style) WithAttrs(attrs AttrMask) Style {
	st.Attrs = attrs
	return st
}
type Point struct {
	X int
	Y int
}
func (p Point) String() string {
	return fmt.Sprintf("(%d,%d)", p.X, p.Y)
}
func (p Point) Shift(x, y int) Point {
	return Point{X: p.X + x, Y: p.Y + y}
}
func (p Point) Add(q Point) Point {
	return Point{X: p.X + q.X, Y: p.Y + q.Y}
}
func (p Point) Sub(q Point) Point {
	return Point{X: p.X - q.X, Y: p.Y - q.Y}
}
func (p Point) In(rg Range) bool {
	return p.X >= rg.Min.X && p.X < rg.Max.X && p.Y >= rg.Min.Y && p.Y < rg.Max.Y
}
func (p Point) Mul(k int) Point {
	return Point{X: p.X * k, Y: p.Y * k}
}
func (p Point) Div(k int) Point {
	return Point{X: p.X / k, Y: p.Y / k}
}
type Range struct {
	Min, Max Point
}
func NewRange(x0, y0, x1, y1 int) Range {
	if x1 < x0 {
		x0, x1 = x1, x0
	}
	if y1 < y0 {
		y0, y1 = y1, y0
	}
	return Range{Min: Point{X: x0, Y: y0}, Max: Point{X: x1, Y: y1}}
}
func (rg Range) String() string {
	return fmt.Sprintf("%s-%s", rg.Min, rg.Max)
}
func (rg Range) Size() Point {
	return rg.Max.Sub(rg.Min)
}
func (rg Range) Shift(x0, y0, x1, y1 int) Range {
	rg = Range{Min: rg.Min.Shift(x0, y0), Max: rg.Max.Shift(x1, y1)}
	if rg.Empty() {
		return Range{}
	}
	return rg
}
func (rg Range) Line(y int) Range {
	if rg.Min.Shift(0, y).In(rg) {
		rg.Min.Y = rg.Min.Y + y
		rg.Max.Y = rg.Min.Y + 1
	} else {
		rg = Range{}
	}
	return rg
}
func (rg Range) Lines(y0, y1 int) Range {
	nrg := rg
	nrg.Min.Y = rg.Min.Y + y0
	nrg.Max.Y = rg.Min.Y + y1
	return rg.Intersect(nrg)
}
func (rg Range) Column(x int) Range {
	if rg.Min.Shift(x, 0).In(rg) {
		rg.Min.X = rg.Min.X + x
		rg.Max.X = rg.Min.X + 1
	} else {
		rg = Range{}
	}
	return rg
}
func (rg Range) Columns(x0, x1 int) Range {
	nrg := rg
	nrg.Min.X = rg.Min.X + x0
	nrg.Max.X = rg.Min.X + x1
	return rg.Intersect(nrg)
}
func (rg Range) Empty() bool {
	return rg.Min.X >= rg.Max.X || rg.Min.Y >= rg.Max.Y
}
func (rg Range) Eq(r Range) bool {
	return rg == r || rg.Empty() && r.Empty()
}
func (rg Range) Sub(p Point) Range {
	rg.Max = rg.Max.Sub(p)
	rg.Min = rg.Min.Sub(p)
	return rg
}
func (rg Range) Add(p Point) Range {
	rg.Max = rg.Max.Add(p)
	rg.Min = rg.Min.Add(p)
	return rg
}
func (rg Range) RelMsg(msg Msg) Msg {
	if msg, ok := msg.(MsgMouse); ok {
		msg.P = msg.P.Sub(rg.Min)
		return msg
	}
	return msg
}