<commit_before>const chalk   = require('chalk');
const client  = require('./client.js');
const log     = console.log;
var wfs       = [];
var projects  = [];
var members   = [];
var wf        = { states: [] };

const listStories = async (program) => {
    [ wfs, members, projects ] = await Promise.all([
        client.listWorkflows(),
        client.listMembers(),
        client.listProjects()
    ]);
    wf = wfs[0];    // TODO: this is always getting the default workflow
    let regexProject = new RegExp(program.project, 'i');
    const filteredProjects = projects
        .filter(p => {
            return !!(p.id + p.name).match(regexProject);
        });
    var stories = await Promise.all(filteredProjects.map(fetchStories));
    return stories.map(filterStories(program, filteredProjects))
        .reduce((a, b) => {
            return a.concat(b);
        }, []);
};
const fetchStories = async (project) => {
    return client.listStories(project.id);
};
const filterStories = (program, projects) => { return (stories, index) => {
    const project = projects[index];
    let created_at = false;
    if (program.created)
        created_at = parseDateComparator(program.created);
    let updated_at = false;
    if (program.updated)
        updated_at = parseDateComparator(program.updated);
    let regexLabel = new RegExp(program.label, 'i');
    let regexState = new RegExp(program.state, 'i');
    let regexOwner = new RegExp(program.owner, 'i');
    let regexText = new RegExp(program.text, 'i');
    let regexType = new RegExp(program.type, 'i');
    const filtered = stories.map(story => {
        story.project = project;
        story.state = wf.states
            .filter(s => s.id === story.workflow_state_id)[0];
        story.owners = members.filter(m => {
            return story.owner_ids.indexOf(m.id) > -1;
        });
        return story;
    }).filter(s => {
        if (!program.archived && s.archived) {
            return false;
        }
        if (!(s.labels
            .map(l => `${l.id},${l.name}`).join(',') + '')
            .match(regexLabel)) {
            return false;
        }
        if (!(s.workflow_state_id + ' ' + (s.state || {}).name)
            .match(regexState)) {
            return false;
        }
        if (program.owner) {
            const owned = s.owners.filter(o => {
                return !!`${o.profile.name} ${o.profile.mention_name}`
                    .match(regexOwner);
            }).length > 0;
            if (!owned) return false;
        }
        if (!s.name.match(regexText)) {
            return false;
        }
        if (!s.story_type.match(regexType)) {
            return false;
        }
        if (created_at && !created_at(s.created_at)) {
            return false;
        }
        if (updated_at && !updated_at(s.updated_at)) {
            return false;
        }
        return true;
    });
    return filtered;
};};

const printStory = (program) => { return (story) => {
    const defaultFormat = `#%I %t
    \tType:   \t%y/%e
    \tLabels: \t%l
    \tProject:\t%p
    \tOwners: \t%o
    \tState:  \t%s
    \tURL:    \t%u
    \tCreated:\t%c\tUpdated: %u
    \tArchived:\t%a
    `;
    const format = program.format || defaultFormat;
    const labels = story.labels.map(l => {
        return chalk.bold(`#${l.id}`) + ` ${l.name}`;
    });
    const owners = story.owners.map(o => {
        return `${o.profile.name} (` + chalk.bold(`${o.profile.mention_name}` + ')');
    });
    log(format
        .replace(/%I/, chalk.blue.bold(`${story.id}`))
        .replace(/%t/, chalk.blue(`${story.name}`))
        .replace(/%d/, story.description || '')
        .replace(/%y/, story.story_type)
        .replace(/%e/, story.estimate || '_')
        .replace(/%l/, labels.join(', ') || '_')
        .replace(/%p/, chalk.bold(`#${story.project.id}`) + ` ${story.project.name}`)
        .replace(/%o/, owners.join(', ') || '_')
        .replace(/%s/, chalk.bold(`#${story.workflow_state_id} `) + story.state.name)
        .replace(/%u/, `https://app.clubhouse.io/story/${story.id}`)
        .replace(/%c/, story.created_at)
        .replace(/%u/, story.updated_at != story.created_at ? story.updated_at : '_')
        .replace(/%a/, story.archived)
    );
    return story;
};};

const parseDateComparator = (arg) => {
    const match = arg.match(/[0-9].*/) || { index: 0, '0': { length: 30 } };
    const parsedDate = new Date(arg.slice(match.index));
    const comparator = arg.slice(0, match.index);
    return (date) => {
        switch(comparator) {
        case '<':
            return new Date(date) < parsedDate;
        case '>':
            return new Date(date) > parsedDate;
        case '=':
        default:
            return new Date(date.slice(0, match[0].length)).getTime()
                == parsedDate.getTime();
        }
    };
};

module.exports = {
    listStories,
    printStory,
};
<commit_msg>chg:dev: Change story id formatting key<commit_after>const chalk   = require('chalk');
const client  = require('./client.js');
const log     = console.log;
var wfs       = [];
var projects  = [];
var members   = [];
var wf        = { states: [] };

const listStories = async (program) => {
    [ wfs, members, projects ] = await Promise.all([
        client.listWorkflows(),
        client.listMembers(),
        client.listProjects()
    ]);
    wf = wfs[0];    // TODO: this is always getting the default workflow
    let regexProject = new RegExp(program.project, 'i');
    const filteredProjects = projects
        .filter(p => {
            return !!(p.id + p.name).match(regexProject);
        });
    var stories = await Promise.all(filteredProjects.map(fetchStories));
    return stories.map(filterStories(program, filteredProjects))
        .reduce((a, b) => {
            return a.concat(b);
        }, []);
};
const fetchStories = async (project) => {
    return client.listStories(project.id);
};
const filterStories = (program, projects) => { return (stories, index) => {
    const project = projects[index];
    let created_at = false;
    if (program.created)
        created_at = parseDateComparator(program.created);
    let updated_at = false;
    if (program.updated)
        updated_at = parseDateComparator(program.updated);
    let regexLabel = new RegExp(program.label, 'i');
    let regexState = new RegExp(program.state, 'i');
    let regexOwner = new RegExp(program.owner, 'i');
    let regexText = new RegExp(program.text, 'i');
    let regexType = new RegExp(program.type, 'i');
    const filtered = stories.map(story => {
        story.project = project;
        story.state = wf.states
            .filter(s => s.id === story.workflow_state_id)[0];
        story.owners = members.filter(m => {
            return story.owner_ids.indexOf(m.id) > -1;
        });
        return story;
    }).filter(s => {
        if (!program.archived && s.archived) {
            return false;
        }
        if (!(s.labels
            .map(l => `${l.id},${l.name}`).join(',') + '')
            .match(regexLabel)) {
            return false;
        }
        if (!(s.workflow_state_id + ' ' + (s.state || {}).name)
            .match(regexState)) {
            return false;
        }
        if (program.owner) {
            const owned = s.owners.filter(o => {
                return !!`${o.profile.name} ${o.profile.mention_name}`
                    .match(regexOwner);
            }).length > 0;
            if (!owned) return false;
        }
        if (!s.name.match(regexText)) {
            return false;
        }
        if (!s.story_type.match(regexType)) {
            return false;
        }
        if (created_at && !created_at(s.created_at)) {
            return false;
        }
        if (updated_at && !updated_at(s.updated_at)) {
            return false;
        }
        return true;
    });
    return filtered;
};};

const printStory = (program) => { return (story) => {
    const defaultFormat = `#%i %t
    \tType:   \t%y/%e
    \tLabels: \t%l
    \tProject:\t%p
    \tOwners: \t%o
    \tState:  \t%s
    \tURL:    \t%u
    \tCreated:\t%c\tUpdated: %u
    \tArchived:\t%a
    `;
    const format = program.format || defaultFormat;
    const labels = story.labels.map(l => {
        return chalk.bold(`#${l.id}`) + ` ${l.name}`;
    });
    const owners = story.owners.map(o => {
        return `${o.profile.name} (` + chalk.bold(`${o.profile.mention_name}` + ')');
    });
    log(format
        .replace(/%i/, chalk.blue.bold(`${story.id}`))
        .replace(/%t/, chalk.blue(`${story.name}`))
        .replace(/%d/, story.description || '')
        .replace(/%y/, story.story_type)
        .replace(/%e/, story.estimate || '_')
        .replace(/%l/, labels.join(', ') || '_')
        .replace(/%p/, chalk.bold(`#${story.project.id}`) + ` ${story.project.name}`)
        .replace(/%o/, owners.join(', ') || '_')
        .replace(/%s/, chalk.bold(`#${story.workflow_state_id} `) + story.state.name)
        .replace(/%u/, `https://app.clubhouse.io/story/${story.id}`)
        .replace(/%c/, story.created_at)
        .replace(/%u/, story.updated_at != story.created_at ? story.updated_at : '_')
        .replace(/%a/, story.archived)
    );
    return story;
};};

const parseDateComparator = (arg) => {
    const match = arg.match(/[0-9].*/) || { index: 0, '0': { length: 30 } };
    const parsedDate = new Date(arg.slice(match.index));
    const comparator = arg.slice(0, match.index);
    return (date) => {
        switch(comparator) {
        case '<':
            return new Date(date) < parsedDate;
        case '>':
            return new Date(date) > parsedDate;
        case '=':
        default:
            return new Date(date.slice(0, match[0].length)).getTime()
                == parsedDate.getTime();
        }
    };
};

module.exports = {
    listStories,
    printStory,
};
<|endoftext|>


