Fully end to end encrypted anonymous chat program. Server only stores public key lookup for users and the encrypted messages. No credentials are transfered to the server, but kept in local browser storage. This allows 100% safe chatting. https://safechat.ch
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

278 lines
4.4 KiB

/*!
* Stylus - HSLA
* Copyright (c) Automattic <developer.wordpress.com>
* MIT Licensed
*/
/**
* Module dependencies.
*/
var Node = require('./node')
, nodes = require('./');
/**
* Initialize a new `HSLA` with the given h,s,l,a component values.
*
* @param {Number} h
* @param {Number} s
* @param {Number} l
* @param {Number} a
* @api public
*/
var HSLA = exports = module.exports = function HSLA(h,s,l,a){
Node.call(this);
this.h = clampDegrees(h);
this.s = clampPercentage(s);
this.l = clampPercentage(l);
this.a = clampAlpha(a);
this.hsla = this;
};
/**
* Inherit from `Node.prototype`.
*/
HSLA.prototype.__proto__ = Node.prototype;
/**
* Return hsla(n,n,n,n).
*
* @return {String}
* @api public
*/
HSLA.prototype.toString = function(){
return 'hsla('
+ this.h + ','
+ this.s.toFixed(0) + '%,'
+ this.l.toFixed(0) + '%,'
+ this.a + ')';
};
/**
* Return a clone of this node.
*
* @return {Node}
* @api public
*/
HSLA.prototype.clone = function(parent){
var clone = new HSLA(
this.h
, this.s
, this.l
, this.a);
clone.lineno = this.lineno;
clone.column = this.column;
clone.filename = this.filename;
return clone;
};
/**
* Return a JSON representation of this node.
*
* @return {Object}
* @api public
*/
HSLA.prototype.toJSON = function(){
return {
__type: 'HSLA',
h: this.h,
s: this.s,
l: this.l,
a: this.a,
lineno: this.lineno,
column: this.column,
filename: this.filename
};
};
/**
* Return rgba `RGBA` representation.
*
* @return {RGBA}
* @api public
*/
HSLA.prototype.__defineGetter__('rgba', function(){
return nodes.RGBA.fromHSLA(this);
});
/**
* Return hash.
*
* @return {String}
* @api public
*/
HSLA.prototype.__defineGetter__('hash', function(){
return this.rgba.toString();
});
/**
* Add h,s,l to the current component values.
*
* @param {Number} h
* @param {Number} s
* @param {Number} l
* @return {HSLA} new node
* @api public
*/
HSLA.prototype.add = function(h,s,l){
return new HSLA(
this.h + h
, this.s + s
, this.l + l
, this.a);
};
/**
* Subtract h,s,l from the current component values.
*
* @param {Number} h
* @param {Number} s
* @param {Number} l
* @return {HSLA} new node
* @api public
*/
HSLA.prototype.sub = function(h,s,l){
return this.add(-h, -s, -l);
};
/**
* Operate on `right` with the given `op`.
*
* @param {String} op
* @param {Node} right
* @return {Node}
* @api public
*/
HSLA.prototype.operate = function(op, right){
switch (op) {
case '==':
case '!=':
case '<=':
case '>=':
case '<':
case '>':
case 'is a':
case '||':
case '&&':
return this.rgba.operate(op, right);
default:
return this.rgba.operate(op, right).hsla;
}
};
/**
* Return `HSLA` representation of the given `color`.
*
* @param {RGBA} color
* @return {HSLA}
* @api public
*/
exports.fromRGBA = function(rgba){
var r = rgba.r / 255
, g = rgba.g / 255
, b = rgba.b / 255
, a = rgba.a;
var min = Math.min(r,g,b)
, max = Math.max(r,g,b)
, l = (max + min) / 2
, d = max - min
, h, s;
switch (max) {
case min: h = 0; break;
case r: h = 60 * (g-b) / d; break;
case g: h = 60 * (b-r) / d + 120; break;
case b: h = 60 * (r-g) / d + 240; break;
}
if (max == min) {
s = 0;
} else if (l < .5) {
s = d / (2 * l);
} else {
s = d / (2 - 2 * l);
}
h %= 360;
s *= 100;
l *= 100;
return new HSLA(h,s,l,a);
};
/**
* Adjust lightness by `percent`.
*
* @param {Number} percent
* @return {HSLA} for chaining
* @api public
*/
HSLA.prototype.adjustLightness = function(percent){
this.l = clampPercentage(this.l + this.l * (percent / 100));
return this;
};
/**
* Adjust hue by `deg`.
*
* @param {Number} deg
* @return {HSLA} for chaining
* @api public
*/
HSLA.prototype.adjustHue = function(deg){
this.h = clampDegrees(this.h + deg);
return this;
};
/**
* Clamp degree `n` >= 0 and <= 360.
*
* @param {Number} n
* @return {Number}
* @api private
*/
function clampDegrees(n) {
n = n % 360;
return n >= 0 ? n : 360 + n;
}
/**
* Clamp percentage `n` >= 0 and <= 100.
*
* @param {Number} n
* @return {Number}
* @api private
*/
function clampPercentage(n) {
return Math.max(0, Math.min(n, 100));
}
/**
* Clamp alpha `n` >= 0 and <= 1.
*
* @param {Number} n
* @return {Number}
* @api private
*/
function clampAlpha(n) {
return Math.max(0, Math.min(n, 1));
}