<commit_before>(function (Q, $, window, undefined) {
/**
 * Assets/service/preview tool.
 * Renders a tool to preview services
 * @class Assets/service/preview
 * @constructor
 * @param {Object} [options] options to pass besides the ones to Streams/preview tool
 */
Q.Tool.define("Assets/service/preview", ["Streams/preview"], function(options, preview) {
	var tool = this;
	tool.preview = preview;

	Q.addStylesheet('{{Assets}}/css/tools/ServicePreview.css', { slotName: 'Assets' });

	preview.state.creatable.preprocess = function (_proceed) {
		tool.openDialog(function (dialog) {
			Q.handle(_proceed, preview, [{
				title: $("input[name=title]", dialog).val(),
				content: $("textarea[name=description]", dialog).val(),
				attributes: {
					price: $("input[name=price]", dialog).val(),
					link: $("input[name=link]", dialog).val(),
					payment: $("select[name=payment]", dialog).val()
				}
			}]);
		}, function () {
			Q.handle(_proceed, preview, [false]);
		});
	};

	Q.Text.get('Assets/content', function (err, text) {
		var msg = Q.firstErrorMessage(err);
		if (msg) {
			return console.warn(msg);
		}

		tool.text = text;

		preview.state.onRefresh.add(tool.refresh.bind(tool));
	});
},

{

},

{
	refresh: function (stream, callback) {
		var tool = this;
		tool.stream = stream;
		var ps = tool.preview.state;
		var $toolElement = $(tool.element);

		$toolElement.attr('data-writeLevel', stream.testWriteLevel('edit'));

		Q.Template.render('Assets/service/preview', {
			title: stream.fields.title,
			price: '($' + parseFloat(stream.getAttribute('price')).toFixed(2) + ')',
			editable: ps.editable
		}, function (err, html) {
			if (err) return;
			tool.element.innerHTML = html;

			tool.preview.icon($("img.Streams_preview_icon", tool.element)[0]);

			$("i.icon-edit", tool.element).on(Q.Pointer.fastclick, function (e) {
				e.stopImmediatePropagation();
				tool.edit();
				return false;
			});
		});

		Q.Streams.Stream.onFieldChanged(ps.publisherId, ps.streamName)
		.set(function (fields, changed) {
			if (changed.title) {
				tool.$('.Streams_preview_title').html(changed.title);
			}
		}, tool);

		Q.Streams.Stream.onAttribute(ps.publisherId, ps.streamName, "price")
		.set(function (attributes, k) {
			var price = parseFloat(attributes[k]).toFixed(2);
			$("span.Assets_service_preview_price", tool.element).html("($" + price + ")");
		}, tool);
	},
	edit: function () {
		var tool = this;
		var previewState = this.preview.state;

		Q.Streams.get(previewState.publisherId, previewState.streamName, function () {
			var stream = this;
			if (!stream.testWriteLevel('edit')) {
				return;
			}

			tool.openDialog(function (dialog) {
				stream.pendingFields.title = $("input[name=title]", dialog).val();
				stream.pendingFields.content = $("textarea[name=description]", dialog).val();
				stream.setAttribute('payment', $("select[name=payment]", dialog).val());
				stream.setAttribute('price', $("input[name=price]", dialog).val());
				stream.setAttribute('link', $("input[name=link]", dialog).val());
				stream.save({
					onSave: function () {
						stream.refresh();
					}
				});
			}, null, {
				title: stream.fields.title,
				payment: stream.getAttribute('payment'),
				price: stream.getAttribute('price'),
				link: stream.getAttribute('link'),
				description: stream.fields.content
			});
		});
	},
	openDialog: function (saveCallback, closeCallback, fields) {
		var tool = this;

		Q.Dialogs.push({
			title: Q.getObject("services.NewServiceTemplate.Title", tool.text) || "New Service Template",
			template: {
				name: "Assets/service/composer",
				fields: Q.extend({text: tool.text}, fields)
			},
			className: "Assets_service_composer",
			onActivate: function (dialog) {
				$("input,textarea", dialog).plugin('Q/placeholders');

				var $price = $("label[for=price]", dialog);
				var payment = Q.getObject("payment", fields) || 'free';
				if (payment === 'free') {
					$price.hide();
				}

				var $payment = $("select[name=payment]", dialog).on('change', function () {
					if ($payment.val() === 'free') {
						$price.hide();
					} else {
						$price.show();
					}
				});

				$payment.val(payment);

				$("button[name=save]", dialog).on(Q.Pointer.fastclick, function () {
					var $form = $(this).closest("form");
					var valid = true;

					Q.each(['title', 'price', 'description'], function (i, value) {
						var $item = $("input[name=" + value + "]", $form);

						if ($item.attr('required') && !$item.val()) {
							$item.addClass('Q_error');
							valid = false;
						} else {
							$item.removeClass('Q_error');
						}
					});

					if (!valid) {
						return false;
					}

					Q.handle(saveCallback, dialog, [dialog]);<commit_msg>Fixed Assets/service/preview tool. Allow to add/edit free events.<commit_after>(function (Q, $, window, undefined) {
/**
 * Assets/service/preview tool.
 * Renders a tool to preview services
 * @class Assets/service/preview
 * @constructor
 * @param {Object} [options] options to pass besides the ones to Streams/preview tool
 */
Q.Tool.define("Assets/service/preview", ["Streams/preview"], function(options, preview) {
	var tool = this;
	tool.preview = preview;

	Q.addStylesheet('{{Assets}}/css/tools/ServicePreview.css', { slotName: 'Assets' });

	preview.state.creatable.preprocess = function (_proceed) {
		tool.openDialog(function (dialog) {
			Q.handle(_proceed, preview, [{
				title: $("input[name=title]", dialog).val(),
				content: $("textarea[name=description]", dialog).val(),
				attributes: {
					price: $("input[name=price]", dialog).val(),
					link: $("input[name=link]", dialog).val(),
					payment: $("select[name=payment]", dialog).val()
				}
			}]);
		}, function () {
			Q.handle(_proceed, preview, [false]);
		});
	};

	Q.Text.get('Assets/content', function (err, text) {
		var msg = Q.firstErrorMessage(err);
		if (msg) {
			return console.warn(msg);
		}

		tool.text = text;

		preview.state.onRefresh.add(tool.refresh.bind(tool));
	});
},

{

},

{
	refresh: function (stream, callback) {
		var tool = this;
		tool.stream = stream;
		var ps = tool.preview.state;
		var $toolElement = $(tool.element);

		$toolElement.attr('data-writeLevel', stream.testWriteLevel('edit'));
		var price = stream.getAttribute('price');

		Q.Template.render('Assets/service/preview', {
			title: stream.fields.title,
			price: price ? '($' + parseFloat(price).toFixed(2) + ')' : '',
			editable: ps.editable
		}, function (err, html) {
			if (err) return;
			tool.element.innerHTML = html;

			tool.preview.icon($("img.Streams_preview_icon", tool.element)[0]);

			$("i.icon-edit", tool.element).on(Q.Pointer.fastclick, function (e) {
				e.stopImmediatePropagation();
				tool.edit();
				return false;
			});
		});

		Q.Streams.Stream.onFieldChanged(ps.publisherId, ps.streamName)
		.set(function (fields, changed) {
			if (changed.title) {
				tool.$('.Streams_preview_title').html(changed.title);
			}
		}, tool);

		Q.Streams.Stream.onAttribute(ps.publisherId, ps.streamName, "price")
		.set(function (attributes, k) {
			var price = parseFloat(attributes[k]);
			price = price ? "($" + price.toFixed(2) + ")" : '';
			$("span.Assets_service_preview_price", tool.element).html(price);
		}, tool);
	},
	edit: function () {
		var tool = this;
		var previewState = this.preview.state;

		Q.Streams.get(previewState.publisherId, previewState.streamName, function () {
			var stream = this;
			if (!stream.testWriteLevel('edit')) {
				return;
			}

			tool.openDialog(function (dialog) {
				stream.pendingFields.title = $("input[name=title]", dialog).val();
				stream.pendingFields.content = $("textarea[name=description]", dialog).val();
				stream.setAttribute('payment', $("select[name=payment]", dialog).val());
				stream.setAttribute('price', $("input[name=price]", dialog).val());
				stream.setAttribute('link', $("input[name=link]", dialog).val());
				stream.save({
					onSave: function () {
						stream.refresh();
					}
				});
			}, null, {
				title: stream.fields.title,
				payment: stream.getAttribute('payment'),
				price: stream.getAttribute('price'),
				link: stream.getAttribute('link'),
				description: stream.fields.content
			});
		});
	},
	openDialog: function (saveCallback, closeCallback, fields) {
		var tool = this;

		Q.Dialogs.push({
			title: Q.getObject("services.NewServiceTemplate.Title", tool.text) || "New Service Template",
			template: {
				name: "Assets/service/composer",
				fields: Q.extend({text: tool.text}, fields)
			},
			className: "Assets_service_composer",
			onActivate: function (dialog) {
				$("input,textarea", dialog).plugin('Q/placeholders');

				var $price = $("label[for=price]", dialog);
				var payment = Q.getObject("payment", fields) || 'free';
				if (payment === 'free') {
					$price.hide();
				}

				var $payment = $("select[name=payment]", dialog).on('change', function () {
					if ($payment.val() === 'free') {
						$("input[name=price]", $price).val('');
						$price.hide();
					} else {
						$price.show();
					}
				});

				$payment.val(payment);

				$("button[name=save]", dialog).on(Q.Pointer.fastclick, function () {
					var $form = $(this).closest("form");
					var valid = true;

					Q.each(['title', 'price', 'description'], function (i, value) {
						var $item = $("input[name=" + value + "]", $form);

						if ($item.is(":visible") && $item.attr('required') && !$item.val()) {
							$item.addClass('Q_error');
							valid = false;
						} else {
							$item.removeClass('Q_error');
						}
					});

					if (!valid) {
						return false;
					}

					Q.handle(saveCallback, dialog, [dialog]);
{'fraction_non_alphanumeric': 0.1932537623248573, 'fraction_numerical': 0.0006227296315516347, 'mean_word_length': 3.6618287373004352, 'pattern_counts': {'":': 1, '<': 3, '<?xml version=': 0, '>': 3, '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': '7387561', 'n_tokens_mistral': 3756, 'n_tokens_neox': 3118, 'n_words': 579}