<commit_before>Utils_Calendar = {
day_href:null,
page_type:null,
go_to_day:function(date) {
	eval(Utils_Calendar.day_href.replace('__DATE__',date));
},
add_events_f:null,
add_events:function(css) {
	var loaded = false;
	for(var i=0; i<document.styleSheets.length; i++) {
		try {
			typeof(document.styleSheets[i].cssRules);
		} catch(err) {
			continue;
		}
		var v = document.styleSheets[i].href;
		if(typeof(v)=='string' && v.indexOf(css)!=-1) {
			loaded = true;
		}
	}
	if (!loaded) {
		setTimeout(Utils_Calendar.add_events.bind(Utils_Calendar,css),100);
	} else {
		Utils_Calendar.add_events_f();
	}
},
add_event:function(dest_id,ev_id,draggable,duration,max_cut) {
	var dest = $(dest_id);
	var ev = $('utils_calendar_event:'+ev_id);
	if(!ev) {
		return;
	}
	if(!dest) {
		ev.hide();
		return;
	}

	ev.setAttribute('last_cell',dest_id);
	if(Utils_Calendar.page_type=='month') {
		dest.appendChild(ev);
		ev.show();
	} else {
		ev.setAttribute('duration',duration);
		ev.setAttribute('max_cut',max_cut);
		ev.style.position = 'absolute';
//		ev.style.overflow = 'hidden';

		Utils_Calendar.reload_events.push(ev.id);
/*		Utils_Calendar.init_reload_event_tag();
		Utils_Calendar.add_event_tag(dest,ev);
		Utils_Calendar.flush_reload_event_tag();*/
	}

	if(draggable)
		new Draggable(ev, {
			handle: 'handle',
			revert: true,
			quiet: true
		});
},
reload_events:null,
remove_event_tag:function(prev_node,ev) {
	var duration = ev.getAttribute('duration');
	var cell = prev_node;
	var prev_ch;
	var reload = new Array();
	do {
		if(cell.hasAttribute('events_children')) {
			prev_ch = cell.getAttribute('events_children').evalJSON().without(ev.id);
			if(prev_ch.length==0) {
				cell.removeAttribute('events_children');
			} else {
				reload = reload.concat(prev_ch);
				cell.setAttribute('events_children',prev_ch.toJSON());
			}
		}

		if(cell.hasAttribute('join_rows')) {
			duration -= cell.getAttribute('join_rows');
			cell = $(cell.getAttribute('next_row'));
		} else
			duration = 0;
	} while(duration>0);

	Utils_Calendar.reload_event_tag(reload);
},
init_reload_event_tag:function() {
	Utils_Calendar.reload_events = new Array();
},
reload_event_tag:function(reload) {
	reload.each(function(id) {
		if(Utils_Calendar.reload_events.indexOf(id)>=0) return;
		var element = $(id);
		Utils_Calendar.reload_events.push(id);
		Utils_Calendar.remove_event_tag($(element.getAttribute('last_cell')),element);
	});
},
flush_reload_event_tag:function() {
	Utils_Calendar.reload_events = Utils_Calendar.reload_events.sortBy(function(id) {
		var element = $(id);
		var cell = element.getAttribute('last_cell');
		var dur = element.getAttribute('duration');
		return parseInt(cell.substr(7))-parseInt(dur);
	});
	Utils_Calendar.reload_events.each(function(id) {
		var element = $(id);
		Utils_Calendar.add_event_tag($(element.getAttribute('last_cell')),element);
	});
	delete(Utils_Calendar.reload_events);
},
add_event_tag:function(dest,ev) {
	var ch;
	var offset = 0;
	var duration = ev.getAttribute('duration');
	var h=0;
	var cell = dest;
	var reload = new Array(ev.id);
	do {
		if(cell.hasAttribute('events_children')) {
			ch = cell.getAttribute('events_children').evalJSON();
			reload = reload.concat(ch);
		} else {
			ch = new Array();
		}
		if(offset<ch.length) offset = ch.length;
		if(ch.indexOf(ev.id)<0) ch.push(ev.id);
		cell.setAttribute('events_children',ch.toJSON());

		if(cell.hasAttribute('join_rows')) {
			max_cut = parseInt(ev.getAttribute('max_cut'));
			cut = parseInt(cell.getAttribute('join_rows'));
			if (cut>1 && max_cut>0 && max_cut<cut) cut = max_cut;
			duration -= cut;
			cell = $(cell.getAttribute('next_row'));
		} else
			duration = 0;
		h++;
	} while(duration>0);
	ev.style.height = (h * dest.getHeight() - 2)+'px';

	var ev_w = ev.getWidth();
	var offset_step = ev_w/5;

	if(offset_step*offset+ev_w>dest.getWidth()) {
		var err_evs;
		if(dest.hasAttribute("too_many_events")){
			err_evs = dest.getAttribute("too_many_events").evalJSON();
		} else {
			var b = document.createElement('a');
			var date = dest.id.substr(7);
			b.id = 'tooManyEventsCell_'+date;
			var i = date.indexOf('_');
			if(i>0) date = date.substr(0,i);
			b.href = 'javascript:Utils_Calendar.go_to_day("'+date+'")';
			b.innerHTML = 'too many events - please see daily view';
			b.style.position = 'absolute';
			b.style.backgroundColor='red';
//			b.setOpacity(0.6);
			b.style.zIndex=20;
			ev.parentNode.appendChild(b);
			b.clonePosition(dest);
			err_evs = new Array();
		}
		err_evs.push(ev.id);
		dest.setAttribute("too_many_events",err_evs.toJSON());
		ev.style.display='none';
	} else {
		if(dest.hasAttribute("too_many_events")) {
			var err_evs = dest.getAttribute("too_many_events").evalJSON();
			dest.removeAttribute("too_many_events");
			var date = dest.id.substr(7);
			var err = $('tooManyEventsCell_'+date);
			err.parentNode.removeChild(err);
			err_evs.each(function(id) {
				$(id).style.display='block';
			});
		}
		ev.style.zIndex=5+offset;
		ev.clonePosition(dest, {setHeight: false, setWidth: false, offsetLeft: (offset_step*offset)});
	}
	ev.setAttribute('last_cell',dest.id);
	ev.show();

	Utils_Calendar.reload_event_tag(reload);
},
ids:null,
join_rows:function(ids_in) {
	var ids = ids_in.evalJSON();
	ids.each(function(x) {
		var y = $('UCcell_'+x[0]);
		y.setAttribute('join_rows',x[1]);
		y.setAttribute('next_row','UCcell_'+x[2]);
	});
},
activate_dnd:function(ids_in,new_ev,mpath,ecid) {
//	alert('act');
	Utils_Calendar.ids = ids_in.evalJSON();
	Utils_Calendar.ids.each(function(id) {
		var cell_id = 'UCcell_'+id;
		var f = '';
		if(typeof id=='string' && id.indexOf('_')>=0) {
			var kkk = id.indexOf('_');
			f = new_ev.replace('__TIME__',id.substr(0,kkk));
			f = f.replace('__TIMELESS__',id.substr(kkk+1));
		} else {
			f = new_ev.replace('__TIME__',id);
			f = f.replace('__TIMELESS__','0');
		}
		Droppables.add(cell_id, {
			accept: 'utils_calendar_event',
			onDrop: function(element,droppable,ev) {
				if(droppable.id==element.getAttribute('last_cell')) return;
				Epesi.updateIndicatorText("Moving event");
				Epesi.procOn++;
				Epesi.updateIndicator();
				new Ajax.Request('modules/Utils/Calendar/update.php',{
					method:'post',
					parameters:{
						ev_id: element.id.substr(21),
						cell_id: droppable.id.substr(7),
						path: mpath,
						cid: ecid,
						page_type: Utils_Calendar.page_type
					},
					onComplete: function(t) {
						var reject=false;
						eval(t.responseText);
						if(!reject) {
							if(Utils_Calendar.page_type=='month') {
								droppable.appendChild(element);
                                element.setAttribute('last_cell',droppable.id);
							} else {
								Utils_Calendar.init_reload_event_tag();
								Utils_Calendar.reload_event_tag(new Array(element.id));
								//Utils_Calendar.remove_event_tag($(element.getAttribute('last_cell')),element);
								//Utils_Calendar.add_event_tag(droppable,element);
								element.setAttribute('last_cell',droppable.id);
								Utils_Calendar.remove_event_tag(droppable,element);
								setTimeout(Utils_Calendar.flush_reload_event_tag,300);
								//Utils_Calendar.flush_reload_event_tag();
                                element.setAttribute('max_cut',0);
							}

							new Draggable(element, {
								handle: 'handle',
								revert: true
							});
						}
						Epesi.procOn--;
						Epesi.updateIndicator();
					},
					onException: function(t,e) {
						throw(e);
					},
					onFailure: function(t) {
						alert('Failure ('+t.status+')');
						Epesi.text(t.responseText,'error_box','p');
					}
				});
			}
		});
		Event.observe(cell_id,'dblclick',function(e){eval(f)});
		Event.observe(cell_id,'touchend',function(e){
		    var now = new Date().getTime();
		    var lastTouch = $(this).readAttribute('lastTouch') || 0;
		    var delta = now-lastTouch;
		    $(this).writeAttribute('lastTouch',now);
		    if(delta<500)
    		    eval(f);
		});
	});

	//activate trash
	Droppables.add('UCtrash', {
		accept: 'utils_calendar_event',
		onDrop: function(element,droppable,ev) {
			element.hide();
//			droppable.appendChild(element);
			setTimeout('Utils_Calendar.delete_event(\''+element.id+'\', \''+mpath+'\', \''+ecid+'\')',1);
		}
	});
},
delete_event:function(eid,mpath,ecid) {
	if(!confirm('Delete this event?')) {
		$(eid).show();
		return;
	}
	Epesi.updateIndicatorText("Deleting event");
	Epesi.procOn++;
	Epesi.updateIndicator();
	new Ajax.Request('modules/Utils/Calendar/update.php',{
			method:'post',
			parameters:{
				ev_id: eid.substr(21),
				cell_id: 'trash',
				path: mpath,
				cid: ecid
			},
			onComplete: function(t) {
				var reject=false;
				eval(t.responseText);
				var element = $(eid);
				if(reject) element.show();
				else {
					if(Utils_Calendar.page_type!='month') {
						Utils_Calendar.init_reload_event_tag();
						Utils_Calendar.remove_event_tag($(element.getAttribute('last_cell')),element);
						Utils_Calendar.flush_reload_event_tag();
					}
				}
				Epesi.procOn--;
				Epesi.updateIndicator();
			},
			onException: function(t,e) {
				throw(e);
			},
			onFailure: function(t) {
				alert('Failure ('+t.status+')');
				Epesi.text(t.responseText,'error_box','p');
			}
	});
},
destroy:function() {
	if(Utils_Calendar.ids==null) return;
//	alert('destroy');

	delete(Droppables.drops);
	Droppables.drops = [];
	Utils_Calendar.ids.each(function(id) {
//		Droppables.remove('UCcell_'+id[0]);
		var cell = $('UCcell_'+id);
		if(cell) cell.removeAttribute('events_children');
	});
	delete(Utils_Calendar.ids);
	Utils_Calendar.ids=null;

//	Droppables.remove('UCtrash');
}
};
document.observe('e:loading', Utils_Calendar.destroy);
<commit_msg>Calendar - JS bug fix<commit_after>Utils_Calendar = {
day_href:null,
page_type:null,
go_to_day:function(date) {
	eval(Utils_Calendar.day_href.replace('__DATE__',date));
},
add_events_f:null,
add_events:function(css) {
	var loaded = false;
	for(var i=0; i<document.styleSheets.length; i++) {
		try {
			typeof(document.styleSheets[i].cssRules);
		} catch(err) {
			continue;
		}
		var v = document.styleSheets[i].href;
		if(typeof(v)=='string' && v.indexOf(css)!=-1) {
			loaded = true;
		}
	}
	if (!loaded) {
		setTimeout(Utils_Calendar.add_events.bind(Utils_Calendar,css),100);
	} else {
		Utils_Calendar.add_events_f();
	}
},
add_event:function(dest_id,ev_id,draggable,duration,max_cut) {
	var dest = $(dest_id);
	var ev = $('utils_calendar_event:'+ev_id);
	if(!ev) {
		return;
	}
	if(!dest) {
		ev.hide();
		return;
	}

	ev.setAttribute('last_cell',dest_id);
	if(Utils_Calendar.page_type=='month') {
		dest.appendChild(ev);
		ev.show();
	} else {
		ev.setAttribute('duration',duration);
		ev.setAttribute('max_cut',max_cut);
		ev.style.position = 'absolute';
//		ev.style.overflow = 'hidden';

		Utils_Calendar.reload_events.push(ev.id);
/*		Utils_Calendar.init_reload_event_tag();
		Utils_Calendar.add_event_tag(dest,ev);
		Utils_Calendar.flush_reload_event_tag();*/
	}

	if(draggable)
		new Draggable(ev, {
			handle: 'handle',
			revert: true,
			quiet: true
		});
},
reload_events:null,
remove_event_tag:function(prev_node,ev) {
	var duration = ev.getAttribute('duration');
	var cell = prev_node;
	var prev_ch;
	var reload = new Array();
	do {
		if(cell.hasAttribute('events_children')) {
			prev_ch = cell.getAttribute('events_children').evalJSON().without(ev.id);
			if(prev_ch.length==0) {
				cell.removeAttribute('events_children');
			} else {
				reload = reload.concat(prev_ch);
				cell.setAttribute('events_children',prev_ch.toJSON());
			}
		}

		if(cell.hasAttribute('join_rows')) {
			duration -= cell.getAttribute('join_rows');
			cell = $(cell.getAttribute('next_row'));
		} else
			duration = 0;
	} while(duration>0);

	Utils_Calendar.reload_event_tag(reload);
},
init_reload_event_tag:function() {
	Utils_Calendar.reload_events = new Array();
},
reload_event_tag:function(reload) {
	reload.each(function(id) {
		if(Utils_Calendar.reload_events.indexOf(id)>=0) return;
		var element = $(id);
		Utils_Calendar.reload_events.push(id);
		Utils_Calendar.remove_event_tag($(element.getAttribute('last_cell')),element);
	});
},
flush_reload_event_tag:function() {
	Utils_Calendar.reload_events = Utils_Calendar.reload_events.sortBy(function(id) {
		var element = $(id);
		var cell = element.getAttribute('last_cell');
		var dur = element.getAttribute('duration');
		return parseInt(cell.substr(7))-parseInt(dur);
	});
	Utils_Calendar.reload_events.each(function(id) {
		var element = $(id);
		Utils_Calendar.add_event_tag($(element.getAttribute('last_cell')),element);
	});
	delete(Utils_Calendar.reload_events);
},
add_event_tag:function(dest,ev) {
	var ch;
	var offset = 0;
	var duration = ev.getAttribute('duration');
	var h=0;
	var cell = dest;
	var reload = new Array(ev.id);
	do {
		if(cell.hasAttribute('events_children')) {
			ch = cell.getAttribute('events_children').evalJSON();
			reload = reload.concat(ch);
		} else {
			ch = new Array();
		}
		if(offset<ch.length) offset = ch.length;
		if(ch.indexOf(ev.id)<0) ch.push(ev.id);
		if(cell.hasAttribute('events_children'))
			cell.setAttribute('events_children',ch.toJSON());

		if(cell.hasAttribute('join_rows')) {
			max_cut = parseInt(ev.getAttribute('max_cut'));
			cut = parseInt(cell.getAttribute('join_rows'));
			if (cut>1 && max_cut>0 && max_cut<cut) cut = max_cut;
			duration -= cut;
			cell = $(cell.getAttribute('next_row'));
		} else
			duration = 0;
		h++;
	} while(duration>0);
	ev.style.height = (h * dest.getHeight() - 2)+'px';

	var ev_w = ev.getWidth();
	var offset_step = ev_w/5;

	if(offset_step*offset+ev_w>dest.getWidth()) {
		var err_evs;
		if(dest.hasAttribute("too_many_events")){
			err_evs = dest.getAttribute("too_many_events").evalJSON();
		} else {
			var b = document.createElement('a');
			var date = dest.id.substr(7);
			b.id = 'tooManyEventsCell_'+date;
			var i = date.indexOf('_');
			if(i>0) date = date.substr(0,i);
			b.href = 'javascript:Utils_Calendar.go_to_day("'+date+'")';
			b.innerHTML = 'too many events - please see daily view';
			b.style.position = 'absolute';
			b.style.backgroundColor='red';
//			b.setOpacity(0.6);
			b.style.zIndex=20;
			ev.parentNode.appendChild(b);
			b.clonePosition(dest);
			err_evs = new Array();
		}
		err_evs.push(ev.id);
		dest.setAttribute("too_many_events",err_evs.toJSON());
		ev.style.display='none';
	} else {
		if(dest.hasAttribute("too_many_events")) {
			var err_evs = dest.getAttribute("too_many_events").evalJSON();
			dest.removeAttribute("too_many_events");
			var date = dest.id.substr(7);
			var err = $('tooManyEventsCell_'+date);
			err.parentNode.removeChild(err);
			err_evs.each(function(id) {
				$(id).style.display='block';
			});
		}
		ev.style.zIndex=5+offset;
		ev.clonePosition(dest, {setHeight: false, setWidth: false, offsetLeft: (offset_step*offset)});
	}
	ev.setAttribute('last_cell',dest.id);
	ev.show();

	Utils_Calendar.reload_event_tag(reload);
},
ids:null,
join_rows:function(ids_in) {
	var ids = ids_in.evalJSON();
	ids.each(function(x) {
		var y = $('UCcell_'+x[0]);
		y.setAttribute('join_rows',x[1]);
		y.setAttribute('next_row','UCcell_'+x[2]);
	});
},
activate_dnd:function(ids_in,new_ev,mpath,ecid) {
//	alert('act');
	Utils_Calendar.ids = ids_in.evalJSON();
	Utils_Calendar.ids.each(function(id) {
		var cell_id = 'UCcell_'+id;
		var f = '';
		if(typeof id=='string' && id.indexOf('_')>=0) {
			var kkk = id.indexOf('_');
			f = new_ev.replace('__TIME__',id.substr(0,kkk));
			f = f.replace('__TIMELESS__',id.substr(kkk+1));
		} else {
			f = new_ev.replace('__TIME__',id);
			f = f.replace('__TIMELESS__','0');
		}
		Droppables.add(cell_id, {
			accept: 'utils_calendar_event',
			onDrop: function(element,droppable,ev) {
				if(droppable.id==element.getAttribute('last_cell')) return;
				Epesi.updateIndicatorText("Moving event");
				Epesi.procOn++;
				Epesi.updateIndicator();
				new Ajax.Request('modules/Utils/Calendar/update.php',{
					method:'post',
					parameters:{
						ev_id: element.id.substr(21),
						cell_id: droppable.id.substr(7),
						path: mpath,
						cid: ecid,
						page_type: Utils_Calendar.page_type
					},
					onComplete: function(t) {
						var reject=false;
						eval(t.responseText);
						if(!reject) {
							if(Utils_Calendar.page_type=='month') {
								droppable.appendChild(element);
                                element.setAttribute('last_cell',droppable.id);
							} else {
								Utils_Calendar.init_reload_event_tag();
								Utils_Calendar.reload_event_tag(new Array(element.id));
								//Utils_Calendar.remove_event_tag($(element.getAttribute('last_cell')),element);
								//Utils_Calendar.add_event_tag(droppable,element);
								element.setAttribute('last_cell',droppable.id);
								Utils_Calendar.remove_event_tag(droppable,element);
								setTimeout(Utils_Calendar.flush_reload_event_tag,300);
								//Utils_Calendar.flush_reload_event_tag();
                                element.setAttribute('max_cut',0);
							}

							new Draggable(element, {
								handle: 'handle',
								revert: true
							});
						}
						Epesi.procOn--;
						Epesi.updateIndicator();
					},
					onException: function(t,e) {
						throw(e);
					},
					onFailure: function(t) {
						alert('Failure ('+t.status+')');
						Epesi.text(t.responseText,'error_box','p');
					}
				});
			}
		});
		Event.observe(cell_id,'dblclick',function(e){eval(f)});
		Event.observe(cell_id,'touchend',function(e){
		    var now = new Date().getTime();
		    var lastTouch = $(this).readAttribute('lastTouch') || 0;
		    var delta = now-lastTouch;
		    $(this).writeAttribute('lastTouch',now);
		    if(delta<500)
    		    eval(f);
		});
	});

	//activate trash
	Droppables.add('UCtrash', {
		accept: 'utils_calendar_event',
		onDrop: function(element,droppable,ev) {
			element.hide();
//			droppable.appendChild(element);
			setTimeout('Utils_Calendar.delete_event(\''+element.id+'\', \''+mpath+'\', \''+ecid+'\')',1);
		}
	});
},
delete_event:function(eid,mpath,ecid) {
	if(!confirm('Delete this event?')) {
		$(eid).show();
		return;
	}
	Epesi.updateIndicatorText("Deleting event");
	Epesi.procOn++;
	Epesi.updateIndicator();
	new Ajax.Request('modules/Utils/Calendar/update.php',{
			method:'post',
			parameters:{
				ev_id: eid.substr(21),
				cell_id: 'trash',
				path: mpath,
				cid: ecid
			},
			onComplete: function(t) {
				var reject=false;
				eval(t.responseText);
				var element = $(eid);
				if(reject) element.show();
				else {
					if(Utils_Calendar.page_type!='month') {
						Utils_Calendar.init_reload_event_tag();
						Utils_Calendar.remove_event_tag($(element.getAttribute('last_cell')),element);
						Utils_Calendar.flush_reload_event_tag();
					}
				}
				Epesi.procOn--;
				Epesi.updateIndicator();
			},
			onException: function(t,e) {
				throw(e);
			},
			onFailure: function(t) {
				alert('Failure ('+t.status+')');
				Epesi.text(t.responseText,'error_box','p');
			}
	});
},
destroy:function() {
	if(Utils_Calendar.ids==null) return;
//	alert('destroy');

	delete(Droppables.drops);
	Droppables.drops = [];
	Utils_Calendar.ids.each(function(id) {
//		Droppables.remove('UCcell_'+id[0]);
		var cell = $('UCcell_'+id);
		if(cell) cell.removeAttribute('events_children');
	});
	delete(Utils_Calendar.ids);
	Utils_Calendar.ids=null;

//	Droppables.remove('UCtrash');
}
};
document.observe('e:loading', Utils_Calendar.destroy);
<|endoftext|>


