<commit_before>SLED.render = function($parent, refOrName) {
	SLED.docChanged();
	// convert rule name to ref
	var ref = Ref.toRef(refOrName);
	var rule = SLED.grammar[ ref.name ];
	
	var isBlock = rule.content;
	var clzLayout = isBlock ? "type-block" : "type-value";
	var $obj = $('<div>')
		.addClass(clzLayout)
		.attr('rule-name', ref.name);
		
	var clzDepth = 'depth-even';
	if ($parent.parent().hasClass('depth-even')) {
		clzDepth = 'depth-odd';
	} 
	$obj.addClass(clzDepth);
	$parent.append($obj);	
	
	if (isBlock) {
		SLED.renderBlock($obj, ref);
	}
	else {
		SLED.renderValue($obj, ref);
	}
}
SLED.renderBlock = function($obj, ref) {
	var rule = SLED.grammar[ ref.name ];

	var $hdr = $('<div class="block-header">');
	var $title = $('<span class="block-name">').text( rule.title );
	$hdr.append( SLED.renderDelete($obj, ref, rule ));
	$hdr.append($title);
	
	var $menu = $('<div class="menu">');
	// contents
	var currChoiceGroup = null;
	for (var i = 0; i < rule.content.length; i++) {
		var refContent = rule.content[i];
		if (currChoiceGroup && currChoiceGroup != refContent.choiceGroup) {
			/*$('<span>').text(")").attr('menu-tag', currChoiceGroup )
				.appendTo($menu);*/
			currChoiceGroup = null;		
		}
		if (currChoiceGroup && currChoiceGroup == refContent.choiceGroup) {
			$('<span>').text("|").attr('menu-tag', refContent.choiceGroup)
				.appendTo($menu);
		}
		if (refContent.choiceGroup && ! currChoiceGroup) {
			/*$('<span>').text("(").attr('menu-tag', refContent.choiceGroup)
				.appendTo($menu);*/
			currChoiceGroup = refContent.choiceGroup;		
		}
		SLED.renderMenuRef($obj, $menu, refContent);
	}
	$hdr.append($menu);
	$obj.append($hdr);
	
	//render content markers in order
	for (var i = 0; i < rule.content.length; i++) {
		var refContent = rule.content[i];
		SLED.renderMarker( $obj, refContent );
	}
}
SLED.renderMenuRef = function($obj, $menu, ref) {
	var rule = SLED.grammar[ref.name];
	
	if (! rule) {
		console.log('Missing rule: ' + ref.name);
	}
	var isList = ref.mult[0] >= 0 && ref.mult[1] > 1;
	var isSingleton = ref.mult[1] == 1;
	
	var clz = "ctl-add";
	var title = rule.title + '*';
	if (isSingleton) { 
		clz = "ctl-option"; 
		title = rule.title;
	}
	
	var menuTag = ref.choiceGroup ? ref.choiceGroup : title;
	var $btn = $('<span>')
		.addClass("menu-item")
		.addClass(clz)
		.attr('menu-tag', menuTag)
		.text(title);
	$btn.click(function() {
		if (isSingleton) {
			$btn.hide();
		}
		if (ref.choiceGroup) {
			$menu.find('[menu-tag="' + ref.choiceGroup + '"]').hide();
		}
		SLED.render( SLED.findElement($menu.parent().parent(), ref.name), ref);
	});
	var isMand = ref.mult[0] > 0;
	if (isMand && isSingleton) { $btn.hide(); }

	$menu.append($btn);
}
SLED.renderDelete = function($obj, ref, rule) {
	var $del = null;
 
	if ( Ref.isOpt(ref) || Ref.isMany(ref) )  {
		var menuTag = ref.choiceGroup ? ref.choiceGroup : rule.title;
		$del = $('<span class="ctl-delete">').text('x');
		$del.click(function() {
			SLED.docChanged();
			SLED.menuShow($obj, menuTag );
			$obj.remove();
		});
	}
	return $del;
}
SLED.menuShow = function($obj, name) {
	var $p = $obj.parent().parent();
	var $menu = $p.find('.menu');
	$menu.find('[menu-tag="' + name + '"]').show();
}
SLED.renderValue = function($obj, ref) {
	var rule = SLED.grammar[ ref.name ];
	$obj.append( SLED.renderDelete($obj, ref, rule) );
	$obj.append( $('<span class="value-title">').text( rule.title ) );
		
	var $input = $('<input type="text" class="value-val">').appendTo($obj).focus();
	$input.bind('keyup', SLED.docChanged );

	if (rule.val) {
		$input.val(rule.val);
	}
	if (rule.size) {
		$input.attr('size', rule.size);
	}
	if (rule.type == 'color') {
		SLED.renderColor($obj, $input);
	}
}
SLED.renderColor = function($obj, $input) {
	var $clrInput = $('<input type="color">')
		.appendTo($obj);
	var $clr = $('<div class="color-swatch">')
		.css('background-color', $input.val() )
		.appendTo($obj);
	$input.bind('keyup change', function() {
		SLED.docChanged();
		var clr = $input.val();
		if (clr.length == 6) {
			$clr.css('background-color', clr);
			$clr.removeClass('color-error');
			$clrInput.val('#'+clr);
		}
		else {
			$clr.css('background-color', '');
			$clr.addClass('color-error');
		}
	});
	$clrInput.bind('change', function() {
		SLED.docChanged();
		var clr = $clrInput.val();
		$input.val(clr.substr(1));
		$clr.css('background-color', clr);
		$clr.removeClass('color-error');
	});
}
SLED.renderMarker = function($block, ref) {
	var rule = SLED.grammar[ref.name];
	var isMand = ref.mult[0] > 0;
	var clzMarker = 'element-'+ref.name;
	
	$('<div>').addClass(clzMarker).appendTo($block);

	if (Ref.isMand(ref) || Ref.isDefault(ref)) {
		SLED.render( SLED.findElement($block, ref.name), ref.name);
	}
}
SLED.findElement = function($e, name) {
	var elts = $e.find('.element-'+name + ':first');
	return elts;
}
SLED.expandVal = function(val, rule) {
	if (rule.type) {
		if (rule.type == 'color') {
			return val.startsWith('#') ? val : '#' + val;
		}
		if (rule.type == 'number') {<commit_msg>Force RGB output to uppercase<commit_after>SLED.render = function($parent, refOrName) {
	SLED.docChanged();
	// convert rule name to ref
	var ref = Ref.toRef(refOrName);
	var rule = SLED.grammar[ ref.name ];
	
	var isBlock = rule.content;
	var clzLayout = isBlock ? "type-block" : "type-value";
	var $obj = $('<div>')
		.addClass(clzLayout)
		.attr('rule-name', ref.name);
		
	var clzDepth = 'depth-even';
	if ($parent.parent().hasClass('depth-even')) {
		clzDepth = 'depth-odd';
	} 
	$obj.addClass(clzDepth);
	$parent.append($obj);	
	
	if (isBlock) {
		SLED.renderBlock($obj, ref);
	}
	else {
		SLED.renderValue($obj, ref);
	}
}
SLED.renderBlock = function($obj, ref) {
	var rule = SLED.grammar[ ref.name ];

	var $hdr = $('<div class="block-header">');
	var $title = $('<span class="block-name">').text( rule.title );
	$hdr.append( SLED.renderDelete($obj, ref, rule ));
	$hdr.append($title);
	
	var $menu = $('<div class="menu">');
	// contents
	var currChoiceGroup = null;
	for (var i = 0; i < rule.content.length; i++) {
		var refContent = rule.content[i];
		if (currChoiceGroup && currChoiceGroup != refContent.choiceGroup) {
			/*$('<span>').text(")").attr('menu-tag', currChoiceGroup )
				.appendTo($menu);*/
			currChoiceGroup = null;		
		}
		if (currChoiceGroup && currChoiceGroup == refContent.choiceGroup) {
			$('<span>').text("|").attr('menu-tag', refContent.choiceGroup)
				.appendTo($menu);
		}
		if (refContent.choiceGroup && ! currChoiceGroup) {
			/*$('<span>').text("(").attr('menu-tag', refContent.choiceGroup)
				.appendTo($menu);*/
			currChoiceGroup = refContent.choiceGroup;		
		}
		SLED.renderMenuRef($obj, $menu, refContent);
	}
	$hdr.append($menu);
	$obj.append($hdr);
	
	//render content markers in order
	for (var i = 0; i < rule.content.length; i++) {
		var refContent = rule.content[i];
		SLED.renderMarker( $obj, refContent );
	}
}
SLED.renderMenuRef = function($obj, $menu, ref) {
	var rule = SLED.grammar[ref.name];
	
	if (! rule) {
		console.log('Missing rule: ' + ref.name);
	}
	var isList = ref.mult[0] >= 0 && ref.mult[1] > 1;
	var isSingleton = ref.mult[1] == 1;
	
	var clz = "ctl-add";
	var title = rule.title + '*';
	if (isSingleton) { 
		clz = "ctl-option"; 
		title = rule.title;
	}
	
	var menuTag = ref.choiceGroup ? ref.choiceGroup : title;
	var $btn = $('<span>')
		.addClass("menu-item")
		.addClass(clz)
		.attr('menu-tag', menuTag)
		.text(title);
	$btn.click(function() {
		if (isSingleton) {
			$btn.hide();
		}
		if (ref.choiceGroup) {
			$menu.find('[menu-tag="' + ref.choiceGroup + '"]').hide();
		}
		SLED.render( SLED.findElement($menu.parent().parent(), ref.name), ref);
	});
	var isMand = ref.mult[0] > 0;
	if (isMand && isSingleton) { $btn.hide(); }

	$menu.append($btn);
}
SLED.renderDelete = function($obj, ref, rule) {
	var $del = null;
 
	if ( Ref.isOpt(ref) || Ref.isMany(ref) )  {
		var menuTag = ref.choiceGroup ? ref.choiceGroup : rule.title;
		$del = $('<span class="ctl-delete">').text('x');
		$del.click(function() {
			SLED.docChanged();
			SLED.menuShow($obj, menuTag );
			$obj.remove();
		});
	}
	return $del;
}
SLED.menuShow = function($obj, name) {
	var $p = $obj.parent().parent();
	var $menu = $p.find('.menu');
	$menu.find('[menu-tag="' + name + '"]').show();
}
SLED.renderValue = function($obj, ref) {
	var rule = SLED.grammar[ ref.name ];
	$obj.append( SLED.renderDelete($obj, ref, rule) );
	$obj.append( $('<span class="value-title">').text( rule.title ) );
		
	var $input = $('<input type="text" class="value-val">').appendTo($obj).focus();
	$input.bind('keyup', SLED.docChanged );

	if (rule.val) {
		$input.val(rule.val);
	}
	if (rule.size) {
		$input.attr('size', rule.size);
	}
	if (rule.type == 'color') {
		SLED.renderColor($obj, $input);
	}
}
SLED.renderColor = function($obj, $input) {
	var $clrInput = $('<input type="color">')
		.appendTo($obj);
	var $clr = $('<div class="color-swatch">')
		.css('background-color', $input.val() )
		.appendTo($obj);
	$input.bind('keyup change', function() {
		SLED.docChanged();
		var clr = $input.val();
		if (clr.length == 6) {
			$clr.css('background-color', clr);
			$clr.removeClass('color-error');
			$clrInput.val('#'+clr);
		}
		else {
			$clr.css('background-color', '');
			$clr.addClass('color-error');
		}
	});
	$clrInput.bind('change', function() {
		SLED.docChanged();
		var clr = $clrInput.val();
		$input.val(clr.substr(1));
		$clr.css('background-color', clr);
		$clr.removeClass('color-error');
	});
}
SLED.renderMarker = function($block, ref) {
	var rule = SLED.grammar[ref.name];
	var isMand = ref.mult[0] > 0;
	var clzMarker = 'element-'+ref.name;
	
	$('<div>').addClass(clzMarker).appendTo($block);

	if (Ref.isMand(ref) || Ref.isDefault(ref)) {
		SLED.render( SLED.findElement($block, ref.name), ref.name);
	}
}
SLED.findElement = function($e, name) {
	var elts = $e.find('.element-'+name + ':first');
	return elts;
}
SLED.expandVal = function(val, rule) {
	if (rule.type) {
		if (rule.type == 'color') {
			return val.startsWith('#') ? val.toUpperCase() : '#' + val.toUpperCase();
		}
		if (rule.type == 'number') {
{'fraction_non_alphanumeric': 0.2218700475435816, 'fraction_numerical': 0.0027733755942947703, 'mean_word_length': 3.932584269662921, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6084249', 'n_tokens_mistral': 4168, 'n_tokens_neox': 3908, 'n_words': 722}