<commit_before>// randomColor by David Merfield under the CC0 license
// https://github.com/davidmerfield/randomColor/

;(function(root, factory) {

  // Support CommonJS
  if (typeof exports === 'object') {
    var randomColor = factory();

    // Support NodeJS & Component, which allow module.exports to be a function
    if (typeof module === 'object' && module && module.exports) {
      exports = module.exports = randomColor;
    }

    // Support CommonJS 1.1.1 spec
    exports.randomColor = randomColor;

  // Support AMD
  } else if (typeof define === 'function' && define.amd) {
    define([], factory);

  // Support vanilla script loading
  } else {
    root.randomColor = factory();
  }

}(this, function() {

  // Seed to get repeatable colors
  var seed = null;

  // Shared color dictionary
  var colorDictionary = {};

  // Populate the color dictionary
  loadColorBounds();

  var randomColor = function (options) {

    options = options || {};

    // Check if there is a seed and ensure it's an
    // integer. Otherwise, reset the seed value.
    if (options.seed !== undefined && options.seed !== null && options.seed === parseInt(options.seed, 10)) {
      seed = options.seed;

    // A string was passed as a seed
    } else if (typeof options.seed === 'string') {
      seed = stringToInteger(options.seed);

    // Something was passed as a seed but it wasn't an integer or string
    } else if (options.seed !== undefined && options.seed !== null) {
      throw new TypeError('The seed value must be an integer or string');

    // No seed, reset the value outside.
    } else {
      seed = null;
    }

    var H,S,B;

    // Check if we need to generate multiple colors
    if (options.count !== null && options.count !== undefined) {

      var totalColors = options.count,
          colors = [];

      options.count = null;

      while (totalColors > colors.length) {

        // Since we're generating multiple colors,
        // incremement the seed. Otherwise we'd just
        // generate the same color each time...
        if (seed && options.seed) options.seed += 1;

        colors.push(randomColor(options));
      }

      options.count = totalColors;

      return colors;
    }

    // First we pick a hue (H)
    H = pickHue(options);

    // Then use H to determine saturation (S)
    S = pickSaturation(H, options);

    // Then use S and H to determine brightness (B).
    B = pickBrightness(H, S, options);

    // Then we return the HSB color in the desired format
    return setFormat([H,S,B], options);
  };

  function pickHue (options) {

    var hueRange = getHueRange(options.hue),
        hue = randomWithin(hueRange);

    // Instead of storing red as two seperate ranges,
    // we group them, using negative numbers
    if (hue < 0) {hue = 360 + hue;}

    return hue;

  }

  function pickSaturation (hue, options) {

    if (options.hue === 'monochrome') {
      return 0;
    }

    if (options.luminosity === 'random') {
      return randomWithin([0,100]);
    }

    var saturationRange = getSaturationRange(hue);

    var sMin = saturationRange[0],
        sMax = saturationRange[1];

    switch (options.luminosity) {

      case 'bright':
        sMin = 55;
        break;

      case 'dark':
        sMin = sMax - 10;
        break;

      case 'light':
        sMax = 55;
        break;
   }

    return randomWithin([sMin, sMax]);

  }

  function pickBrightness (H, S, options) {

    var bMin = getMinimumBrightness(H, S),
        bMax = 100;

    switch (options.luminosity) {

      case 'dark':
        bMax = bMin + 20;
        break;

      case 'light':
        bMin = (bMax + bMin)/2;
        break;

      case 'random':
        bMin = 0;
        bMax = 100;
        break;
    }

    return randomWithin([bMin, bMax]);
  }

  function setFormat (hsv, options) {

    switch (options.format) {

      case 'hsvArray':
        return hsv;

      case 'hslArray':
        return HSVtoHSL(hsv);

      case 'hsl':
        var hsl = HSVtoHSL(hsv);
        return 'hsl('+hsl[0]+', '+hsl[1]+'%, '+hsl[2]+'%)';

      case 'hsla':
        var hslColor = HSVtoHSL(hsv);
        var alpha = options.alpha || Math.random();
        return 'hsla('+hslColor[0]+', '+hslColor[1]+'%, '+hslColor[2]+'%, ' + alpha + ')';

      case 'rgbArray':
        return HSVtoRGB(hsv);

      case 'rgb':
        var rgb = HSVtoRGB(hsv);
        return 'rgb(' + rgb.join(', ') + ')';

      case 'rgba':
        var rgbColor = HSVtoRGB(hsv);
        var alpha = options.alpha || Math.random();
        return 'rgba(' + rgbColor.join(', ') + ', ' + alpha + ')';

      default:
        return HSVtoHex(hsv);
    }

  }

  function getMinimumBrightness(H, S) {

    var lowerBounds = getColorInfo(H).lowerBounds;

    for (var i = 0; i < lowerBounds.length - 1; i++) {

      var s1 = lowerBounds[i][0],
          v1 = lowerBounds[i][1];

      var s2 = lowerBounds[i+1][0],
          v2 = lowerBounds[i+1][1];

      if (S >= s1 && S <= s2) {

         var m = (v2 - v1)/(s2 - s1),
             b = v1 - m*s1;

         return m*S + b;
      }

    }

    return 0;
  }

  function getHueRange (colorInput) {

    if (typeof parseInt(colorInput) === 'number') {

      var number = parseInt(colorInput);

      if (number < 360 && number > 0) {
        return [number, number];
      }

    }

    if (typeof colorInput === 'string') {

      if (colorDictionary[colorInput]) {
        var color = colorDictionary[colorInput];
        if (color.hueRange) {return color.hueRange;}
      } else if (colorInput.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)) {
        var hue = HexToHSB(colorInput)[0];
        return [ hue, hue ];
      }
    }

    return [0,360];

  }

  function getSaturationRange (hue) {
    return getColorInfo(hue).saturationRange;
  }

  function getColorInfo (hue) {

    // Maps red colors to make picking hue easier
    if (hue >= 334 && hue <= 360) {
      hue-= 360;
    }

    for (var colorName in colorDictionary) {
       var color = colorDictionary[colorName];
       if (color.hueRange &&
           hue >= color.hueRange[0] &&
           hue <= color.hueRange[1]) {
          return colorDictionary[colorName];
       }
    } return 'Color not found';
  }

  function randomWithin (range) {
    if (seed === null) {
      return Math.floor(range[0] + Math.random()*(range[1] + 1 - range[0]));
    } else {
      //Seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
      var max = range[1] || 1;
      var min = range[0] || 0;
      seed = (seed * 9301 + 49297) % 233280;
      var rnd = seed / 233280.0;
      return Math.floor(min + rnd * (max - min));
    }
  }

  function HSVtoHex (hsv){

    var rgb = HSVtoRGB(hsv);

    function componentToHex(c) {
        var hex = c.toString(16);
        return hex.length == 1 ? '0' + hex : hex;
    }

    var hex = '#' + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);

    return hex;

  }

  function defineColor (name, hueRange, lowerBounds) {

    var sMin = lowerBounds[0][0],
        sMax = lowerBounds[lowerBounds.length - 1][0],

        bMin = lowerBounds[lowerBounds.length - 1][1],
        bMax = lowerBounds[0][1];

    colorDictionary[name] = {
      hueRange: hueRange,
      lowerBounds: lowerBounds,
      saturationRange: [sMin, sMax],
      brightnessRange: [bMin, bMax]
    };

  }

  function loadColorBounds () {

    defineColor(
      'monochrome',
      null,
      [[0,0],[100,0]]
    );

    defineColor(
      'red',
      [-26,18],
      [[20,100],[30,92],[40,89],[50,85],[60,78],[70,70],[80,60],[90,55],[100,50]]
    );

    defineColor(
      'orange',
      [19,46],
      [[20,100],[30,93],[40,88],[50,86],[60,85],[70,70],[100,70]]
    );

    defineColor(
      'yellow',
      [47,62],
      [[25,100],[40,94],[50,89],[60,86],[70,84],[80,82],[90,80],[100,75]]
    );

    defineColor(
      'green',
      [63,178],
      [[30,100],[40,90],[50,85],[60,81],[70,74],[80,64],[90,50],[100,40]]
    );

    defineColor(
      'blue',
      [179, 257],
      [[20,100],[30,86],[40,80],[50,74],[60,60],[70,52],[80,44],[90,39],[100,35]]
    );

    defineColor(
      'purple',
      [258, 282],
      [[20,100],[30,87],[40,79],[50,70],[60,65],[70,59],[80,52],[90,45],[100,42]]
    );

    defineColor(
      'pink',
      [283, 334],
      [[20,100],[30,90],[40,86],[60,84],[80,80],[90,75],[100,73]]
    );

  }

  function HSVtoRGB (hsv) {

    // this doesn't work for the values of 0 and 360
    // here's the hacky fix
    var h = hsv[0];
    if (h === 0) {h = 1;}
    if (h === 360) {h = 359;}

    // Rebase the h,s,v values
    h = h/360;
    var s = hsv[1]/100,
        v = hsv[2]/100;

    var h_i = Math.floor(h*6),
      f = h * 6 - h_i,
      p = v * (1 - s),
      q = v * (1 - f*s),
      t = v * (1 - (1 - f)*s),
      r = 256,
      g = 256,
      b = 256;

    switch(h_i) {
      case 0: r = v; g = t; b = p;  break;
      case 1: r = q; g = v; b = p;  break;
      case 2: r = p; g = v; b = t;  break;
      case 3: r = p; g = q; b = v;  break;
      case 4: r = t; g = p; b = v;  break;
      case 5: r = v; g = p; b = q;  break;
    }

    var result = [Math.floor(r*255), Math.floor(g*255), Math.floor(b*255)];
    return result;
  }

  function HexToHSB (hex) {
    hex = hex.replace(/^#/, '');
    hex = hex.length === 3 ? hex.replace(/(.)/g, '$1$1') : hex;

    var red = parseInt(hex.substr(0, 2), 16) / 255,
          green = parseInt(hex.substr(2, 2), 16) / 255,
          blue = parseInt(hex.substr(4, 2), 16) / 255;

    var cMax = Math.max(red, green, blue),
          delta = cMax - Math.min(red, green, blue),
          saturation = cMax ? (delta / cMax) : 0;

    switch (cMax) {
      case red: return [ 60 * (((green - blue) / delta) % 6) || 0, saturation, cMax ];
      case green: return [ 60 * (((blue - red) / delta) + 2) || 0, saturation, cMax ];
      case blue: return [ 60 * (((red - green) / delta) + 4) || 0, saturation, cMax ];
    }
  }

  function HSVtoHSL (hsv) {
    var h = hsv[0],
      s = hsv[1]/100,
      v = hsv[2]/100,
      k = (2-s)*v;

    return [
      h,
      Math.round(s*v / (k<1 ? k : 2-k) * 10000) / 100,
      k/2 * 100
    ];
  }

  function stringToInteger (string) {
    var total = 0
    for (var i = 0; i !== string.length; i++) {
      if (total >= Number.MAX_SAFE_INTEGER) break;
      total += string.charCodeAt(i)
    }
    return total
  }

  return randomColor;
}));
<commit_msg>Maximise color difference<commit_after>// randomColor by David Merfield under the CC0 license
// https://github.com/davidmerfield/randomColor/

;(function(root, factory) {

  // Support CommonJS
  if (typeof exports === 'object') {
    var randomColor = factory();

    // Support NodeJS & Component, which allow module.exports to be a function
    if (typeof module === 'object' && module && module.exports) {
      exports = module.exports = randomColor;
    }

    // Support CommonJS 1.1.1 spec
    exports.randomColor = randomColor;

  // Support AMD
  } else if (typeof define === 'function' && define.amd) {
    define([], factory);

  // Support vanilla script loading
  } else {
    root.randomColor = factory();
  }

}(this, function() {

  // Seed to get repeatable colors
  var seed = null;

  // Shared color dictionary
  var colorDictionary = {};

  // Populate the color dictionary
  loadColorBounds();

  // check if a range is taken
  var colorRanges = [];

  var randomColor = function (options) {

    options = options || {};

    // Check if there is a seed and ensure it's an
    // integer. Otherwise, reset the seed value.
    if (options.seed !== undefined && options.seed !== null && options.seed === parseInt(options.seed, 10)) {
      seed = options.seed;

    // A string was passed as a seed
    } else if (typeof options.seed === 'string') {
      seed = stringToInteger(options.seed);

    // Something was passed as a seed but it wasn't an integer or string
    } else if (options.seed !== undefined && options.seed !== null) {
      throw new TypeError('The seed value must be an integer or string');

    // No seed, reset the value outside.
    } else {
      seed = null;
    }

    var H,S,B;

    // Check if we need to generate multiple colors
    if (options.count !== null && options.count !== undefined) {

      var totalColors = options.count,
          colors = [];
      // Value false at index i means the range i is not taken yet.
      for (var i = 0; i < options.count; i++) {
        colorRanges.push(false)
        }
      options.count = null;

      while (totalColors > colors.length) {

        // Since we're generating multiple colors,
        // incremement the seed. Otherwise we'd just
        // generate the same color each time...
        if (seed && options.seed) options.seed += 1;

        colors.push(randomColor(options));
      }

      options.count = totalColors;

      return colors;
    }

    // First we pick a hue (H)
    H = pickHue(options);

    // Then use H to determine saturation (S)
    S = pickSaturation(H, options);

    // Then use S and H to determine brightness (B).
    B = pickBrightness(H, S, options);

    // Then we return the HSB color in the desired format
    return setFormat([H,S,B], options);
  };

  function pickHue(options) {
    if (colorRanges.length > 0) {
      var hueRange = getRealHueRange(options.hue)

      var hue = randomWithin(hueRange)

      //Each of colorRanges.length ranges has a length equal approximatelly one step
      var step = (hueRange[1] - hueRange[0]) / colorRanges.length

      var j = parseInt((hue - hueRange[0]) / step)

      //Check if the range j is taken
      if (colorRanges[j] === true) {
        j = (j + 2) % colorRanges.length
      }
      else {
        colorRanges[j] = true
           }

      var min = (hueRange[0] + j * step) % 359,
          max = (hueRange[0] + (j + 1) * step) % 359;

      hueRange = [min, max]

      hue = randomWithin(hueRange)

      if (hue < 0) {hue = 360 + hue;}
      return hue
    }
    else {
      var hueRange = getHueRange(options.hue)

      hue = randomWithin(hueRange);
      // Instead of storing red as two seperate ranges,
      // we group them, using negative numbers
      if (hue < 0) {
        hue = 360 + hue;
      }

      return hue;
    }
  }

  function pickSaturation (hue, options) {

    if (options.hue === 'monochrome') {
      return 0;
    }

    if (options.luminosity === 'random') {
      return randomWithin([0,100]);
    }

    var saturationRange = getSaturationRange(hue);

    var sMin = saturationRange[0],
        sMax = saturationRange[1];

    switch (options.luminosity) {

      case 'bright':
        sMin = 55;
        break;

      case 'dark':
        sMin = sMax - 10;
        break;

      case 'light':
        sMax = 55;
        break;
   }

    return randomWithin([sMin, sMax]);

  }

  function pickBrightness (H, S, options) {

    var bMin = getMinimumBrightness(H, S),
        bMax = 100;

    switch (options.luminosity) {

      case 'dark':
        bMax = bMin + 20;
        break;

      case 'light':
        bMin = (bMax + bMin)/2;
        break;

      case 'random':
        bMin = 0;
        bMax = 100;
        break;
    }

    return randomWithin([bMin, bMax]);
  }

  function setFormat (hsv, options) {

    switch (options.format) {

      case 'hsvArray':
        return hsv;

      case 'hslArray':
        return HSVtoHSL(hsv);

      case 'hsl':
        var hsl = HSVtoHSL(hsv);
        return 'hsl('+hsl[0]+', '+hsl[1]+'%, '+hsl[2]+'%)';

      case 'hsla':
        var hslColor = HSVtoHSL(hsv);
        var alpha = options.alpha || Math.random();
        return 'hsla('+hslColor[0]+', '+hslColor[1]+'%, '+hslColor[2]+'%, ' + alpha + ')';

      case 'rgbArray':
        return HSVtoRGB(hsv);

      case 'rgb':
        var rgb = HSVtoRGB(hsv);
        return 'rgb(' + rgb.join(', ') + ')';

      case 'rgba':
        var rgbColor = HSVtoRGB(hsv);
        var alpha = options.alpha || Math.random();
        return 'rgba(' + rgbColor.join(', ') + ', ' + alpha + ')';

      default:
        return HSVtoHex(hsv);
    }

  }

  function getMinimumBrightness(H, S) {

    var lowerBounds = getColorInfo(H).lowerBounds;

    for (var i = 0; i < lowerBounds.length - 1; i++) {

      var s1 = lowerBounds[i][0],
          v1 = lowerBounds[i][1];

      var s2 = lowerBounds[i+1][0],
          v2 = lowerBounds[i+1][1];

      if (S >= s1 && S <= s2) {

         var m = (v2 - v1)/(s2 - s1),
             b = v1 - m*s1;

         return m*S + b;
      }

    }

    return 0;
  }

  function getHueRange (colorInput) {

    if (typeof parseInt(colorInput) === 'number') {

      var number = parseInt(colorInput);

      if (number < 360 && number > 0) {
        return [number, number];
      }

    }

    if (typeof colorInput === 'string') {

      if (colorDictionary[colorInput]) {
        var color = colorDictionary[colorInput];
        if (color.hueRange) {return color.hueRange;}
      } else if (colorInput.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)) {
        var hue = HexToHSB(colorInput)[0];
        return [ hue, hue ];
      }
    }

    return [0,360];

  }

  function getSaturationRange (hue) {
    return getColorInfo(hue).saturationRange;
  }

  function getColorInfo (hue) {

    // Maps red colors to make picking hue easier
    if (hue >= 334 && hue <= 360) {
      hue-= 360;
    }

    for (var colorName in colorDictionary) {
       var color = colorDictionary[colorName];
       if (color.hueRange &&
           hue >= color.hueRange[0] &&
           hue <= color.hueRange[1]) {
          return colorDictionary[colorName];
       }
    } return 'Color not found';
  }

  function randomWithin (range) {
    if (seed === null) {
      //generate random evenly destinct number from : https://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/
      var golden_ratio = 0.618033988749895
      var r=Math.random()
      r += golden_ratio
      r %= 1
      return Math.floor(range[0] + r*(range[1] + 1 - range[0]));
    } else {
      //Seeded random algorithm from http://indiegamr.com/generate-repeatable-random-numbers-in-js/
      var max = range[1] || 1;
      var min = range[0] || 0;
      seed = (seed * 9301 + 49297) % 233280;
      var rnd = seed / 233280.0;
      return Math.floor(min + rnd * (max - min));
}
  }

  function HSVtoHex (hsv){

    var rgb = HSVtoRGB(hsv);

    function componentToHex(c) {
        var hex = c.toString(16);
        return hex.length == 1 ? '0' + hex : hex;
    }

    var hex = '#' + componentToHex(rgb[0]) + componentToHex(rgb[1]) + componentToHex(rgb[2]);

    return hex;

  }

  function defineColor (name, hueRange, lowerBounds) {

    var sMin = lowerBounds[0][0],
        sMax = lowerBounds[lowerBounds.length - 1][0],

        bMin = lowerBounds[lowerBounds.length - 1][1],
        bMax = lowerBounds[0][1];

    colorDictionary[name] = {
      hueRange: hueRange,
      lowerBounds: lowerBounds,
      saturationRange: [sMin, sMax],
      brightnessRange: [bMin, bMax]
    };

  }

  function loadColorBounds () {

    defineColor(
      'monochrome',
      null,
      [[0,0],[100,0]]
    );

    defineColor(
      'red',
      [-26,18],
      [[20,100],[30,92],[40,89],[50,85],[60,78],[70,70],[80,60],[90,55],[100,50]]
    );

    defineColor(
      'orange',
      [19,46],
      [[20,100],[30,93],[40,88],[50,86],[60,85],[70,70],[100,70]]
    );

    defineColor(
      'yellow',
      [47,62],
      [[25,100],[40,94],[50,89],[60,86],[70,84],[80,82],[90,80],[100,75]]
    );

    defineColor(
      'green',
      [63,178],
      [[30,100],[40,90],[50,85],[60,81],[70,74],[80,64],[90,50],[100,40]]
    );

    defineColor(
      'blue',
      [179, 257],
      [[20,100],[30,86],[40,80],[50,74],[60,60],[70,52],[80,44],[90,39],[100,35]]
    );

    defineColor(
      'purple',
      [258, 282],
      [[20,100],[30,87],[40,79],[50,70],[60,65],[70,59],[80,52],[90,45],[100,42]]
    );

    defineColor(
      'pink',
      [283, 334],
      [[20,100],[30,90],[40,86],[60,84],[80,80],[90,75],[100,73]]
    );

  }

  function HSVtoRGB (hsv) {

    // this doesn't work for the values of 0 and 360
    // here's the hacky fix
    var h = hsv[0];
    if (h === 0) {h = 1;}
    if (h === 360) {h = 359;}

    // Rebase the h,s,v values
    h = h/360;
    var s = hsv[1]/100,
        v = hsv[2]/100;

    var h_i = Math.floor(h*6),
      f = h * 6 - h_i,
      p = v * (1 - s),
      q = v * (1 - f*s),
      t = v * (1 - (1 - f)*s),
      r = 256,
      g = 256,
      b = 256;

    switch(h_i) {
      case 0: r = v; g = t; b = p;  break;
      case 1: r = q; g = v; b = p;  break;
      case 2: r = p; g = v; b = t;  break;
      case 3: r = p; g = q; b = v;  break;
      case 4: r = t; g = p; b = v;  break;
      case 5: r = v; g = p; b = q;  break;
    }

    var result = [Math.floor(r*255), Math.floor(g*255), Math.floor(b*255)];
    return result;
  }

  function HexToHSB (hex) {
    hex = hex.replace(/^#/, '');
    hex = hex.length === 3 ? hex.replace(/(.)/g, '$1$1') : hex;

    var red = parseInt(hex.substr(0, 2), 16) / 255,
          green = parseInt(hex.substr(2, 2), 16) / 255,
          blue = parseInt(hex.substr(4, 2), 16) / 255;

    var cMax = Math.max(red, green, blue),
          delta = cMax - Math.min(red, green, blue),
          saturation = cMax ? (delta / cMax) : 0;

    switch (cMax) {
      case red: return [ 60 * (((green - blue) / delta) % 6) || 0, saturation, cMax ];
      case green: return [ 60 * (((blue - red) / delta) + 2) || 0, saturation, cMax ];
      case blue: return [ 60 * (((red - green) / delta) + 4) || 0, saturation, cMax ];
    }
  }

  function HSVtoHSL (hsv) {
    var h = hsv[0],
      s = hsv[1]/100,
      v = hsv[2]/100,
      k = (2-s)*v;

    return [
      h,
      Math.round(s*v / (k<1 ? k : 2-k) * 10000) / 100,
      k/2 * 100
    ];
  }

  function stringToInteger (string) {
    var total = 0
    for (var i = 0; i !== string.length; i++) {
      if (total >= Number.MAX_SAFE_INTEGER) break;
      total += string.charCodeAt(i)
    }
    return total
  }

  // get The range of given hue when options.count!=0
  function getRealHueRange(colorHue)
  { if (!isNaN(colorHue)) {
    var number = parseInt(colorHue);

    if (number < 360 && number > 0) {
      return getColorInfo(colorHue).hueRange
    }
  }
    else if (typeof colorHue === 'string') {

      if (colorDictionary[colorHue]) {
        var color = colorDictionary[colorHue];

        if (color.hueRange) {
          return color.hueRange
       }
    } else if (colorHue.match(/^#?([0-9A-F]{3}|[0-9A-F]{6})$/i)) {
        var hue = HexToHSB(colorHue)[0]
        return getColorInfo(hue).hueRange
    }
  }

    return [0,360]
}
  return randomColor;
}));
<|endoftext|>


<commit_before>"use strict";

var React             = require('react');
var NavigatableMixin  = require('./NavigatableMixin');
var Environment       = require('./Environment');

/**
 * Link.
 *
 * A basic navigatable component which renders into <a> DOM element and handles
 * onClick event by transitioning onto different route (defined by
 * this.props.href).
 */
var Link = React.createClass({
  mixins: [NavigatableMixin],

  displayName: 'Link',

  propTypes: {
    href: React.PropTypes.string.isRequired,
    global: React.PropTypes.bool,
    globalHash: React.PropTypes.bool
  },

  onClick: function(e) {
    e.preventDefault();
    this._navigate(this.props.href, function(err) {
      if (err) {
        throw err;
      }
    });
    if (this.props.onClick) {
      this.props.onClick(e);
    }
  },

  _createHref: function() {
    return this.props.global ?
      Environment.defaultEnvironment.makeHref(this.props.href) :
      this.makeHref(this.props.href);
  },

  _navigate: function(path, cb) {
    if(this.props.globalHash) {
      return Environment.hashEnvironment.navigate(path, cb);
    }

    return this.props.global ?
      Environment.defaultEnvironment.navigate(path, cb) :
      this.navigate(path, cb);
  },

  render: function() {
    var props = {
      onClick: this.onClick,
      href: this._createHref()
    };
    return this.transferPropsTo(React.DOM.a(props, this.props.children));
  }
});

module.exports = Link;
<commit_msg>lib/Link: gardening<commit_after>"use strict";

var React             = require('react');
var NavigatableMixin  = require('./NavigatableMixin');
var Environment       = require('./Environment');

/**
 * Link.
 *
 * A basic navigatable component which renders into <a> DOM element and handles
 * onClick event by transitioning onto different route (defined by
 * this.props.href).
 */
var Link = React.createClass({
  mixins: [NavigatableMixin],

  displayName: 'Link',

  propTypes: {
    href: React.PropTypes.string.isRequired,
    global: React.PropTypes.bool,
    globalHash: React.PropTypes.bool
  },

  onClick: function(e) {
    e.preventDefault();
    this._navigate(this.props.href, function(err) {
      if (err) {
        throw err;
      }
    });
    if (this.props.onClick) {
      this.props.onClick(e);
    }
  },

  _createHref: function() {
    return this.props.global ?
      Environment.defaultEnvironment.makeHref(this.props.href) :
      this.makeHref(this.props.href);
  },

  _navigate: function(path, cb) {
    if (this.props.globalHash) {
      return Environment.hashEnvironment.navigate(path, cb);
    }

    if (this.props.global) {
      return Environment.defaultEnvironment.navigate(path, cb);
    }

    return this.navigate(path, cb);
  },

  render: function() {
    var props = {
      onClick: this.onClick,
      href: this._createHref()
    };
    return this.transferPropsTo(React.DOM.a(props, this.props.children));
  }
});

module.exports = Link;
<|endoftext|>


<commit_before>/* This is the entry point for all web requests
 * This will deal with handling the distrobution of requests to the static file server or api
 */

var express    = require('express');        // call express
var app        = express();                 // define our app using express
var path       = require('path');
var bodyParser = require('body-parser');
var port       = process.env.PORT || 3030;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

var neo4j = require('neo4j');
var db = new neo4j.GraphDatabase('http://neo4j:n@localhost:7474');

//================================= Routes
var apiRouter = express.Router();

apiRouter.get('/claim', function(req, res){
   //http://localhost:3030/claim

    try {

        db.cypher({
            query: 'MATCH (n) RETURN (n) LIMIT 100'
        }, function (err, results) {
            if (err) throw err;

            if (!results) {
                console.log('No claims found.');
                res.json({
                    error: 'No claims found'
                });
            } else {
                console.log(JSON.stringify(results, null, 4));
                res.json({
                    claims: results
                });
            }
        });

    }
    catch(err){
        res.json({
            error: 'Server error' + err
        });
    }
});

app.use('/', apiRouter);

//================================= Begin
app.listen(port);

console.log('http://localhost:' + port);<commit_msg>CORS - now they talk to each other :D<commit_after>/* This is the entry point for all web requests
 * This will deal with handling the distrobution of requests to the static file server or api
 */

var express    = require('express');        // call express
var app        = express();                 // define our app using express
var path       = require('path');
var bodyParser = require('body-parser');
var port       = process.env.PORT || 3030;

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

//CORS
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    next();
});

var neo4j = require('neo4j');
var db = new neo4j.GraphDatabase('http://neo4j:n@localhost:7474');

//================================= Routes
var apiRouter = express.Router();

apiRouter.get('/claim', function(req, res){
   //http://localhost:3030/claim

    try {

        db.cypher({
            query: 'MATCH (n) RETURN (n) LIMIT 100'
        }, function (err, results) {
            if (err) throw err;

            if (!results) {
                console.log('No claims found.');
                res.json({
                    error: 'No claims found'
                });
            } else {
                console.log(JSON.stringify(results, null, 4));
                res.json({
                    claims: results
                });
            }
        });

    }
    catch(err){
        res.json({
            error: 'Server error' + err
        });
    }
});

app.use('/', apiRouter);

//================================= Begin
app.listen(port);

console.log('http://localhost:' + port);<|endoftext|>


<commit_before>'use strict';

const boom = require('boom');
const hu = require('../lib/handler-utils');

module.exports = (route, options) => {
  const Model = options.model;

  return (req, reply) => {

    const query = hu.getIdQuery(options, req);
    if (options.preQuery) options.preSend(query); // query extension point
    Model.remove(query, (err, mod) => {

      if (err) return reply(boom.badImplementation(err));
      return reply(mod);
    });
  };
};

module.exports.validOptions = {
  idKey: hu.schemas.idKey,
};
<commit_msg>delete: return document instead of mongo result<commit_after>'use strict';

const boom = require('boom');
const hu = require('../lib/handler-utils');

module.exports = (route, options) => {
  const Model = options.model;

  return (req, reply) => {

    const query = hu.getIdQuery(options, req);
    if (options.preQuery) options.preSend(query); // query extension point
    Model.findOneAndRemove(query, (err, mod) => {

      if (err) return reply(boom.badImplementation(err));
      return reply(mod);
    });
  };
};

module.exports.validOptions = {
  idKey: hu.schemas.idKey,
};
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { useTranslator } from '@u-wave/react-translate';
import CircularProgress from '@material-ui/core/CircularProgress';
import Tooltip from '@material-ui/core/Tooltip';
import IconButton from '@material-ui/core/IconButton';
import ShuffleIcon from '@material-ui/icons/Shuffle';

const { useCallback, useState } = React;
const HARDCODED_LOADING_SIZE = 24; // FIXME derive this from some mui property?

function ShuffleButton({ onShuffle }) {
  const [isLoading, setLoading] = useState(false);
  const { t } = useTranslator();

  const onClick = useCallback(() => {
    setLoading(true);
    onShuffle().finally(() => {
      setLoading(false);
    });
  }, [onShuffle]);

  return (
    <Tooltip title={t('playlists.shuffle')} placement="top">
      <IconButton
        className="PlaylistMeta-iconButton"
        onClick={onClick}
      >
        {isLoading ? (
          <CircularProgress size={HARDCODED_LOADING_SIZE} />
        ) : (
          <ShuffleIcon />
        )}
      </IconButton>
    </Tooltip>
  );
}

ShuffleButton.propTypes = {
  onShuffle: PropTypes.func.isRequired,
};

export default ShuffleButton;
<commit_msg>Disable shuffle button while shuffling in progress.<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { useTranslator } from '@u-wave/react-translate';
import CircularProgress from '@material-ui/core/CircularProgress';
import Tooltip from '@material-ui/core/Tooltip';
import IconButton from '@material-ui/core/IconButton';
import ShuffleIcon from '@material-ui/icons/Shuffle';

const { useCallback, useState } = React;
const HARDCODED_LOADING_SIZE = 24; // FIXME derive this from some mui property?

function ShuffleButton({ onShuffle }) {
  const [isLoading, setLoading] = useState(false);
  const { t } = useTranslator();

  const onClick = useCallback(() => {
    setLoading(true);
    onShuffle().finally(() => {
      setLoading(false);
    });
  }, [onShuffle]);

  return (
    <Tooltip title={t('playlists.shuffle')} placement="top">
      <IconButton
        className="PlaylistMeta-iconButton"
        onClick={onClick}
        disabled={isLoading}
      >
        {isLoading ? (
          <CircularProgress size={HARDCODED_LOADING_SIZE} />
        ) : (
          <ShuffleIcon />
        )}
      </IconButton>
    </Tooltip>
  );
}

ShuffleButton.propTypes = {
  onShuffle: PropTypes.func.isRequired,
};

export default ShuffleButton;
<|endoftext|>


<commit_before>var keys = require('../keys');
var express = require('express');
var router = express.Router();
var SpotifyWebApi = require('spotify-web-api-node');

// credentials are optional
var spotifyApi = new SpotifyWebApi({
 	'accessToken' : 'myAccessToken',
 	'refreshToken' : 'myRefreshToken',
 	response_type : 'code',
	'client_id' : keys.spotifyclientID,
	clientSecret : keys.spotifyclientSecret,
	redirectUri : 'http://localhost/playlist'
});

var scopes = ['playlist-modify-public', 'user-read-email', 'playlist-read-private', 'user-read-private'];
var authorizationCode = 'sa';

/* GET users listing. */
router.get('/', function(req, res, next) {
	//res.send('respond with a resource');
	//var authorizeURL = spotifyApi.createAuthorizeURL(scopes);
	dothis();
	res.render('loginreturn', {title : 'Playlist'});
});

module.exports = router;

var dothis = function()
{
	spotifyApi.authorizationCodeGrant(authorizationCode)
	  .then(function(data) {
	    spotifyApi.setAccessToken(data.body['access_token']);
	    //return spotifyApi.addTracksToPlaylist('thelinmichael', '5ieJqeLJjjI8iJWaxeBLuK', ["spotify:track:4iV5W9uYEdYUVa79Axb7Rh", "spotify:track:1301WleyT98MSxVHPZCA6M"],
	    //  {
	    //    position : 10
	    //  })
	  }).then(function(data) {
	    console.log('Added tracks to the playlist!');
	  }).catch(function(err) {
	    console.log('Something went wrong!', err.message);
	  });
}

<commit_msg>playlist<commit_after>var keys = require('../keys');
var express = require('express');
var router = express.Router();
var SpotifyWebApi = require('spotify-web-api-node');

// credentials are optional
var spotifyApi = new SpotifyWebApi({
 	'accessToken' : 'myAccessToken',
 	'refreshToken' : 'myRefreshToken',
 	response_type : 'code',
	clientID : keys.spotifyclientID,
	clientSecret : keys.spotifyclientSecret,
	redirectUri : 'http://localhost/playlist'
});

var scopes = ['playlist-modify-public', 'user-read-email', 'playlist-read-private', 'user-read-private'];
var authorizationCode = 'sa';

/* GET users listing. */
router.get('/', function(req, res, next) {
	//res.send('respond with a resource');
	//var authorizeURL = spotifyApi.createAuthorizeURL(scopes);
	dothis();
	res.render('loginreturn', {title : 'Playlist'});
});

module.exports = router;

var dothis = function()
{
	spotifyApi.authorizationCodeGrant(authorizationCode)
	  .then(function(data) {
	    spotifyApi.setAccessToken(data.body['access_token']);
	    return spotifyApi.addTracksToPlaylist('gabe1118', '5ieJqeLJjjI8iJWaxeBLuK', ["spotify:track:4iV5W9uYEdYUVa79Axb7Rh", "spotify:track:1301WleyT98MSxVHPZCA6M"],
	      {
	        position : 10
	      })
	  }).then(function(data) {
	    console.log('Added tracks to the playlist!');
	  }).catch(function(err) {
	    console.log('Something went wrong!', err.message);
	  });
}

<|endoftext|>


<commit_before>(function() {

    var randomgraph = {

        /*
         * Simple balanced tree
         *
         * @param r number of children each node has
         * @param h height of the tree
         */
        BalancedTree: function(r, h) {
            var v = 0,
                graph = { nodes: [{ label: 'node 0', index: 0 }], edges: [] },
                newLeaves = [],
                i, j, height, node, leaves;

            for (i = 0; i < r; i++) {
                node = { label: 'node '+(++v), index: (v-1) };
                graph.nodes.push(node);
                newLeaves.push(node);
                graph.edges.push({ source: 0, target: v });
            }

            for (height = 1; height < h; height++) {
                leaves = newLeaves;
                newLeaves = [];
                for (j = 0; j < leaves.length; j++) {
                    for (i = 0; i < r; i++) {
                        node = { label: 'node '+(++v), index: (v-1) };
                        newLeaves.push(node);
                        graph.nodes.push(node);
                        graph.edges.push({ source: leaves[j].index, target: v });
                    }
                }
            }
            return graph;
        },

        ErdosRenyi: {
            /**
             * Erdős–Rényi aka Gilbert
             *
             * @param n number of nodes
             * @param p probability of a edge between any two nodes
             */
            np: function(n, p) {
                var graph = { nodes: [], edges: [] },
                    i, j;
                for (i = 0; i < n; i++) {
                    graph.nodes.push({ label: 'node '+i });
                    for (j = 0; j < i; j++) {
                        if (Math.random() < p) {
                            graph.edges.push({
                                source: i,
                                target: j
                            });
                        }
                    }
                }
                return graph;
            },

            /**
             * Erdős–Rényi aka Gilbert
             *
             * @param n number of nodes
             * @param m number of edges
             */
            nm: function(n, m) {
                var graph = { nodes: [], edges: [] },
                    tmpEdges = [],
                    i, j, k;
                for (i = 0; i < n; i++) {
                    graph.nodes.push({ label: 'node '+i });
                    for (j = i+1; j < n; j++) {
                        tmpEdges.push({ source: i, target: j });
                    }
                }
                // pick m random edges from tmpEdges
                k = tmpEdges.length - 1;
                for (i = 0; i < m; i++) {
                    graph.edges.push(tmpEdges.splice(Math.floor(Math.random()*k), 1)[0]);
                    k--;
                }
                return graph;
            }

        },

        WattsStrogatz: {

            /**
             * Watts-Strogatz Small World model Alpha
             *
             * @param n number of nodes
             * @param K mean degree (even integer)
             * @param alpha rewiring probability [0..1]
             */
            alpha: function(n, k, alpha) {
                var graph = { nodes: [], edges: [] },
                    i, j, edge,
                    p = Math.pow(10, -10),
                    ec = 0,
                    edge_lut = {},
                    ids = [],
                    nk_half = n * k / 2,
                    Rij, sumRij, r, pij;

                for (i = 0; i < n; i++) {
                    graph.nodes.push({ label: 'node '+i });
                    // create a latice ring structure
                    edge = { source: i, target: (i+1)%n };
                    edge_lut[edge.source+'-'+edge.target] = edge;
                    graph.edges.push(edge);
                    ec++;
                }
                // Creating n * k / 2 edges
                while (ec < nk_half) {
                    for (i = 0; i < n; i++) {
                        ids.push(i);
                    }
                    while (ec < nk_half && ids.length > 0) {
                        i = ids.splice(Math.floor(Math.random()*ids.length), 1)[0];
                        Rij = [];
                        sumRij = 0;
                        for (j = 0; j < n; j++) {
                            Rij[j] = calculateRij(i, j);
                            sumRij += Rij[j];
                        }
                        r = Math.random();
                        pij = 0;
                        for (j = 0; j < n; j++) {
                            if (i != j) {
                                pij += Rij[j] / sumRij;
                                if (r <= pij) {
                                    edge = { source: i, target: j };
                                    graph.edges.push(edge);
                                    ec++;
                                    edge_lut[edge.source+'-'+edge.target] = edge;
                                }
                            }
                        }
                    }
                }

                return graph;

                function calculateRij(i, j) {
                    if (i == j || edge_lut[i+'-'+j]) return 0;
                    var mij = calculatemij(i, j);
                    if (mij >= k) return 1;
                    if (mij === 0) return p;
                    return Math.pow(mij / k, alpha) * (1 - p) + p;
                }

                function calculatemij(i, j) {
                    var mij = 0, l;
                    for (l = 0; l < n; l++) {
                        if (l != i && l != j && edge_lut[i+'-'+l] && edge_lut[j+'-'+l]) {
                            mij++;
                        }
                    }
                    return mij;
                }
            },

            /**
             * Watts-Strogatz Small World model Beta
             *
             * @param n number of nodes
             * @param K mean degree (even integer)
             * @param beta rewiring probability [0..1]
             */
            beta: function(n, K, beta) {
                var graph = { nodes: [], edges: [] },
                    i, j, t, edge,
                    edge_lut = {};
                K = K>>1; // divide by two
                for (i = 0; i < n; i++) {
                    graph.nodes.push({ label: 'node '+i });
                    // create a latice ring structure
                    for (j = 1; j <= K; j++) {
                        edge = { source: i, target: (i+j)%n };
                        edge_lut[edge.source+'-'+edge.target] = edge;
                        graph.edges.push(edge);
                    }
                }
                // rewiring of edges
                for (i = 0; i < n; i++) {
                    for (j = 1; j <= K; j++) { // for every pair of nodes
                        if (Math.random() <= beta) {
                            do {
                                t = Math.floor(Math.random() * (n-1));
                            } while (t == i || edge_lut[i+'-'+t]);
                            var j_ = (i+j)%n;
                            edge_lut[i+'-'+j_].target = t; // rewire
                            edge_lut[i+'-'+t] = edge_lut[i+'-'+j_];
                            delete edge_lut[i+'-'+j_];
                        }
                    }
                }
                return graph;
            }
        },

        /**
         * Barabási–Albert
         *
         * @param N total number of nodes  N  > 0
         * @param m0  m0 > 0 && m0 <  N
         * @param M    M  > 0 && M  <= m0
         */
        BarabasiAlbert: function(N, m0, M) {
            var graph = { nodes: [], edges: [] },
                edge_lut = {},
                degrees = [],
                i, j, edge, sum, s, m, r, p;
            // creating m0 nodes
            for (i = 0; i < m0; i++) {
                graph.nodes.push({ label: 'node '+i });
                degrees[i] = 0;
            }
            // Linking every node with each other (no self-loops)
            for (i = 0; i < m0; i++) {
                for (j = i+1; j < m0; j++) {
                    edge = { source: i, target: j };
                    edge_lut[edge.source+'-'+edge.target] = edge;
                    graph.edges.push(edge);
                    degrees[i]++;
                    degrees[j]++;
                }
            }
            // Adding N - m0 nodes, each with M edges
            for (i = m0; i < N; i++) {
                graph.nodes.push({ label: 'node '+i });
                degrees[i] = 0;
                sum = 0;  // sum of all nodes degrees
                for (j = 0; j < i; j++) sum += degrees[j];
                s = 0;
                for (m = 0; m < M; m++) {
                    r = Math.random();
                    p = 0;
                    for (j = 0; j < i; j++) {
                        if (edge_lut[i+'-'+j] || edge_lut[j+'-'+i]) continue;
                        if (i == 1) p = 1;
                        else p += degrees[j] / sum + s / (i - m);

                        if (r <= p) {
                            s += degrees[j] / sum;
                            edge = { source: i, target: j };
                            edge_lut[edge.source+'-'+edge.target] = edge;
                            graph.edges.push(edge);
                            degrees[i]++;
                            degrees[j]++;
                            break;
                        }
                    }
                }
            }
            return graph;
        }
    };

    // CommonJS module is defined
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = randomgraph;
    }

    /*global ender:false */
    if (typeof ender === 'undefined') {
        // here, `this` means `window` in the browser, or `global` on the server
        // add `numeral` as a global object via a string identifier,
        // for Closure Compiler 'advanced' mode
        this['randomgraph'] = randomgraph;
    }

    /*global define:false */
    if (typeof define === 'function' && define.amd) {
        define([], function () {
            return randomgraph;
        });
    }

})();<commit_msg>white space<commit_after>(function() {

    var randomgraph = {

        /*
         * Simple balanced tree
         *
         * @param r number of children each node has
         * @param h height of the tree
         */
        BalancedTree: function(r, h) {
            var v = 0,
                graph = { nodes: [{ label: 'node 0', index: 0 }], edges: [] },
                newLeaves = [],
                i, j, height, node, leaves;

            for (i = 0; i < r; i++) {
                node = { label: 'node '+(++v), index: (v-1) };
                graph.nodes.push(node);
                newLeaves.push(node);
                graph.edges.push({ source: 0, target: v });
            }

            for (height = 1; height < h; height++) {
                leaves = newLeaves;
                newLeaves = [];
                for (j = 0; j < leaves.length; j++) {
                    for (i = 0; i < r; i++) {
                        node = { label: 'node '+(++v), index: (v-1) };
                        newLeaves.push(node);
                        graph.nodes.push(node);
                        graph.edges.push({ source: leaves[j].index, target: v });
                    }
                }
            }
            return graph;
        },

        ErdosRenyi: {
            /**
             * Erdős–Rényi aka Gilbert
             *
             * @param n number of nodes
             * @param p probability of a edge between any two nodes
             */
            np: function(n, p) {
                var graph = { nodes: [], edges: [] },
                    i, j;
                for (i = 0; i < n; i++) {
                    graph.nodes.push({ label: 'node '+i });
                    for (j = 0; j < i; j++) {
                        if (Math.random() < p) {
                            graph.edges.push({
                                source: i,
                                target: j
                            });
                        }
                    }
                }
                return graph;
            },

            /**
             * Erdős–Rényi aka Gilbert
             *
             * @param n number of nodes
             * @param m number of edges
             */
            nm: function(n, m) {
                var graph = { nodes: [], edges: [] },
                    tmpEdges = [],
                    i, j, k;
                for (i = 0; i < n; i++) {
                    graph.nodes.push({ label: 'node '+i });
                    for (j = i+1; j < n; j++) {
                        tmpEdges.push({ source: i, target: j });
                    }
                }
                // pick m random edges from tmpEdges
                k = tmpEdges.length - 1;
                for (i = 0; i < m; i++) {
                    graph.edges.push(tmpEdges.splice(Math.floor(Math.random()*k), 1)[0]);
                    k--;
                }
                return graph;
            }

        },

        WattsStrogatz: {

            /**
             * Watts-Strogatz Small World model Alpha
             *
             * @param n number of nodes
             * @param K mean degree (even integer)
             * @param alpha rewiring probability [0..1]
             */
            alpha: function(n, k, alpha) {
                var graph = { nodes: [], edges: [] },
                    i, j, edge,
                    p = Math.pow(10, -10),
                    ec = 0,
                    edge_lut = {},
                    ids = [],
                    nk_half = n * k / 2,
                    Rij, sumRij, r, pij;

                for (i = 0; i < n; i++) {
                    graph.nodes.push({ label: 'node '+i });
                    // create a latice ring structure
                    edge = { source: i, target: (i+1)%n };
                    edge_lut[edge.source+'-'+edge.target] = edge;
                    graph.edges.push(edge);
                    ec++;
                }
                // Creating n * k / 2 edges
                while (ec < nk_half) {
                    for (i = 0; i < n; i++) {
                        ids.push(i);
                    }
                    while (ec < nk_half && ids.length > 0) {
                        i = ids.splice(Math.floor(Math.random()*ids.length), 1)[0];
                        Rij = [];
                        sumRij = 0;
                        for (j = 0; j < n; j++) {
                            Rij[j] = calculateRij(i, j);
                            sumRij += Rij[j];
                        }
                        r = Math.random();
                        pij = 0;
                        for (j = 0; j < n; j++) {
                            if (i != j) {
                                pij += Rij[j] / sumRij;
                                if (r <= pij) {
                                    edge = { source: i, target: j };
                                    graph.edges.push(edge);
                                    ec++;
                                    edge_lut[edge.source+'-'+edge.target] = edge;
                                }
                            }
                        }
                    }
                }

                return graph;

                function calculateRij(i, j) {
                    if (i == j || edge_lut[i+'-'+j]) return 0;
                    var mij = calculatemij(i, j);
                    if (mij >= k) return 1;
                    if (mij === 0) return p;
                    return Math.pow(mij / k, alpha) * (1 - p) + p;
                }

                function calculatemij(i, j) {
                    var mij = 0, l;
                    for (l = 0; l < n; l++) {
                        if (l != i && l != j && edge_lut[i+'-'+l] && edge_lut[j+'-'+l]) {
                            mij++;
                        }
                    }
                    return mij;
                }
            },

            /**
             * Watts-Strogatz Small World model Beta
             *
             * @param n number of nodes
             * @param K mean degree (even integer)
             * @param beta rewiring probability [0..1]
             */
            beta: function(n, K, beta) {
                var graph = { nodes: [], edges: [] },
                    i, j, t, edge,
                    edge_lut = {};
                K = K>>1; // divide by two
                for (i = 0; i < n; i++) {
                    graph.nodes.push({ label: 'node '+i });
                    // create a latice ring structure
                    for (j = 1; j <= K; j++) {
                        edge = { source: i, target: (i+j)%n };
                        edge_lut[edge.source+'-'+edge.target] = edge;
                        graph.edges.push(edge);
                    }
                }
                // rewiring of edges
                for (i = 0; i < n; i++) {
                    for (j = 1; j <= K; j++) { // for every pair of nodes
                        if (Math.random() <= beta) {
                            do {
                                t = Math.floor(Math.random() * (n-1));
                            } while (t == i || edge_lut[i+'-'+t]);
                            var j_ = (i+j)%n;
                            edge_lut[i+'-'+j_].target = t; // rewire
                            edge_lut[i+'-'+t] = edge_lut[i+'-'+j_];
                            delete edge_lut[i+'-'+j_];
                        }
                    }
                }
                return graph;
            }
        },

        /**
         * Barabási–Albert
         *
         * @param N total number of nodes  N  > 0
         * @param m0  m0 > 0 && m0 <  N
         * @param M    M  > 0 && M  <= m0
         */
        BarabasiAlbert: function(N, m0, M) {
            var graph = { nodes: [], edges: [] },
                edge_lut = {},
                degrees = [],
                i, j, edge, sum, s, m, r, p;
            // creating m0 nodes
            for (i = 0; i < m0; i++) {
                graph.nodes.push({ label: 'node '+i });
                degrees[i] = 0;
            }
            // Linking every node with each other (no self-loops)
            for (i = 0; i < m0; i++) {
                for (j = i+1; j < m0; j++) {
                    edge = { source: i, target: j };
                    edge_lut[edge.source+'-'+edge.target] = edge;
                    graph.edges.push(edge);
                    degrees[i]++;
                    degrees[j]++;
                }
            }
            // Adding N - m0 nodes, each with M edges
            for (i = m0; i < N; i++) {
                graph.nodes.push({ label: 'node '+i });
                degrees[i] = 0;
                sum = 0;  // sum of all nodes degrees
                for (j = 0; j < i; j++) sum += degrees[j];
                s = 0;
                for (m = 0; m < M; m++) {
                    r = Math.random();
                    p = 0;
                    for (j = 0; j < i; j++) {
                        if (edge_lut[i+'-'+j] || edge_lut[j+'-'+i]) continue;
                        if (i == 1) p = 1;
                        else p += degrees[j] / sum + s / (i - m);

                        if (r <= p) {
                            s += degrees[j] / sum;
                            edge = { source: i, target: j };
                            edge_lut[edge.source+'-'+edge.target] = edge;
                            graph.edges.push(edge);
                            degrees[i]++;
                            degrees[j]++;
                            break;
                        }
                    }
                }
            }
            return graph;
        }
    };

    // CommonJS module is defined
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = randomgraph;
    }

    /*global ender:false */
    if (typeof ender === 'undefined') {
        // here, `this` means `window` in the browser, or `global` on the server
        // add `numeral` as a global object via a string identifier,
        // for Closure Compiler 'advanced' mode
        this['randomgraph'] = randomgraph;
    }

    /*global define:false */
    if (typeof define === 'function' && define.amd) {
        define([], function () {
            return randomgraph;
        });
    }

})();<|endoftext|>


<commit_before>module.exports = Site;

var fs = require('fs'),
	path = require('path'),
	jade = require('jade'),
	express = require('express'),
	async = require('async');

var fsUtil = require('./fs-util'),
	Parsers = require('./Parsers'),
	thumbnails = require('./thumbnails'),
	watchDirectory = require('./watchDirectory'),
	Page = require('./Page');

require('util').inherits(Site, require('events').EventEmitter);

function Site(woods, directory, callback) {
	this.woods = woods;
	this.directory = directory;
	this.url = path.join('/', this.directory);
	this.parsers = new Parsers(this);
	watchDirectory(this);
	installRoutes(this);
	var site = this;
	this.parsers.loadAll(function() {
		site.build(function(err) {
			callback(err);
		});
	});
}

Site.prototype.getUri = function(file) {
	return path.resolve(this.woods.directory, this.directory, file || '');
};

Site.prototype._addType = function(type, callback) {
	if (this._types[type])
		return callback();

	// Check for templates belonging to type and install them
	var typeTemplates = this._types[type] = {},
		templateLocations = this._templateLocations[type] = {},
		templatesDir = getTemplateDirectory(this, type);

	var compileTemplate = function(file, doneCompiling) {
		// Compile jade templates:
		if ((/jade$/).test(file)) {
			var templateName = path.basename(file, '.jade');
			var location = templateLocations[templateName] =
					path.join(templatesDir, file);
			fs.readFile(location, 'utf-8', function(err, data) {
				if (!err)
					typeTemplates[templateName] = jade.compile(data);
				return doneCompiling(err);
			});
		} else {
			return doneCompiling();
		}
	};

	fsUtil.listOnlyVisibleFiles(templatesDir, function(err, files) {
		if (err || !files)
			return callback(err);
		async.each(files, compileTemplate, callback);
	});
};

// TODO: what happens if this function is called while
// the site is already being built?
Site.prototype.build = function(callback) {
	var site = this;
	site.pageCount = 0;
	// TODO: remove static routes
	site._types = {};
	site._templateLocations = {};
	site._addType('default', function(err) {
		if (err)
			return callback(err);
		site.root = new Page(site, null, '', null, function(err) {
			site.modified = Date.now();
			callback(err);
		});
	});
};

function getTemplateDirectory(site, type) {
	return site.getUri(path.join('templates', type || ''));
}

function escapeRegex(str) {
	return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

function installRoutes(site) {
	site.woods.express.use(
		path.join(site.url, 'assets'),
		express.static(site.getUri('assets'))
	);

	var regex = new RegExp(escapeRegex(site.url) + '(.+)*');
	// Install the path in express:
	site.woods.express.get(regex, function(req, res, next) {
		var then = new Date(),
			page = site.root.get(req.params.length && req.params[0]);
		if (page) {
			res.end(page._renderTemplate('html', {
				_activePage: page,
				request: req,
				query: req.query
			}));
			console.log('Serving ', req.url, 'took', new Date() - then);
		} else {
			next();
		}
	});
}
<commit_msg>Implement site settings.<commit_after>module.exports = Site;

var fs = require('fs'),
	path = require('path'),
	jade = require('jade'),
	express = require('express'),
	parsedown = require('woods-parsedown');

var fsUtil = require('./fs-util'),
	Parsers = require('./Parsers'),
	thumbnails = require('./thumbnails'),
	watchDirectory = require('./watchDirectory'),
	Page = require('./Page');

require('util').inherits(Site, require('events').EventEmitter);

var loadSettings = function(site, callback) {
	fsUtil.readIfExists(site.getUri('settings.md'), function(err, data) {
		site.settings = err ? {} : parsedown(data);
		callback();
	});
};

function Site(woods, directory, callback) {
	this.woods = woods;
	this.directory = directory;
	this.url = path.join('/', this.directory);
	this.parsers = new Parsers(this);
	watchDirectory(this);
	installRoutes(this);
	var site = this;
	loadSettings(this, function() {
		site.parsers.loadAll(function() {
			site.build(callback);
		});
	});
}

Site.prototype.getUri = function(file) {
	return path.resolve(this.woods.directory, this.directory, file || '');
};

Site.prototype._addType = function(type, callback) {
	if (this._types[type])
		return callback();

	// Check for templates belonging to type and install them
	var typeTemplates = this._types[type] = {},
		templateLocations = this._templateLocations[type] = {},
		templatesDir = getTemplateDirectory(this, type);

	var compileTemplate = function(file, doneCompiling) {
		// Compile jade templates:
		if ((/jade$/).test(file)) {
			var templateName = path.basename(file, '.jade');
			var location = templateLocations[templateName] =
					path.join(templatesDir, file);
			fs.readFile(location, 'utf-8', function(err, data) {
				if (!err)
					typeTemplates[templateName] = jade.compile(data);
				return doneCompiling(err);
			});
		} else {
			return doneCompiling();
		}
	};

	fsUtil.listOnlyVisibleFiles(templatesDir, function(err, files) {
		if (err || !files)
			return callback(err);
		async.each(files, compileTemplate, callback);
	});
};

// TODO: what happens if this function is called while
// the site is already being built?
Site.prototype.build = function(callback) {
	var site = this;
	site.pageCount = 0;
	// TODO: remove static routes
	site._types = {};
	site._templateLocations = {};
	site._addType('default', function(err) {
		if (err)
			return callback(err);
		site.root = new Page(site, null, '', null, function(err) {
			site.modified = Date.now();
			callback(err);
		});
	});
};

function getTemplateDirectory(site, type) {
	return site.getUri(path.join('templates', type || ''));
}

function escapeRegex(str) {
	return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

function installRoutes(site) {
	site.woods.express.use(
		path.join(site.url, 'assets'),
		express.static(site.getUri('assets'))
	);

	var regex = new RegExp(escapeRegex(site.url) + '(.+)*');
	// Install the path in express:
	site.woods.express.get(regex, function(req, res, next) {
		var then = new Date(),
			page = site.root.get(req.params.length && req.params[0]);
		if (page) {
			res.end(page._renderTemplate('html', {
				_activePage: page,
				request: req,
				query: req.query
			}));
			console.log('Serving ', req.url, 'took', new Date() - then);
		} else {
			next();
		}
	});
}
<|endoftext|>


<commit_before>(function(上帝){
	var
	需编码字串表={
		'&':'&',
		'<':'<',
		'>':'>',
		'"':'"',
		"'":''',
		'/':'/',
		'`':'`',
		'=':'='
	},
	编码成文本=function(string){
		return String(string).replace(/[&<>"'`=\/]/g,function(s){
			return 需编码字串表[s];
		}).replace(/\n\r/g,function(s){
			return '\\n';
		})
	},
	编码成网页=function(string){
		return String(string);
		return String(string).replace(/"/g,function(s){
			return '\\'+s;
		});
	},
	编译模板=function(模板字串){
		var
		已打开的钥匙们=[],
		模板字串=模板字串
			.replace(/[\n\r\t]/g,'')
			.replace(/"/g,'\\"')
			.replace(/\{\{(#|\/|\^|&|\$)?(.+?)\}\}/g,function(整段文字,动作,管道){

			if(管道=='.')
				管道='$value';
			管道=管道.split('|');

			钥匙=管道.shift();

			var
			管道前,
			管道后,
			钥匙和管道;

			管道前=管道.join('(')+'(';

			管道后=[];
			管道后.length=管道.length;
			管道后=管道后.join(')')+')';

			钥匙和管道=管道前+钥匙+管道后;

			switch(动作){
				case '#':
					已打开的钥匙们.push(钥匙);

					return '");\
					(function(){\
						var $value;\
						var $key;\
						if( typeof('+钥匙+')!=="undefined" && '+钥匙+' && (钥匙='+钥匙和管道+'))\
						for($key in '+钥匙+')\
							with($value='+钥匙+'[$key]){\
							$return.push("';

					break;
				case '$':
					已打开的钥匙们.push(钥匙);

					return '");\
					(function(){\
						if( typeof('+钥匙+')!=="undefined" && '+钥匙+' ){\
							$return.push("';

					break;
				case '^':
					已打开的钥匙们.push(钥匙);

					return '");\
					(function(){\
						if( typeof('+钥匙+')==="undefined" || !'+钥匙+' ){\
							$return.push("';

					break;
				case '/':
					var
					长度=已打开的钥匙们.length+1;
					while(已打开的钥匙们[--长度]&&已打开的钥匙们[长度]!=钥匙);

					已打开的钥匙们.splice(长度,1);

					return '")\
						}\
					})();\
					$return.push("';

					break;
				case '&':

					return '");\
						if(typeof('+钥匙+')!=="undefined")\
							$return.push(模板.编码成网页('+钥匙和管道+'||\'\'));\
						\
						$return.push("';

					break;
				default:

					return '");\
						if(typeof('+钥匙+')!=="undefined")\
							$return.push(模板.编码成文本('+钥匙和管道+'||\'\'));\
						\
						$return.push("';

					break;
			}

		});

		模板字串='\
			var $return=[];\
			with($data){\
				$return.push("'+模板字串+'");\
			}\
			return $return.join(\'\');';

		return Function('$data',模板字串);
	},
	运转=function(模板字串,数据,作用域){
		return 编译模板(模板字串).call(作用域||上帝,数据);
	};

	上帝.模板={
		运转:运转,
		编译模板:编译模板,
		编码成文本:编码成文本,
		编码成网页:编码成网页,
	};

})(this);<commit_msg>修复 $ -> _<commit_after>(function(上帝){
	var
	需编码字串表={
		'&':'&',
		'<':'<',
		'>':'>',
		'"':'"',
		"'":''',
		'/':'/',
		'`':'`',
		'=':'='
	},
	编码成文本=function(string){
		return String(string).replace(/[&<>"'`=\/]/g,function(s){
			return 需编码字串表[s];
		}).replace(/\n\r/g,function(s){
			return '\\n';
		})
	},
	编码成网页=function(string){
		return String(string);
		return String(string).replace(/"/g,function(s){
			return '\\'+s;
		});
	},
	编译模板=function(模板字串){
		var
		已打开的钥匙们=[],
		模板字串=模板字串
			.replace(/[\n\r\t]/g,'')
			.replace(/"/g,'\\"')
			.replace(/\{\{(#|\/|\^|&|\$)?(.+?)\}\}/g,function(整段文字,动作,管道){

			if(管道=='.')
				管道='_value';
			管道=管道.split('|');

			钥匙=管道.shift();

			var
			管道前,
			管道后,
			钥匙和管道;

			管道前=管道.join('(')+'(';

			管道后=[];
			管道后.length=管道.length;
			管道后=管道后.join(')')+')';

			钥匙和管道=管道前+钥匙+管道后;

			switch(动作){
				case '#':
					已打开的钥匙们.push(钥匙);

					return '");\
					(function(){\
						var _value;\
						var _key;\
						if( typeof('+钥匙+')!=="undefined" && '+钥匙+' && (钥匙='+钥匙和管道+'))\
						for(_key in '+钥匙+')\
							with(_value='+钥匙+'[_key]){\
							$return.push("';

					break;
				case '$':
					已打开的钥匙们.push(钥匙);

					return '");\
					(function(){\
						if( typeof('+钥匙+')!=="undefined" && '+钥匙+' ){\
							$return.push("';

					break;
				case '^':
					已打开的钥匙们.push(钥匙);

					return '");\
					(function(){\
						if( typeof('+钥匙+')==="undefined" || !'+钥匙+' ){\
							$return.push("';

					break;
				case '/':
					var
					长度=已打开的钥匙们.length+1;
					while(已打开的钥匙们[--长度]&&已打开的钥匙们[长度]!=钥匙);

					已打开的钥匙们.splice(长度,1);

					return '")\
						}\
					})();\
					$return.push("';

					break;
				case '&':

					return '");\
						if(typeof('+钥匙+')!=="undefined")\
							$return.push(编码成网页('+钥匙和管道+'||\'\'));\
						\
						$return.push("';

					break;
				default:

					return '");\
						if(typeof('+钥匙+')!=="undefined")\
							$return.push(编码成文本('+钥匙和管道+'||\'\'));\
						\
						$return.push("';

					break;
			}

		});

		模板字串='\
			var $return=[];\
			with($data){\
				$return.push("'+模板字串+'");\
			}\
			return $return.join(\'\');';

		return Function('$data','编码成文本','编码成网页',模板字串);
	},
	运转=function(模板字串,数据,作用域){
		return 编译模板(模板字串).call(作用域||上帝,数据,编码成文本,编码成网页);
	};

	上帝.模板={
		运转:运转,
		编译模板:编译模板,
		编码成文本:编码成文本,
		编码成网页:编码成网页,
	};

})(this);
<|endoftext|>