text:
import { localize } from 'vs/nls';
import { Emitter } from 'vs/base/common/event';
import { URI } from 'vs/base/common/uri';
import { assertIsDefined, withNullAsUndefined } from 'vs/base/common/types';
import { EncodingMode, ITextFileService, TextFileEditorModelState, ITextFileEditorModel, ITextFileStreamContent, ITextFileResolveOptions, IResolvedTextFileEditorModel, ITextFileSaveOptions, TextFileResolveReason, ITextFileEditorModelSaveEvent } from 'vs/workbench/services/textfile/common/textfiles';
import { IRevertOptions, SaveReason, SaveSourceRegistry } from 'vs/workbench/common/editor';
import { BaseTextEditorModel } from 'vs/workbench/common/editor/textEditorModel';
import { IWorkingCopyBackupService, IResolvedWorkingCopyBackup } from 'vs/workbench/services/workingCopy/common/workingCopyBackup';
import { IFileService, FileOperationError, FileOperationResult, FileChangesEvent, FileChangeType, IFileStatWithMetadata, ETAG_DISABLED, FileSystemProviderCapabilities, NotModifiedSinceFileOperationError } from 'vs/platform/files/common/files';
import { ILanguageService } from 'vs/editor/common/languages/language';
import { IModelService } from 'vs/editor/common/services/model';
import { timeout, TaskSequentializer } from 'vs/base/common/async';
import { ITextBufferFactory, ITextModel } from 'vs/editor/common/model';
import { ILogService } from 'vs/platform/log/common/log';
import { basename } from 'vs/base/common/path';
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
import { IWorkingCopyBackup, WorkingCopyCapabilities, NO_TYPE_ID, IWorkingCopyBackupMeta } from 'vs/workbench/services/workingCopy/common/workingCopy';
import { IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { ILabelService } from 'vs/platform/label/common/label';
import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cancellation';
import { UTF16be, UTF16le, UTF8, UTF8_with_bom } from 'vs/workbench/services/textfile/common/encoding';
import { createTextBufferFactoryFromStream } from 'vs/editor/common/model/textModel';
import { ILanguageDetectionService } from 'vs/workbench/services/languageDetection/common/languageDetectionWorkerService';
import { IPathService } from 'vs/workbench/services/path/common/pathService';
import { extUri } from 'vs/base/common/resources';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';

interface IBackupMetaData extends IWorkingCopyBackupMeta {
	mtime: number;
	ctime: number;
	size: number;
	etag: string;
	orphaned: boolean;
}

/**
 * The text file editor model listens to changes to its underlying code editor model and saves these changes through the file service back to the disk.
 */
export class TextFileEditorModel extends BaseTextEditorModel implements ITextFileEditorModel {

	private static readonly TEXTFILE_SAVE_ENCODING_SOURCE = SaveSourceRegistry.registerSource('textFileEncoding.source', localize('textFileCreate.source', "File Encoding Changed"));

	//#region Events

	private readonly _onDidChangeContent = this._register(new Emitter<void>());
	readonly onDidChangeContent = this._onDidChangeContent.event;

	private readonly _onDidResolve = this._register(new Emitter<TextFileResolveReason>());
	readonly onDidResolve = this._onDidResolve.event;

	private readonly _onDidChangeDirty = this._register(new Emitter<void>());
	readonly onDidChangeDirty = this._onDidChangeDirty.event;

	private readonly _onDidSaveError = this._register(new Emitter<void>());
	readonly onDidSaveError = this._onDidSaveError.event;

	private readonly _onDidSave = this._register(new Emitter<ITextFileEditorModelSaveEvent>());
	readonly onDidSave = this._onDidSave.event;

	private readonly _onDidRevert = this._register(new Emitter<void>());
	readonly onDidRevert = this._onDidRevert.event;

	private readonly _onDidChangeEncoding = this._register(new Emitter<void>());
	readonly onDidChangeEncoding = this._onDidChangeEncoding.event;

	private readonly _onDidChangeOrphaned = this._register(new Emitter<void>());
	readonly onDidChangeOrphaned = this._onDidChangeOrphaned.event;

	private readonly _onDidChangeReadonly = this._register(new Emitter<void>());
	readonly onDidChangeReadonly = this._onDidChangeReadonly.event;

	//#endregion

	readonly typeId = NO_TYPE_ID; // IMPORTANT: never change this to not break existing assumptions (e.g. backups)

	readonly capabilities = WorkingCopyCapabilities.None;

	readonly name = basename(this.labelService.getUriLabel(this.resource));
	private resourceHasExtension: boolean = !!extUri.extname(this.resource);

	private contentEncoding: string | undefined; // encoding as reported from disk

	private versionId = 0;
	private bufferSavedVersionId: number | undefined;
	private ignoreDirtyOnModelContentChange = false;

	private static readonly UNDO_REDO_SAVE_PARTICIPANTS_AUTO_SAVE_THROTTLE_THRESHOLD = 500;
	private lastModelContentChangeFromUndoRedo: number | undefined = undefined;

	private lastResolvedFileStat: IFileStatWithMetadata | undefined;

	private readonly saveSequentializer = new TaskSequentializer();

	private dirty = false;
	private inConflictMode = false;
	private inOrphanMode = false;
	private inErrorMode = false;

	constructor(
		readonly resource: URI,
		private preferredEncoding: string | undefined,		// encoding as chosen by the user
		private preferredLanguageId: string | undefined,	// language id as chosen by the user
		@ILanguageService languageService: ILanguageService,
		@IModelService modelService: IModelService,
		@IFileService private readonly fileService: IFileService,
		@ITextFileService private readonly textFileService: ITextFileService,
		@IWorkingCopyBackupService private readonly workingCopyBackupService: IWorkingCopyBackupService,
		@ILogService private readonly logService: ILogService,
		@IWorkingCopyService private readonly workingCopyService: IWorkingCopyService,
		@IFilesConfigurationService private readonly filesConfigurationService: IFilesConfigurationService,
		@ILabelService private readonly labelService: ILabelService,
		@ILanguageDetectionService languageDetectionService: ILanguageDetectionService,
		@IAccessibilityService accessibilityService: IAccessibilityService,
		@IPathService private readonly pathService: IPathService,
		@IExtensionService private readonly extensionService: IExtensionService
	) {
		super(modelService, languageService, languageDetectionService, accessibilityService);

		// Make known to working copy service
		this._register(this.workingCopyService.registerWorkingCopy(this));

		this.registerListeners();
	}

	private registerListeners(): void {
		this._register(this.fileService.onDidFilesChange(e => this.onDidFilesChange(e)));
		this._register(this.filesConfigurationService.onFilesAssociationChange(() => this.onFilesAssociationChange()));
	}

	private async onDidFilesChange(e: FileChangesEvent): Promise<void> {
		let fileEventImpactsModel = false;
		let newInOrphanModeGuess: boolean | undefined;

		// If we are currently orphaned, we check if the model file was added back
		if (this.inOrphanMode) {
			const modelFileAdded = e.contains(this.resource, FileChangeType.ADDED);
			if (modelFileAdded) {
				newInOrphanModeGuess = false;
				fileEventImpactsModel = true;
			}
		}

		// Otherwise we check if the model file was deleted
		else {
			const modelFileDeleted = e.contains(this.resource, FileChangeType.DELETED);
			if (modelFileDeleted) {
				newInOrphanModeGuess = true;
				fileEventImpactsModel = true;
			}
		}

		if (fileEventImpactsModel && this.inOrphanMode !== newInOrphanModeGuess) {
			let newInOrphanModeValidated: boolean = false;
			if (newInOrphanModeGuess) {
				// We have received reports of users seeing delete events even though the file still
				// exists (network shares issue: https://github.com/microsoft/vscode/issues/13665).
				// Since we do not want to mark the model as orphaned, we have to check if the
				// file is really gone and not just a faulty file event.
				await timeout(100);

				if (this.isDisposed()) {
					newInOrphanModeValidated = true;
				} else {
					const exists = await this.fileService.exists(this.resource);
					newInOrphanModeValidated = !exists;
				}
			}

			if (this.inOrphanMode !== newInOrphanModeValidated && !this.isDisposed()) {
				this.setOrphaned(newInOrphanModeValidated);
			}
		}
	}

	private setOrphaned(orphaned: boolean): void {
		if (this.inOrphanMode !== orphaned) {
			this.inOrphanMode = orphaned;
			this._onDidChangeOrphaned.fire();
		}
	}

	private onFilesAssociationChange(): void {
		if (!this.isResolved()) {
			return;
		}

		const firstLineText = this.getFirstLineText(this.textEditorModel);
		const languageSelection = this.getOrCreateLanguage(this.resource, this.languageService, this.preferredLanguageId, firstLineText);

		this.modelService.setMode(this.textEditorModel, languageSelection);
	}

	override setLanguageId(languageId: string): void {
		super.setLanguageId(languageId);

		this.preferredLanguageId = languageId;
	}

	//#region Backup

	async backup(token: CancellationToken): Promise<IWorkingCopyBackup> {

		// Fill in metadata if we are resolved
		let meta: IBackupMetaData | undefined = undefined;
		if (this.lastResolvedFileStat) {
			meta = {
				mtime: this.lastResolvedFileStat.mtime,
				ctime: this.lastResolvedFileStat.ctime,
				size: this.lastResolvedFileStat.size,
				etag: this.lastResolvedFileStat.etag,
				orphaned: this.inOrphanMode
			};
		}

		// Fill in content the same way we would do when
		// saving the file via the text file service
		// encoding support (hardcode UTF-8)
		const content = await this.textFileService.getEncodedReadable(this.resource, withNullAsUndefined(this.createSnapshot()), { encoding: UTF8 });

		return { meta, content };
	}

	//#endregion

	//#region Revert

	async revert(options?: IRevertOptions): Promise<void> {
		if (!this.isResolved()) {
			return;
		}

		// Unset flags
		const wasDirty = this.dirty;
		const undo = this.doSetDirty(false);

		// Force read from disk unless reverting soft
		const softUndo = options?.soft;
		if (!softUndo) {
			try {
				await this.forceResolveFromFile();
			} catch (error) {

				// FileNotFound means the file got deleted meanwhile, so ignore it
				if ((<FileOperationError>error).fileOperationResult !== FileOperationResult.FILE_NOT_FOUND) {

					// Set flags back to previous values, we are still dirty if revert failed
					undo();

					throw error;
				}
			}
		}

		// Emit file change event
		this._onDidRevert.fire();

		// Emit dirty change event
		if (wasDirty) {
			this._onDidChangeDirty.fire();
		}
	}

	//#endregion

	//#region Resolve

	override async resolve(options?: ITextFileResolveOptions): Promise<void> {
		this.trace('resolve() - enter');

		// Return early if we are disposed
		if (this.isDisposed()) {
			this.trace('resolve() - exit - without resolving because model is disposed');

			return;
		}

		// Unless there are explicit contents provided, it is important that we do not
		// resolve a model that is dirty or is in the process of saving to prevent data
		// loss.
		if (!options?.contents && (this.dirty || this.saveSequentializer.hasPending())) {
			this.trace('resolve() - exit - without resolving because model is dirty or being saved');

			return;
		}

		return this.doResolve(options);
	}

	private async doResolve(options?: ITextFileResolveOptions): Promise<void> {

		// First check if we have contents to use for the model
		if (options?.contents) {
			return this.resolveFromBuffer(options.contents, options);
		}

		// Second, check if we have a backup to resolve from (only for new models)
		const isNewModel = !this.isResolved();
		if (isNewModel) {
			const resolvedFromBackup = await this.resolveFromBackup(options);
			if (resolvedFromBackup) {
				return;
			}
		}

		// Finally, resolve from file resource
		return this.resolveFromFile(options);
	}

	private async resolveFromBuffer(buffer: ITextBufferFactory, options?: ITextFileResolveOptions): Promise<void> {
		this.trace('resolveFromBuffer()');

		// Try to resolve metdata from disk
		let mtime: number;
		let ctime: number;
		let size: number;
		let etag: string;
		try {
			const metadata = await this.fileService.stat(this.resource);
			mtime = metadata.mtime;
			ctime = metadata.ctime;
			size = metadata.size;
			etag = metadata.etag;

			// Clear orphaned state when resolving was successful
			this.setOrphaned(false);
		} catch (error) {

			// Put some fallback values in error case
			mtime = Date.now();
			ctime = Date.now();
			size = 0;
			etag = ETAG_DISABLED;

			// Apply orphaned state based on error code
			this.setOrphaned(error.fileOperationResult === FileOperationResult.FILE_NOT_FOUND);
		}

		const preferredEncoding = await this.textFileService.encoding.getPreferredWriteEncoding(this.resource, this.preferredEncoding);

		// Resolve with buffer
		this.resolveFromContent({
			resource: this.resource,
			name: this.name,
			mtime,
			ctime,
			size,
			etag,
			value: buffer,
			encoding: preferredEncoding.encoding,
			readonly: false
		}, true /* dirty (resolved from buffer) */, options);
	}

	private async resolveFromBackup(options?: ITextFileResolveOptions): Promise<boolean> {

		// Resolve backup if any
		const backup = await this.workingCopyBackupService.resolve<IBackupMetaData>(this);

		// Resolve preferred encoding if we need it
		let encoding = UTF8;
		if (backup) {
			encoding = (await this.textFileService.encoding.getPreferredWriteEncoding(this.resource, this.preferredEncoding)).encoding;
		}

		// Abort if someone else managed to resolve the model by now
		const isNewModel = !this.isResolved();
		if (!isNewModel) {
			this.trace('resolveFromBackup() - exit - without resolving because previously new model got created meanwhile');

			return true; // imply that resolving has happened in another operation
		}

		// Try to resolve from backup if we have any
		if (backup) {
			await this.doResolveFromBackup(backup, encoding, options);

			return true;
		}

		// Otherwise signal back that resolving did not happen
		return false;
	}

	private async doResolveFromBackup(backup: IResolvedWorkingCopyBackup<IBackupMetaData>, encoding: string, options?: ITextFileResolveOptions): Promise<void> {
		this.trace('doResolveFromBackup()');

		// Resolve with backup
		this.resolveFromContent({
			resource: this.resource,
			name: this.name,
			mtime: backup.meta ? backup.meta.mtime : Date.now(),
			ctime: backup.meta ? backup.meta.ctime : Date.now(),
			size: backup.meta ? backup.meta.size : 0,
			etag: backup.meta ? backup.meta.etag : ETAG_DISABLED, // etag disabled if unknown!
			value: await createTextBufferFactoryFromStream(await this.textFileService.getDecodedStream(this.resource, backup.value, { encoding: UTF8 })),
			encoding,
			readonly: false
		}, true /* dirty (resolved from backup) */, options);

		// Restore orphaned flag based on state
		if (backup.meta?.orphaned) {
			this.setOrphaned(true);
		}
	}

	private async resolveFromFile(options?: ITextFileResolveOptions): Promise<void> {
		this.trace('resolveFromFile()');

		const forceReadFromFile = options?.forceReadFromFile;
		const allowBinary = this.isResolved() /* always allow if we resolved previously */ || options?.allowBinary;

		// Decide on etag
		let etag: string | undefined;
		if (forceReadFromFile) {
			etag = ETAG_DISABLED; // disable ETag if we enforce to read from disk
		} else if (this.lastResolvedFileStat) {
			etag = this.lastResolvedFileStat.etag; // otherwise respect etag to support caching
		}

		// Remember current version before doing any long running operation
		// to ensure we are not changing a model that was changed meanwhile
		const currentVersionId = this.versionId;

		// Resolve Content
		try {
			const content = await this.textFileService.readStream(this.resource, { acceptTextOnly: !allowBinary, etag, encoding: this.preferredEncoding });

			// Clear orphaned state when resolving was successful
			this.setOrphaned(false);

			// Return early if the model content has changed
			// meanwhile to prevent loosing any changes
			if (currentVersionId !== this.versionId) {
				this.trace('resolveFromFile() - exit - without resolving because model content changed');

				return;
			}

			return this.resolveFromContent(content, false /* not dirty (resolved from file) */, options);
		} catch (error) {
			const result = error.fileOperationResult;

			// Apply orphaned state based on error code
			this.setOrphaned(result === FileOperationResult.FILE_NOT_FOUND);

			// NotModified status is expected and can be handled gracefully
			// if we are resolved. We still want to update our last resolved
			// stat to e.g. detect changes to the file's readonly state
			if (this.isResolved() && result === FileOperationResult.FILE_NOT_MODIFIED_SINCE) {
				if (error instanceof NotModifiedSinceFileOperationError) {
					this.updateLastResolvedFileStat(error.stat);
				}

				return;
			}

			// Unless we are forced to read from the file, Ignore when a model has been resolved once
			// and the file was deleted meanwhile. Since we already have the model resolved, we can return
			// to this state and update the orphaned flag to indicate that this model has no version on
			// disk anymore.
			if (this.isResolved() && result === FileOperationResult.FILE_NOT_FOUND && !forceReadFromFile) {
				return;
			}

			// Otherwise bubble up the error
			throw error;
		}
	}

	private resolveFromContent(content: ITextFileStreamContent, dirty: boolean, options?: ITextFileResolveOptions): void {
		this.trace('resolveFromContent() - enter');

		// Return early if we are disposed
		if (this.isDisposed()) {
			this.trace('resolveFromContent() - exit - because model is disposed');

			return;
		}

		// Update our resolved disk stat model
		this.updateLastResolvedFileStat({
			resource: this.resource,
			name: content.name,
			mtime: content.mtime,
			ctime: content.ctime,
			size: content.size,
			etag: content.etag,
			readonly: content.readonly,
			isFile: true,
			isDirectory: false,
			isSymbolicLink: false,
			children: undefined
		});

		// Keep the original encoding to not loose it when saving
		const oldEncoding = this.contentEncoding;
		this.contentEncoding = content.encoding;

		// Handle events if encoding changed
		if (this.preferredEncoding) {
			this.updatePreferredEncoding(this.contentEncoding); // make sure to reflect the real encoding of the file (never out of sync)
		} else if (oldEncoding !== this.contentEncoding) {
			this._onDidChangeEncoding.fire();
		}

		// Update Existing Model
		if (this.textEditorModel) {
			this.doUpdateTextModel(content.value);
		}

		// Create New Model
		else {
			this.doCreateTextModel(content.resource, content.value);
		}

		// Update model dirty flag. This is very important to call
		// in both cases of dirty or not because it conditionally
		// updates the `bufferSavedVersionId` to determine the
		// version when to consider the model as saved again (e.g.
		// when undoing back to the saved state)
		this.setDirty(!!dirty);

		// Emit as event
		this._onDidResolve.fire(options?.reason ?? TextFileResolveReason.OTHER);
	}

	private doCreateTextModel(resource: URI, value: ITextBufferFactory): void {
		this.trace('doCreateTextModel()');

		// Create model
		const textModel = this.createTextEditorModel(value, resource, this.preferredLanguageId);

		// Model Listeners
		this.installModelListeners(textModel);

		// Detect language from content
		this.autoDetectLanguage();
	}

	private doUpdateTextModel(value: ITextBufferFactory): void {
		this.trace('doUpdateTextModel()');

		// Update model value in a block that ignores content change events for dirty tracking
		this.ignoreDirtyOnModelContentChange = true;
		try {
			this.updateTextEditorModel(value, this.preferredLanguageId);
		} finally {
			this.ignoreDirtyOnModelContentChange = false;
		}
	}

	private installModelListeners(model: ITextModel): void {

		// See https://github.com/microsoft/vscode/issues/30189
		// This code has been extracted to a different method because it caused a memory leak
		// where `value` was captured in the content change listener closure scope.

		// Listen to text model events
		this._register(model.onDidChangeContent(e => this.onModelContentChanged(model, e.isUndoing || e.isRedoing)));
		this._register(model.onDidChangeLanguage(() => this.onMaybeShouldChangeEncoding())); // detect possible encoding change via language specific settings
	}

	private onModelContentChanged(model: ITextModel, isUndoingOrRedoing: boolean): void {
		this.trace(`onModelContentChanged() - enter`);

		// In any case increment the version id because it tracks the textual content state of the model at all times
		this.versionId++;
		this.trace(`onModelContentChanged() - new versionId ${this.versionId}`);

		// Remember when the user changed the model through a undo/redo operation.
		// We need this information to throttle save participants to fix
		// https://github.com/microsoft/vscode/issues/102542
		if (isUndoingOrRedoing) {
			this.lastModelContentChangeFromUndoRedo = Date.now();
		}

		// We mark check for a dirty-state change upon model content change, unless:
		// - explicitly instructed to ignore it (e.g. from model.resolve())
		// - the model is readonly (in that case we never assume the change was done by the user)
		if (!this.ignoreDirtyOnModelContentChange && !this.isReadonly()) {

			// The contents changed as a matter of Undo and the version reached matches the saved one
			// In this case we clear the dirty flag and emit a SAVED event to indicate this state.
			if (model.getAlternativeVersionId() === this.bufferSavedVersionId) {
				this.trace('onModelContentChanged() - model content changed back to last saved version');

				// Clear flags
				const wasDirty = this.dirty;
				this.setDirty(false);

				// Emit revert event if we were dirty
				if (wasDirty) {
					this._onDidRevert.fire();
				}
			}

			// Otherwise the content has changed and we signal this as becoming dirty
			else {
				this.trace('onModelContentChanged() - model content changed and marked as dirty');

				// Mark as dirty
				this.setDirty(true);
			}
		}

		// Emit as event
		this._onDidChangeContent.fire();

		// Detect language from content
		this.autoDetectLanguage();
	}

	protected override async autoDetectLanguage(): Promise<void> {

		// Wait to be ready to detect language
		await this.extensionService?.whenInstalledExtensionsRegistered();

		// Only perform language detection conditionally
		const languageId = this.getLanguageId();
		if (
			this.resource.scheme === this.pathService.defaultUriScheme &&	// make sure to not detect language for non-user visible documents
			(!languageId || languageId === PLAINTEXT_LANGUAGE_ID) &&		// only run on files with plaintext language set or no language set at all
			!this.resourceHasExtension										// only run if this particular file doesn't have an extension
		) {
			return super.autoDetectLanguage();
		}
	}

	private async forceResolveFromFile(): Promise<void> {
		if (this.isDisposed()) {
			return; // return early when the model is invalid
		}

		// We go through the text file service to make
		// sure this kind of `resolve` is properly
		// running in sequence with any other running
		// `resolve` if any, including subsequent runs
		// that are triggered right after.

		await this.textFileService.files.resolve(this.resource, {
			reload: { async: false },
			forceReadFromFile: true
		});
	}

	//#endregion

	//#region Dirty

	isDirty(): this is IResolvedTextFileEditorModel {
		return this.dirty;
	}

	setDirty(dirty: boolean): void {
		if (!this.isResolved()) {
			return; // only resolved models can be marked dirty
		}

		// Track dirty state and version id
		const wasDirty = this.dirty;
		this.doSetDirty(dirty);

		// Emit as Event if dirty changed
		if (dirty !== wasDirty) {
			this._onDidChangeDirty.fire();
		}
	}

	private doSetDirty(dirty: boolean): () => void {
		const wasDirty = this.dirty;
		const wasInConflictMode = this.inConflictMode;
		const wasInErrorMode = this.inErrorMode;
		const oldBufferSavedVersionId = this.bufferSavedVersionId;

		if (!dirty) {
			this.dirty = false;
			this.inConflictMode = false;
			this.inErrorMode = false;
			this.updateSavedVersionId();
		} else {
			this.dirty = true;
		}

		// Return function to revert this call
		return () => {
			this.dirty = wasDirty;
			this.inConflictMode = wasInConflictMode;
			this.inErrorMode = wasInErrorMode;
			this.bufferSavedVersionId = oldBufferSavedVersionId;
		};
	}

	//#endregion

	//#region Save

	async save(options: ITextFileSaveOptions = Object.create(null)): Promise<boolean> {
		if (!this.isResolved()) {
			return false;
		}

		if (this.isReadonly()) {
			this.trace('save() - ignoring request for readonly resource');

			return false; // if model is readonly we do not attempt to save at all
		}

		if (
			(this.hasState(TextFileEditorModelState.CONFLICT) || this.hasState(TextFileEditorModelState.ERROR)) &&
			(options.reason === SaveReason.AUTO || options.reason === SaveReason.FOCUS_CHANGE || options.reason === SaveReason.WINDOW_CHANGE)
		) {
			this.trace('save() - ignoring auto save request for model that is in conflict or error');

			return false; // if model is in save conflict or error, do not save unless save reason is explicit
		}

		// Actually do save and log
		this.trace('save() - enter');
		await this.doSave(options);
		this.trace('save() - exit');

		return this.hasState(TextFileEditorModelState.SAVED);
	}

	private async doSave(options: ITextFileSaveOptions): Promise<void> {
		if (typeof options.reason !== 'number') {
			options.reason = SaveReason.EXPLICIT;
		}

		let versionId = this.versionId;
		this.trace(`doSave(${versionId}) - enter with versionId ${versionId}`);

		// Lookup any running pending save for this versionId and return it if found
		//
		// Scenario: user invoked the save action multiple times quickly for the same contents
		//           while the save was not yet finished to disk
		//
		if (this.saveSequentializer.hasPending(versionId)) {
			this.trace(`doSave(${versionId}) - exit - found a pending save for versionId ${versionId}`);

			return this.saveSequentializer.pending;
		}

		// Return early if not dirty (unless forced)
		//
		// Scenario: user invoked save action even though the model is not dirty
		if (!options.force && !this.dirty) {
			this.trace(`doSave(${versionId}) - exit - because not dirty and/or versionId is different (this.isDirty: ${this.dirty}, this.versionId: ${this.versionId})`);

			return;
		}

		// Return if currently saving by storing this save request as the next save that should happen.
		// Never ever must 2 saves execute at the same time because this can lead to dirty writes and race conditions.
		//
		// Scenario A: auto save was triggered and is currently busy saving to disk. this takes long enough that another auto save
		//             kicks in.
		// Scenario B: save is very slow (e.g. network share) and the user manages to change the buffer and trigger another save
		//             while the first save has not returned yet.
		//
		if (this.saveSequentializer.hasPending()) {
			this.trace(`doSave(${versionId}) - exit - because busy saving`);

			// Indicate to the save sequentializer that we want to
			// cancel the pending operation so that ours can run
			// before the pending one finishes.
			// Currently this will try to cancel pending save
			// participants but never a pending save.
			this.saveSequentializer.cancelPending();

			// Register this as the next upcoming save and return
			return this.saveSequentializer.setNext(() => this.doSave(options));
		}

		// Push all edit operations to the undo stack so that the user has a chance to
		// Ctrl+Z back to the saved version.
		if (this.isResolved()) {
			this.textEditorModel.pushStackElement();
		}

		const saveCancellation = new CancellationTokenSource();

		return this.saveSequentializer.setPending(versionId, (async () => {

			// A save participant can still change the model now and since we are so close to saving
			// we do not want to trigger another auto save or similar, so we block this
			// In addition we update our version right after in case it changed because of a model change
			//
			// Save participants can also be skipped through API.
			if (this.isResolved() && !options.skipSaveParticipants) {
				try {

					// Measure the time it took from the last undo/redo operation to this save. If this
					// time is below `UNDO_REDO_SAVE_PARTICIPANTS_THROTTLE_THRESHOLD`, we make sure to
					// delay the save participant for the remaining time if the reason is auto save.
					//
					// This fixes the following issue:
					// - the user has configured auto save with delay of 100ms or shorter
					// - the user has a save participant enabled that modifies the file on each save
					// - the user types into the file and the file gets saved
					// - the user triggers undo operation
					// - this will undo the save participant change but trigger the save participant right after
					// - the user has no chance to undo over the save participant
					//
					// Reported as: https://github.com/microsoft/vscode/issues/102542
					if (options.reason === SaveReason.AUTO && typeof this.lastModelContentChangeFromUndoRedo === 'number') {
						const timeFromUndoRedoToSave = Date.now() - this.lastModelContentChangeFromUndoRedo;
						if (timeFromUndoRedoToSave < TextFileEditorModel.UNDO_REDO_SAVE_PARTICIPANTS_AUTO_SAVE_THROTTLE_THRESHOLD) {
							await timeout(TextFileEditorModel.UNDO_REDO_SAVE_PARTICIPANTS_AUTO_SAVE_THROTTLE_THRESHOLD - timeFromUndoRedoToSave);
						}
					}

					// Run save participants unless save was cancelled meanwhile
					if (!saveCancellation.token.isCancellationRequested) {
						await this.textFileService.files.runSaveParticipants(this, { reason: options.reason ?? SaveReason.EXPLICIT }, saveCancellation.token);
					}
				} catch (error) {
					this.logService.error(`[text file model] runSaveParticipants(${versionId}) - resulted in an error: ${error.toString()}`, this.resource.toString());
				}
			}

			// It is possible that a subsequent save is cancelling this
			// running save. As such we return early when we detect that
			// However, we do not pass the token into the file service
			// because that is an atomic operation currently without
			// cancellation support, so we dispose the cancellation if
			// it was not cancelled yet.
			if (saveCancellation.token.isCancellationRequested) {
				return;
			} else {
				saveCancellation.dispose();
			}

			// We have to protect against being disposed at this point. It could be that the save() operation
			// was triggerd followed by a dispose() operation right after without waiting. Typically we cannot
			// be disposed if we are dirty, but if we are not dirty, save() and dispose() can still be triggered
			// one after the other without waiting for the save() to complete. If we are disposed(), we risk
			// saving contents to disk that are stale (see https://github.com/microsoft/vscode/issues/50942).
			// To fix this issue, we will not store the contents to disk when we got disposed.
			if (this.isDisposed()) {
				return;
			}

			// We require a resolved model from this point on, since we are about to write data to disk.
			if (!this.isResolved()) {
				return;
			}

			// update versionId with its new value (if pre-save changes happened)
			versionId = this.versionId;

			// Clear error flag since we are trying to save again
			this.inErrorMode = false;

			// Save to Disk. We mark the save operation as currently pending with
			// the latest versionId because it might have changed from a save
			// participant triggering
			this.trace(`doSave(${versionId}) - before write()`);
			const lastResolvedFileStat = assertIsDefined(this.lastResolvedFileStat);
			const resolvedTextFileEditorModel = this;
			return this.saveSequentializer.setPending(versionId, (async () => {
				try {
					const stat = await this.textFileService.write(lastResolvedFileStat.resource, resolvedTextFileEditorModel.createSnapshot(), {
						mtime: lastResolvedFileStat.mtime,
						encoding: this.getEncoding(),
						etag: (options.ignoreModifiedSince || !this.filesConfigurationService.preventSaveConflicts(lastResolvedFileStat.resource, resolvedTextFileEditorModel.getLanguageId())) ? ETAG_DISABLED : lastResolvedFileStat.etag,
						unlock: options.writeUnlock,
						writeElevated: options.writeElevated
					});

					this.handleSaveSuccess(stat, versionId, options);
				} catch (error) {
					this.handleSaveError(error, versionId, options);
				}
			})());
		})(), () => saveCancellation.cancel());
	}

	private handleSaveSuccess(stat: IFileStatWithMetadata, versionId: number, options: ITextFileSaveOptions): void {

		// Updated resolved stat with updated stat
		this.updateLastResolvedFileStat(stat);

		// Update dirty state unless model has changed meanwhile
		if (versionId === this.versionId) {
			this.trace(`handleSaveSuccess(${versionId}) - setting dirty to false because versionId did not change`);
			this.setDirty(false);
		} else {
			this.trace(`handleSaveSuccess(${versionId}) - not setting dirty to false because versionId did change meanwhile`);
		}

		// Update orphan state given save was successful
		this.setOrphaned(false);

		// Emit Save Event
		this._onDidSave.fire({ reason: options.reason, stat, source: options.source });
	}

	private handleSaveError(error: Error, versionId: number, options: ITextFileSaveOptions): void {
		(options.ignoreErrorHandler ? this.logService.trace : this.logService.error).apply(this.logService, [`[text file model] handleSaveError(${versionId}) - exit - resulted in a save error: ${error.toString()}`, this.resource.toString()]);

		// Return early if the save() call was made asking to
		// handle the save error itself.
		if (options.ignoreErrorHandler) {
			throw error;
		}

		// In any case of an error, we mark the model as dirty to prevent data loss
		// It could be possible that the write corrupted the file on disk (e.g. when
		// an error happened after truncating the file) and as such we want to preserve
		// the model contents to prevent data loss.
		this.setDirty(true);

		// Flag as error state in the model
		this.inErrorMode = true;

		// Look out for a save conflict
		if ((<FileOperationError>error).fileOperationResult === FileOperationResult.FILE_MODIFIED_SINCE) {
			this.inConflictMode = true;
		}

		// Show to user
		this.textFileService.files.saveErrorHandler.onSaveError(error, this);

		// Emit as event
		this._onDidSaveError.fire();
	}

	private updateSavedVersionId(): void {
		// we remember the models alternate version id to remember when the version
		// of the model matches with the saved version on disk. we need to keep this
		// in order to find out if the model changed back to a saved version (e.g.
		// when undoing long enough to reach to a version that is saved and then to
		// clear the dirty flag)
		if (this.isResolved()) {
			this.bufferSavedVersionId = this.textEditorModel.getAlternativeVersionId();
		}
	}

	private updateLastResolvedFileStat(newFileStat: IFileStatWithMetadata): void {
		const oldReadonly = this.isReadonly();

		// First resolve - just take
		if (!this.lastResolvedFileStat) {
			this.lastResolvedFileStat = newFileStat;
		}

		// Subsequent resolve - make sure that we only assign it if the mtime is equal or has advanced.
		// This prevents race conditions from resolving and saving. If a save comes in late after a revert
		// was called, the mtime could be out of sync.
		else if (this.lastResolvedFileStat.mtime <= newFileStat.mtime) {
			this.lastResolvedFileStat = newFileStat;
		}

		// Signal that the readonly state changed
		if (this.isReadonly() !== oldReadonly) {
			this._onDidChangeReadonly.fire();
		}
	}

	//#endregion

	hasState(state: TextFileEditorModelState): boolean {
		switch (state) {
			case TextFileEditorModelState.CONFLICT:
				return this.inConflictMode;
			case TextFileEditorModelState.DIRTY:
				return this.dirty;
			case TextFileEditorModelState.ERROR:
				return this.inErrorMode;
			case TextFileEditorModelState.ORPHAN:
				return this.inOrphanMode;
			case TextFileEditorModelState.PENDING_SAVE:
				return this.saveSequentializer.hasPending();
			case TextFileEditorModelState.SAVED:
				return !this.dirty;
		}
	}

	async joinState(state: TextFileEditorModelState.PENDING_SAVE): Promise<void> {
		return this.saveSequentializer.pending;
	}

	override getLanguageId(this: IResolvedTextFileEditorModel): string;
	override getLanguageId(): string | undefined;
	override getLanguageId(): string | undefined {
		if (this.textEditorModel) {
			return this.textEditorModel.getLanguageId();
		}

		return this.preferredLanguageId;
	}

	//#region Encoding

	private async onMaybeShouldChangeEncoding(): Promise<void> {

		// This is a bit of a hack but there is a narrow case where
		// per-language configured encodings are not working:
		//
		// On startup we may not yet have all languages resolved so
		// we pick a wrong encoding. We never used to re-apply the
		// encoding when the language was then resolved, because that
		// is an operation that is will have to fetch the contents
		// again from disk.
		//
		// To mitigate this issue, when we detect the model language
		// changes, we see if there is a specific encoding configured
		// for the new language and apply it, only if the model is
		// not dirty and only if the encoding was not explicitly set.
		//
		// (see https://github.com/microsoft/vscode/issues/127936)

		if (this.hasEncodingSetExplicitly) {
			this.trace('onMaybeShouldChangeEncoding() - ignoring because encoding was set explicitly');

			return; // never change the user's choice of encoding
		}

		if (this.contentEncoding === UTF8_with_bom || this.contentEncoding === UTF16be || this.contentEncoding === UTF16le) {
			this.trace('onMaybeShouldChangeEncoding() - ignoring because content encoding has a BOM');

			return; // never change an encoding that we can detect 100% via BOMs
		}

		const { encoding } = await this.textFileService.encoding.getPreferredReadEncoding(this.resource);
		if (typeof encoding !== 'string' || !this.isNewEncoding(encoding)) {
			this.trace(`onMaybeShouldChangeEncoding() - ignoring because preferred encoding ${encoding} is not new`);

			return; // return early if encoding is invalid or did not change
		}

		if (this.isDirty()) {
			this.trace('onMaybeShouldChangeEncoding() - ignoring because model is dirty');

			return; // return early to prevent accident saves in this case
		}

		this.logService.info(`Adjusting encoding based on configured language override to '${encoding}' for ${this.resource.toString(true)}.`);

		// Re-open with new encoding
		return this.setEncodingInternal(encoding, EncodingMode.Decode);
	}

	private hasEncodingSetExplicitly: boolean = false;

	setEncoding(encoding: string, mode: EncodingMode): Promise<void> {

		// Remember that an explicit encoding was set
		this.hasEncodingSetExplicitly = true;

		return this.setEncodingInternal(encoding, mode);
	}

	private async setEncodingInternal(encoding: string, mode: EncodingMode): Promise<void> {

		// Encode: Save with encoding
		if (mode === EncodingMode.Encode) {
			this.updatePreferredEncoding(encoding);

			// Save
			if (!this.isDirty()) {
				this.versionId++; // needs to increment because we change the model potentially
				this.setDirty(true);
			}

			if (!this.inConflictMode) {
				await this.save({ source: TextFileEditorModel.TEXTFILE_SAVE_ENCODING_SOURCE });
			}
		}

		// Decode: Resolve with encoding
		else {
			if (!this.isNewEncoding(encoding)) {
				return; // return early if the encoding is already the same
			}

			if (this.isDirty() && !this.inConflictMode) {
				await this.save();
			}

			this.updatePreferredEncoding(encoding);

			await this.forceResolveFromFile();
		}
	}

	updatePreferredEncoding(encoding: string | undefined): void {
		if (!this.isNewEncoding(encoding)) {
			return;
		}

		this.preferredEncoding = encoding;

		// Emit
		this._onDidChangeEncoding.fire();
	}

	private isNewEncoding(encoding: string | undefined): boolean {
		if (this.preferredEncoding === encoding) {
			return false; // return early if the encoding is already the same
		}

		if (!this.preferredEncoding && this.contentEncoding === encoding) {
			return false; // also return if we don't have a preferred encoding but the content encoding is already the same
		}

		return true;
	}

	getEncoding(): string | undefined {
		return this.preferredEncoding || this.contentEncoding;
	}

	//#endregion

	private trace(msg: string): void {
		this.logService.trace(`[text file model] ${msg}`, this.resource.toString());
	}

	override isResolved(): this is IResolvedTextFileEditorModel {
		return !!this.textEditorModel;
	}

	override isReadonly(): boolean {
		return this.lastResolvedFileStat?.readonly || this.fileService.hasCapability(this.resource, FileSystemProviderCapabilities.Readonly);
	}

	override dispose(): void {
		this.trace('dispose()');

		this.inConflictMode = false;
		this.inOrphanMode = false;
		this.inErrorMode = false;

		super.dispose();
	}
}


text:
package com.sylvanaar.idea.Lua.console;

import com.intellij.execution.console.LanguageConsoleImpl;
import com.intellij.execution.process.ColoredProcessHandler;

import java.nio.charset.Charset;

/**
 * Created by IntelliJ IDEA.
 * User: Jon S Akhtar
 * Date: 2/20/11
 * Time: 4:55 PM
 */
public class LuaConsoleProcessHandler extends ColoredProcessHandler {

    public LuaConsoleProcessHandler(Process process, LanguageConsoleImpl languageConsole, String commandLine,
                                    Charset charset) {
        super(process, commandLine, charset);
        myLanguageConsole = languageConsole;
    }

    private final LanguageConsoleImpl myLanguageConsole;
}

redpajama_set_name: RedPajamaGithub


text:
from __future__ import absolute_import

from django.core.urlresolvers import reverse
from django.test.client import RequestFactory

from tests.apidocs.util import APIDocsTestCase

class OrganizationShortIDDocs(APIDocsTestCase):
    def setUp(self):
        group = self.create_group(project=self.project)

        self.url = reverse(
            "sentry-api-0-short-id-lookup",
            kwargs={
                "organization_slug": self.organization.slug,
                "short_id": group.qualified_short_id,
            },
        )

        self.login_as(user=self.user)

    def test_get(self):
        response = self.client.get(self.url)
        request = RequestFactory().get(self.url)

        self.validate_schema(request, response)


text:
Merb.logger.info("Compiling routes...")
Merb::Router.prepare do
  # RESTful routes
  # resources :posts
  resources :users, :collection => {:signup => :get}

  # Adds the required routes for merb-auth using the password slice
  slice(:merb_auth_slice_password, :name_prefix => nil, :path_prefix => "")

  match("/servers").to(:controller => 'servers').name('servers')
  match("/servers/xrds").to(:controller => 'servers', :action => :idp_page).name('xrds')
  match("/servers/acceptance").to(:controller => 'servers', :action => 'acceptance').name('acceptance')
  match("/servers/decision").to(:controller => 'servers', :action => 'decision').name('server_decision')

  # Change this for your home page to be available at /
  match('/').to(:controller => 'servers', :action => 'landing')
end


text:
[![Version](https://cocoapod-badges.herokuapp.com/v/youtube-ios-player-helper/badge.png)](https://cocoapods.org/pods/youtube-ios-player-helper)
[![Platform](https://cocoapod-badges.herokuapp.com/p/youtube-ios-player-helper/badge.png)](https://cocoapods.org/pods/youtube-ios-player-helper)

## Usage

To run the example project; clone the repo, and run `pod install` from the Project directory first.  For a simple tutorial see this Google Developers article - [Using the YouTube Helper Library to embed YouTube videos in your iOS application](https://developers.google.com/youtube/v3/guides/ios_youtube_helper).

## Requirements

## Installation

YouTube-Player-iOS-Helper is available through [CocoaPods](http://cocoapods.org), to install
it simply add the following line to your Podfile:

    pod "youtube-ios-player-helper", "~> 0.1.4"

After installing in your project and opening the workspace, to use the library:

  1. Drag a UIView the desired size of your player onto your Storyboard.
  2. Change the UIView's class in the Identity Inspector tab to YTPlayerView
  3. Import "YTPlayerView.h" in your ViewController.
  4. Add the following property to your ViewController's header file:
```objc
    @property(nonatomic, strong) IBOutlet YTPlayerView *playerView;
```
  5. Load the video into the player in your controller's code with the following code:
```objc
    [self.playerView loadWithVideoId:@"M7lc1UVf-VE"];
```
  6. Run your code!

See the sample project for more advanced uses, including passing additional player parameters and
working with callbacks via YTPlayerViewDelegate.

## Author

Ikai Lan
Ibrahim Ulukaya, ulukaya@google.com
Yoshifumi Yamaguchi, yoshifumi@google.com

## License

YouTube-Player-iOS-Helper is available under the Apache 2.0 license. See the LICENSE file for more info.


text:
Web Workers are a browser feature that allows running client-side code in parallel. Every worker runs on a separate thread, and they communicate by posting messages to one another.

In WebSharper 4.4 and later, creating a Web Worker is very simple; much simpler, in fact, than in plain JavaScript.

## Creating a Worker

You can call the `WebSharper.JavaScript.Worker` constructor and pass it a function, which will be the entry point for the worker.

```fsharp
open WebSharper.JavaScript

let myWorker = new Worker(fun self ->
    Console.Log "This was written from the worker!"
    self.PostMessage("This worker's job is done, it can be terminated.")
)
myWorker.Onmessage <- fun event ->
    Console.Log event.Data
    myWorker.Terminate()
```

The above code will:

- create and start a new Web Worker.

- print the following from the created worker thread:

    ```
    This was written from the worker!
    ```

- send the following from the worker thread to the main thread, which then prints it:

    ```
    This worker's job is done, it can be terminated.
    ```

- terminate the worker thread.

## What's happening behind the scenes

A lot of things are happening behind the scenes with this simple call. The WebSharper compiler:

- recognizes that you are calling the `Worker` constructor with a function argument, and sets this function (which we will call the entry point) aside.
- creates a separate compiled JavaScript file called `MyProject.worker.js` that only contains the entry point and any other functions, classes, etc that it requires. It passes as argument to the entry point the global scope of the worker.
- compiles the `Worker` constructor call into JavaScript as:

    ```javascript
    var myWorker = new Worker("MyProject.worker.js")
    ```

If you have several such `Worker` calls in the same project, subsequent ones will be compiled to JavaScript files called `MyProject.worker0.js`, `MyProject.worker1.js`, and so on.

## Message passing

Communication between a Worker and the main thread is done by message passing. The worker can listen for incoming messages from the main thread using `self.Onmessage <- f` or `self.AddEventListener("message", f, false)`, and send messages to the main thread using `self.PostMessage(msg)`. Conversely, the main thread can listen for incoming messages from the worker using `worker.Onmessage <- f` or `self.AddEventListener("message", f, false)`, and send messages to the worker using `worker.PostMessage(msg)`.

```fsharp
let echoWorker = new Worker(fun self ->
    // This is the code of the worker

    // Listen to messages from the main thread
    self.Onmessage <- fun event ->

        // Here we're assuming we'll only ever receive strings
        let msg = event.Data :?> string

        // Send a message to the main thread
        self.PostMessage("The worker said: " + msg)
)

// This code is on the main thread

// Listen to messages from the worker
echoWorker.Onmessage <- fun event ->

    // Again we're assuming we'll only ever receive strings
    let msg = event.Data :?> string

    // Print the received message to the console
    Console.Log(msg)

// This will send the string to the worker, receive it back,
// and print to the console: "The worker said: Hello world!"
echoWorker.PostMessage("Hello world!")

// The worker is still running, we can send more messages
// and they will be sent back and forth and printed.
echoWorker.PostMessage("Hi again!")
```

## Using external dependencies

It is possible to use external script dependencies in a Worker. These will be compiled to calls to `importScripts()` in the worker script. For example, here is a worker that uses [math.js](http://mathjs.org/) and the binding [WebSharper.MathJS](https://www.nuget.org/packages/websharper.mathjs) to perform mathematical operations:

```fsharp
open WebSharper.MathJS

let myWorker = new Worker(fun self ->
    self.Onmessage <- fun event ->
        let msg = event.Data :?> string
        let res = Math.Derivative(msg, "x").ToString()
        Console.Log(res)
)
// This will print "4 * x + 3":
myWorker.PostMessage("2x^2 + 3x + 4")
```

## Customizing the worker script

There are a few options to customize the generated script for a worker.

- You can customize the filename of the script by passing a string as first argument to the `Worker` constructor:

    ```fsharp
    // This script will be called "MyLibrary.worker.js":
    let simpleWorker = new Worker(fun self ->
        Console.Log("I'm a worker")
    )

    // This script will be called "MyLibrary.say-hello.js":
    let helloWorker = new Worker("say-hello", fun self ->
        Console.Log("I'm called 'say-hello'!")
    )
    ```

- You can decide to include the values, modules and types marked `[<JavaScriptExport>]` in the generated script by passing an additional `true` argument to the `Worker` constructor. This can be useful for example if you intend to also call the generated script manually from JavaScript.

    ```fsharp
    [<JavaScriptExport>]
    let MyExportedFunction() =
        Console.Log("I'm not called directly from the worker entry point")

    let CreateWorker() =
        new Worker("worker", true, fun self ->
            Console.Log("This doesn't call MyExportedFunction, but it will be defined anyway")
        )
    ```

Note that in both cases, you must use a literal string or boolean, rather than a more complex expression, because it must be recognized at compile time.

## Customizing the script location

[The behind-the-scenes section](#behind-the-scenes) states that the worker constructor call is translated into the following JavaScript:

```javascript
var myWorker = new Worker("MyProject.worker.js")
```

That is actually a simplification. In practice, WebSharper needs to figure out the path to the script: the file name is not sufficient. The full path is computed and depends on the type of final project that the code is used in:

- In a client-server `website` project, the default path is `/Scripts/WebSharper/<assemblyname>/<filename>`.
- In a single-page application (aka `bundle` or `bundleOnly` project), the default path is `/Content/<assemblyname>/<filename>`.
- In a generated static HTML site (aka `html` project), the default path is `/Scripts/<assemblyname>/<filename>`.

These correspond to the location where the compiler extracts the files, so in a standard setup, everything just works and there is nothing to do. But if you need it, this is customizable using the `scriptBaseUrl` [configuration setting](project-variables#scriptBaseUrl). It changes the base URL for the script, ie. the paths mentioned aboved minus the `<assemblyname>/<filename>` suffix. Note that this URL **must** end with a slash, and almost always needs to start with a slash too.

Here is an example `wsconfig.json` that deviates from the standard: the output directory into which the files are extracted is customized using `outputDir`, so we need to customize `scriptBaseUrl` too.

```json
{
    "project": "bundleOnly",
    "outputDir": "wwwroot/js",
    "scriptBaseUrl": "/js/"
}
```


text:
// Copyright (c) 2015 fjz13. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
#include "MedusaPreCompiled.h"
#include "BehaviorConfig.h"
#include "Game/AI/Predicate/PredicateConfig.h"
#include "Game/AI/Behavior/BehaviorFactory.h"
#include "Game/AI/Predicate/PredicateFactory.h"
#include "Core/Log/Log.h"
#include "CoreLib/Common/pugixml/pugixml.hpp"
#include "Core/IO/FileIdRef.h"

MEDUSA_BEGIN;

bool BehaviorConfig::LoadFromData(const FileIdRef& fileId, const MemoryData& data, uint format /*= 0*/)
{
	Unload();
	RETURN_FALSE_IF(data.IsNull());

	pugi::xml_document doc;
	pugi::xml_parse_result result = doc.load_buffer(data.Data(), data.Size());
	if (!result)
	{
		Log::AssertFailedFormat("Cannot parse xml:{} because {}", fileId, result.description());
		return false;
	}
	for (const auto& child : doc.first_child().children())
	{
		StringRef typeName = child.name();
		StringRef id = child.attribute("Id").value();
		if (id.IsEmpty())
		{
			id = typeName;
		}

#ifdef MEDUSA_SAFE_CHECK
		if (ContainsId(id))
		{
			Log::AssertFailedFormat("Duplicate id:{} in {}", id.c_str(), typeName.c_str());
		}
#endif

		IBehavior* behavior = BehaviorFactory::Instance().SmartCreate(typeName);
		behavior->LoadFromXmlNode(child);
		behavior->Initialize();
		if (id.EndWith("Behavior"))
		{
			Add(id, behavior);
		}
		else
		{
			Add(id + "Behavior", behavior);
		}
	}

	return true;
}

void BehaviorConfig::Unload()
{
	Clear();
}

IBehavior* BehaviorConfig::SmartCreate(StringRef name)
{
	IBehavior* behavior = TryGetObjectWithFailed(name, nullptr);
	if (behavior == nullptr)
	{
		behavior = TryGetObjectWithFailed(name + "Behavior", nullptr);
	}

	if (behavior == nullptr)
	{
		behavior = BehaviorFactory::Instance().SmartCreate(name);
	}

	return behavior;
}

MEDUSA_END;


text:
{-# LANGUAGE DataKinds         #-}
{-# LANGUAGE FlexibleContexts  #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs             #-}
{-# LANGUAGE LambdaCase        #-}
{-# LANGUAGE NamedFieldPuns    #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes        #-}
{-# LANGUAGE TypeOperators     #-}

module Qi.Program.SQS.Lang where

import           Control.Monad.Freer
import           Data.Aeson           (FromJSON, ToJSON)
import qualified Data.ByteString.Lazy as LBS
import           Network.AWS.SQS
import           Protolude
import           Qi.AWS.SQS
import           Qi.Config.AWS.SQS
import           Qi.Config.Identifier
import           Qi.Core.Curry
import           Qi.Program.Gen.Lang

data SqsEff r where
  SendSqsMessage
    :: ToJSON a
    => SqsQueueId
    -> a
    -> SqsEff ()

  ReceiveSqsMessage
    :: FromJSON a
    => SqsQueueId
    -> SqsEff [(a, ReceiptHandle)]

  DeleteSqsMessage
    :: SqsQueueId
    -> ReceiptHandle
    -> SqsEff ()

sendSqsMessage
  :: (Member SqsEff effs, ToJSON a)
  => SqsQueueId
  -> a
  -> Eff effs ()
sendSqsMessage = send .: SendSqsMessage

receiveSqsMessage
  :: (Member SqsEff effs, FromJSON a)
  => SqsQueueId
  -> Eff effs [(a, ReceiptHandle)] -- the json body and the receipt handle
receiveSqsMessage = send . ReceiveSqsMessage

deleteSqsMessage
  :: (Member SqsEff effs)
  => SqsQueueId
  -> ReceiptHandle
  -> Eff effs ()
deleteSqsMessage = send .: DeleteSqsMessage


text:
module Jobs
  class SendNotificationEmail
    include Sidekiq::Worker

    sidekiq_options retry: 10

    # The default retry is exponential
    sidekiq_retry_in do |count|
      200 * (count + 1) # (i.e. 200, 400, 600, 800... seconds)
    end

    def perform(notification_id, followup_id)
      note = Notification[id: notification_id]
      user = note.user
      followup = Followup[id: followup_id]
      message = followup.message

      emailer = Telex::Emailer.new(
        email: user.email,
        in_reply_to: note.id,
        subject: message.title,
        body: followup.body
      )
      emailer.deliver!
    end
  end
end


text:
 * Infected Wars, an open source Garry's Mod game-mode.
 *
 * Infected Wars is the work of multiple authors,
 * a full list can be found in CONTRIBUTORS.md.
 * For more information, visit https://github.com/JarnoVgr/InfectedWars
 *
 * Infected Wars is free software: you can redistribute it and/or modify
 * it under the terms of the MIT License.
 *
 * A full copy of the MIT License can be found in LICENSE.txt.
 -----------------------------------------------------------------------------]]

function DebugVector(start, vector, color)
	umsg.Start("Debug_Vector")
	umsg.Vector(start)
	umsg.Vector(vector)
	umsg.Vector(Vector(color.r, color.g, color.b))
	umsg.End()
end


text:
require 'test_helper'

class ListopiaTest < ActiveSupport::TestCase
  test "truth" do
    assert_kind_of Module, Listopia
  end
end


text:
package ctxhttp

import (
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/asemt/ghuwtchr/Godeps/_workspace/src/golang.org/x/net/context"
)

const (
	requestDuration = 100 * time.Millisecond
	requestBody     = "ok"
)

func TestNoTimeout(t *testing.T) {
	ctx := context.Background()
	resp, err := doRequest(ctx)

	if resp == nil || err != nil {
		t.Fatalf("error received from client: %v %v", err, resp)
	}
}
func TestCancel(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		time.Sleep(requestDuration / 2)
		cancel()
	}()

	resp, err := doRequest(ctx)

	if resp != nil || err == nil {
		t.Fatalf("expected error, didn't get one. resp: %v", resp)
	}
	if err != ctx.Err() {
		t.Fatalf("expected error from context but got: %v", err)
	}
}

func TestCancelAfterRequest(t *testing.T) {
	ctx, cancel := context.WithCancel(context.Background())

	resp, err := doRequest(ctx)

	// Cancel before reading the body.
	// Request.Body should still be readable after the context is canceled.
	cancel()

	b, err := ioutil.ReadAll(resp.Body)
	if err != nil || string(b) != requestBody {
		t.Fatalf("could not read body: %q %v", b, err)
	}
}

func doRequest(ctx context.Context) (*http.Response, error) {
	var okHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(requestDuration)
		w.Write([]byte(requestBody))
	})

	serv := httptest.NewServer(okHandler)
	defer serv.Close()

	return Get(ctx, nil, serv.URL)
}


text:
/*
 *  21.04.2004 Original verion. davagin@udm.ru.
 *-----------------------------------------------------------------------
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *----------------------------------------------------------------------
 */

package davaguine.jmac.decoder;

/**
 * Author: Dmitry Vaguine
 * Date: 04.03.2004
 * Time: 14:51:31
 */
public class AntiPredictorOffset extends AntiPredictor {
    public void AntiPredict(int[] pInputArray, int[] pOutputArray, int NumberOfElements, int Offset, int DeltaM) {
        System.arraycopy(pInputArray, 0, pOutputArray, 0, Offset);

        int ip = Offset;
        int ipo = 0;
        int op = Offset;
        int m = 0;

        for (; op < NumberOfElements; ip++, ipo++, op++) {
            pOutputArray[op] = pInputArray[ip] + ((pOutputArray[ipo] * m) >> 12);

            if ((pOutputArray[ipo] ^ pInputArray[ip]) > 0)
                m += DeltaM;
            else
                m -= DeltaM;
        }
    }
}


text:
package org.okbqa.rendering.model;

public class Binding {
	private String var = "";
	private String binding = "";
	private String endpoint = "";
    public Binding(String aVar, String aUriBinding, String aSourceEndpoint) {
		var = aVar;
		binding = aUriBinding;
		endpoint = aSourceEndpoint;
	}
	public String getVar() {
		return var;
	}
	public void setVar(String mVar) {
		this.var = mVar;
	}
	public String getUriBinding() {
		return binding;
	}
	public void setUriBinding(String mUriBinding) {
		this.binding = mUriBinding;
	}
	public String getSourceEndpoint() {
		return endpoint;
	}
	public void setSourceEndpoint(String mSourceEndpoint) {
		this.endpoint = mSourceEndpoint;
	}
}


text:
require 'win-ffi/core/struct/point'

require_relative '../../typedef/hmenu'

require_relative '../../enum/resource/menu/flag'
require_relative '../../enum/resource/menu/track_popup_menu_flag'
require_relative '../../enum/resource/menu/get_menu_default_item_flag'
require_relative '../../enum/window/control/system_object_id'

require_relative '../../struct/resource/menu/menubar_info'
require_relative '../../struct/resource/menu/info'
require_relative '../../struct/resource/menu/item_info'
require_relative '../../struct/resource/menu/item_template'
require_relative '../../struct/resource/menu/tpm_params'

module WinFFI
  module User32
    PMB_ACTIVE = 0x00000001

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-appendmenua
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-appendmenuw
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uFlags
    # @param [Integer] uIDNewItem
    # @param [FFI::Pointer] lpNewItem
    # @return [true, false]
    def self.AppendMenu(hMenu, uFlags, uIDNewItem, lpNewItem) end
    encoded_function 'AppendMenu', [:hmenu, MenuFlag, :uint_ptr, :pointer], :bool

    # Deprecated
    # http://winapi.freetechsecrets.com/win32/WIN32ChangeMenu.htm
    # @param [FFI::Pointer] hMenu
    # @param [Integer] cmd
    # @param [String] lpszNewItem
    # @param [Integer] cmdInsert
    # @param [Integer] flags
    # @return [true, false]
    # def self.ChangeMenu(hMenu, cmd, lpszNewItem, cmdInsert, flags) end
    # encoded_function 'ChangeMenu', [:hmenu, :uint, :string, :uint, :uint], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-checkmenuitem
    # @param [FFI::Pointer] hmenu
    # @param [Integer] uIDCheckItem
    # @param [Integer] uCheck
    # @return [Integer]
    def self.CheckMenuItem(hmenu, uIDCheckItem, uCheck) end
    attach_function 'CheckMenuItem', [:hmenu, :uint, :uint], :dword

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-checkmenuradioitem
    # @param [# @return [true, false]] hmenu
    # @param [Integer] idFirst
    # @param [Integer] idLast
    # @param [Integer] idCheck
    # @param [Integer] uFlags
    # @param [true, false] hmenu
    def self.CheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags) end
    attach_function 'CheckMenuRadioItem', [:hmenu, :uint, :uint, :uint, :uint], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createmenu
    # @return [FFI::Pointer]
    def self.CreateMenu; end
    attach_function 'CreateMenu', [], :hmenu

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-createpopupmenu
    # @return [FFI::Pointer]
    def self.CreatePopupMenu; end
    attach_function 'CreatePopupMenu', [], :hmenu

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-deletemenu
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uPosition
    # @param [Integer] uFlags
    # @return [true, false]
    def self.DeleteMenu(hMenu, uPosition, uFlags) end
    attach_function 'DeleteMenu', [:hmenu, :uint, :uint], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-destroymenu
    # @param [FFI::Pointer] hMenu
    # @return [true, false]
    def self.DestroyMenu(hMenu) end
    attach_function 'DestroyMenu', [:hmenu], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-drawmenubar
    # @param [FFI::Pointer] hWnd
    # @return [true, false]
    def self.DrawMenuBar(hWnd) end
    attach_function 'DrawMenuBar', [:hwnd], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-enablemenuitem
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uIDEnableItem
    # @param [Integer] uEnable
    # @return [true, false]
    def self.EnableMenuItem(hMenu, uIDEnableItem, uEnable) end
    attach_function 'EnableMenuItem', [:hmenu, :uint, MenuFlag], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-endmenu
    # @return [true, false]
    def self.EndMenu; end
    attach_function 'EndMenu', [], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenu
    # @param [FFI::Pointer] hWnd
    # @return [FFI::Pointer]
    def self.GetMenu(hWnd) end
    attach_function 'GetMenu', [:hwnd], :hmenu

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenubarinfo
    # @param [FFI::Pointer] hwnd
    # @param [Integer] idObject
    # @param [Integer] idItem
    # @param [FFI::Pointer] pmbi
    # @return [true, false]
    def self.GetMenuBarInfo(hwnd, idObject, idItem, pmbi); end
    attach_function 'GetMenuBarInfo', [:hwnd, SystemObjectId, :long, MENUBARINFO.ptr], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenucheckmarkdimensions
    # @return [Integer]
    def self.GetMenuCheckMarkDimensions; end
    attach_function 'GetMenuCheckMarkDimensions', [], :long

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenudefaultitem
    # @param [FFI::Pointer] hMenu
    # @param [Integer] fByPos
    # @param [Integer] gmdiFlags
    # @return [Integer]
    def self.GetMenuDefaultItem(hMenu, fByPos, gmdiFlags); end
    attach_function 'GetMenuDefaultItem', [:hmenu, :uint, GetMenuDefaultItemFlag], :uint

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenuinfo
    # @param [FFI::Pointer] hmenu
    # @param [FFI::Pointer] lpcmi
    # @return [true, false]
    def self.GetMenuInfo(hmenu, lpcmi); end
    attach_function 'GetMenuInfo', [:hmenu, MENUINFO.ptr], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenuitemcount
    # @param [FFI::Pointer] hMenu
    # @return [Integer]
    def self.GetMenuItemCount(hMenu); end
    attach_function 'GetMenuItemCount', [:hmenu], :int

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenuitemid
    # @param [FFI::Pointer] hMenu
    # @param [Integer] nPos
    # @return [Integer]
    def self.GetMenuItemID(hMenu, nPos); end
    attach_function 'GetMenuItemID', [:hmenu, :int], :uint

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenuiteminfoa
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenuiteminfow
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uItem
    # @param [true, false] fByPosition
    # @param [FFI::Pointer] lpmii
    # @return [true, false]
    def self.GetMenuItemInfo(hMenu, uItem, fByPosition, lpmii); end
    encoded_function 'GetMenuItemInfo', [:hmenu, :uint, :bool, MENUITEMINFO.ptr], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenuitemrect
    # @param [FFI::Pointer] hWnd
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uItem
    # @param [FFI::Pointer] lprcItem
    # @return [true, false]
    def self.GetMenuItemRect(hWnd, hMenu, uItem, lprcItem); end
    attach_function 'GetMenuItemRect', [:hwnd, :hmenu, :uint, RECT.ptr(:out)], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenustate
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uId
    # @param [Integer] uFlags
    # @return [Integer]
    def self.GetMenuState(hMenu, uId, uFlags); end
    attach_function 'GetMenuState', [:hmenu, :uint, :uint], :uint

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenustringa
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getmenustringw
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uIDItem
    # @param [FFI::Pointer] lpString
    # @param [Integer] nMaxCount
    # @param [Integer] uFlag
    # @return [Integer]
    def self.GetMenuString(hMenu, uIDItem, lpString, nMaxCount, uFlag); end
    encoded_function 'GetMenuString', [:hmenu, :uint, :pointer, :int, :uint], :int

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getsubmenu
    # @param [FFI::Pointer] hMenu
    # @param [Integer] nPos
    # @return [FFI::Pointer]
    def self.GetSubMenu(hMenu, nPos); end
    attach_function 'GetSubMenu', [:hmenu, :int], :hmenu

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-getsystemmenu
    # @param [FFI::Pointer] hWnd
    # @param [true, false] bRevert
    # @return [FFI::Pointer]
    def self.GetSystemMenu(hWnd, bRevert); end
    attach_function 'GetSystemMenu', [:hwnd, :bool], :hmenu

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-hilitemenuitem
    # @param [FFI::Pointer] hwnd
    # @param [FFI::Pointer] hmenu
    # @param [Integer] uItemHilite
    # @param [Integer] uHilite
    # @return [true, false]
    def self.HiliteMenuItem(hwnd, hmenu, uItemHilite, uHilite); end
    attach_function 'HiliteMenuItem', [:hwnd, :hmenu, :uint, MenuFlag], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-insertmenua
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-insertmenuw
    # The InsertMenu function has been superseded by the InsertMenuItem function.
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uPosition
    # @param [Integer] uFlags
    # @param [Integer] uIDNewItem
    # @param [String] lpNewItem
    # @return [true, false]
    def self.InsertMenu(hMenu, uPosition, uFlags, uIDNewItem, lpNewItem); end
    encoded_function 'InsertMenu', [:hmenu, :uint, MenuFlag, :uint_ptr, :string], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-insertmenuitema
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-insertmenuitemw
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uItem
    # @param [true, false] fByPosition
    # @param [FFI::Pointer] lpmii
    # @return [true, false]
    def self.InsertMenuItem(hMenu, uItem, fByPosition, lpmii); end
    encoded_function 'InsertMenuItem', [:hmenu, :uint, :bool, MENUITEMINFO.ptr(:in)], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-ismenu
    # @param [FFI::Pointer] hMenu
    # @return [true, false]
    def self.IsMenu(hMenu); end
    attach_function 'IsMenu', [:hmenu], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-loadmenua
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-loadmenuw
    # @param [FFI::Pointer] hInstance
    # @param [String] lpMenuName
    # @return [FFI::Pointer]
    def self.LoadMenu(hInstance, lpMenuName); end
    encoded_function 'LoadMenu', [:hinstance, :string], :hmenu

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-loadmenuindirecta
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-loadmenuindirectw
    # @param [FFI::Pointer] lpMenuTemplate
    # @return [FFI::Pointer]
    def self.LoadMenuIndirect(lpMenuTemplate); end
    encoded_function 'LoadMenuIndirect', [MENUITEMTEMPLATE.ptr], :hmenu

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-menuitemfrompoint
    # @param [FFI::Pointer] hWnd
    # @param [FFI::Pointer] hMenu
    # @param [POINT] ptScreen
    # @return [Integer]
    def self.MenuItemFromPoint(hWnd, hMenu, ptScreen); end
    attach_function 'MenuItemFromPoint', [:hwnd, :hmenu, POINT], :int

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-modifymenua
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-modifymenuw
    # The ModifyMenu function has been superseded by the SetMenuItemInfo function
    # @param [FFI::Pointer] hMnu
    # @param [Integer] uPosition
    # @param [Integer] uFlags
    # @param [Integer] uIDNewItem
    # @param [String] lpNewItem
    # @return [true, false]
    def self.ModifyMenu(hMnu, uPosition, uFlags, uIDNewItem, lpNewItem); end
    encoded_function 'ModifyMenu', [:hmenu, :uint, MenuFlag, :uint_ptr, :string], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-removemenu
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uPosition
    # @param [Integer] uFlags
    # @return [true, false]
    def self.RemoveMenu(hMenu, uPosition, uFlags); end
    attach_function 'RemoveMenu', [:hmenu, :uint, :uint], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setmenu
    # @param [FFI::Pointer] hWnd
    # @param [FFI::Pointer] hMenu
    # @return [true, false]
    def self.SetMenu(hWnd, hMenu); end
    attach_function 'SetMenu', [:hwnd, :hmenu], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setmenudefaultitem
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uItem
    # @param [Integer] fByPos
    # @return [true, false]
    def self.SetMenuDefaultItem(hMenu, uItem, fByPos); end
    attach_function 'SetMenuDefaultItem', [:hmenu, :uint, :uint], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setmenuinfo
    # @param [FFI::Pointer] hmenu
    # @param [FFI::Pointer] lpcmi
    # @return [true, false]
    def self.SetMenuInfo(hmenu, lpcmi); end
    attach_function 'SetMenuInfo', [:hmenu, MENUINFO.ptr(:in)], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setmenuitembitmaps
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uPosition
    # @param [Integer] uFlags
    # @param [FFI::Pointer] hBitmapUnchecked
    # @param [FFI::Pointer] hBitmapChecked
    # @return [true, false]
    def self.SetMenuItemBitmaps(hMenu, uPosition, uFlags, hBitmapUnchecked, hBitmapChecked); end
    attach_function 'SetMenuItemBitmaps', [:hmenu, :uint, MenuFlag, :hbitmap, :hbitmap], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setmenuiteminfoa
    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-setmenuiteminfow
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uItem
    # @param [true, false] fByPosition
    # @param [FFI::Pointer] lpmii
    # @return [true, false]
    def self.SetMenuItemInfo(hMenu, uItem, fByPosition, lpmii); end
    encoded_function 'SetMenuItemInfo', [:hmenu, :uint, :bool, MENUITEMINFO.ptr(:in)], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-trackpopupmenu
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uFlags
    # @param [Integer] x
    # @param [Integer] y
    # @param [Integer] nReserved
    # @param [FFI::Pointer] hWnd
    # @param [FFI::Pointer] prcRect
    # @return [true, false]
    def self.TrackPopupMenu(hMenu, uFlags, x, y, nReserved, hWnd, prcRect); end
    attach_function 'TrackPopupMenu', [:hmenu, TrackPopupMenuFlag, :int, :int, :int, :hwnd, RECT.ptr], :bool

    # https://docs.microsoft.com/en-us/windows/desktop/api/winuser/nf-winuser-trackpopupmenuex
    # @param [FFI::Pointer] hMenu
    # @param [Integer] uFlags
    # @param [Integer] x
    # @param [Integer] y
    # @param [FFI::Pointer] hWnd
    # @param [FFI::Pointer] lptpm
    # @return [true, false]
    def self.TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm); end
    attach_function 'TrackPopupMenuEx', [:hmenu, TrackPopupMenuFlag, :int, :int, :hwnd, TPMPARAMS.ptr(:in)], :bool
  end
end


text:
Example projects

## Modules
### robe-chat-server [more...](./robe-chat-server/README.md)
### robe-chat-ui [more...](./robe-chat-ui/README.md)


text:
Me
===

![](./images/favicon-90.png)

Java Developer writes web application.


text:
require 'digest/md5'

module RuboCop
  # ProcessedSource contains objects which are generated by Parser
  # and other information such as disabled lines for cops.
  # It also provides a convenient way to access source lines.
  class ProcessedSource
    STRING_SOURCE_NAME = '(string)'.freeze

    attr_reader :path, :buffer, :ast, :comments, :tokens, :diagnostics,
                :parser_error, :raw_source, :ruby_version

    def self.from_file(path, ruby_version)
      file = File.read(path)
      new(file, ruby_version, path)
    rescue Errno::ENOENT
      raise RuboCop::Error, "No such file or directory: #{path}"
    end

    def initialize(source, ruby_version, path = nil)
      # In Ruby 2, source code encoding defaults to UTF-8. We follow the same
      # principle regardless of which Ruby version we're running under.
      # Encoding comments will override this setting.
      unless source.encoding == Encoding::UTF_8
        source.force_encoding(Encoding::UTF_8)
      end

      @raw_source = source
      @path = path
      @diagnostics = []
      @ruby_version = ruby_version

      parse(source, ruby_version)
    end

    def comment_config
      @comment_config ||= CommentConfig.new(self)
    end

    def disabled_line_ranges
      comment_config.cop_disabled_line_ranges
    end

    def ast_with_comments
      return if !ast || !comments
      @ast_with_comments ||= Parser::Source::Comment.associate(ast, comments)
    end

    # Returns the source lines, line break characters removed, excluding a
    # possible __END__ and everything that comes after.
    def lines
      @lines ||= begin
        all_lines = @buffer.source_lines
        last_token_line = tokens.any? ? tokens.last.pos.line : all_lines.size
        result = []
        all_lines.each_with_index do |line, ix|
          break if ix >= last_token_line && line == '__END__'
          result << line
        end
        result
      end
    end

    def [](*args)
      lines[*args]
    end

    def valid_syntax?
      return false if @parser_error
      @diagnostics.none? { |d| [:error, :fatal].include?(d.level) }
    end

    # Raw source checksum for tracking infinite loops.
    def checksum
      Digest::MD5.hexdigest(@raw_source)
    end

    private

    def parse(source, ruby_version)
      buffer_name = @path || STRING_SOURCE_NAME
      @buffer = Parser::Source::Buffer.new(buffer_name, 1)

      begin
        @buffer.source = source
      rescue EncodingError => error
        @parser_error = error
        return
      end

      parser = create_parser(ruby_version)

      begin
        @ast, @comments, tokens = parser.tokenize(@buffer)
        @ast.complete! if @ast
      rescue Parser::SyntaxError # rubocop:disable Lint/HandleExceptions
        # All errors are in diagnostics. No need to handle exception.
      end

      @tokens = tokens.map { |t| Token.from_parser_token(t) } if tokens
    end

    def parser_class(ruby_version)
      case ruby_version
      when 1.9
        require 'parser/ruby19'
        Parser::Ruby19
      when 2.0
        require 'parser/ruby20'
        Parser::Ruby20
      when 2.1
        require 'parser/ruby21'
        Parser::Ruby21
      when 2.2
        require 'parser/ruby22'
        Parser::Ruby22
      when 2.3
        require 'parser/ruby23'
        Parser::Ruby23
      else
        raise ArgumentError, "Unknown Ruby version: #{ruby_version.inspect}"
      end
    end

    def create_parser(ruby_version)
      builder = RuboCop::Node::Builder.new

      parser_class(ruby_version).new(builder).tap do |parser|
        # On JRuby and Rubinius, there's a risk that we hang in tokenize() if we
        # don't set the all errors as fatal flag. The problem is caused by a bug
        # in Racc that is discussed in issue #93 of the whitequark/parser
        # project on GitHub.
        parser.diagnostics.all_errors_are_fatal = (RUBY_ENGINE != 'ruby')
        parser.diagnostics.ignore_warnings = false
        parser.diagnostics.consumer = lambda do |diagnostic|
          @diagnostics << diagnostic
        end
      end
    end
  end
end


text:
(function (){
var _type,
    _currentDate,
    _tzHours,
    _tzMinutes,
    _tzOffset = 0,
    _min,
    _max,
    _step,
    _shortMonthLabels,
    _longMonthLabels,
    _daysOfWeekLabels,
    _amPmLabels,
    _baseOffset,
    _dragging = false,
    _firstY = 0,
    _scrollListener,
    _endScrollListener;

var ITEM_HEIGHT = (screen.width === 720 && screen.height === 720) ? 91 : 99; // in px, no border

var TIME = 'Time',
    DATE_TIME = 'DateTime',
    DATE_TIME_LOCAL = 'DateTimeLocal',
    DATE = 'Date',
    MONTH = 'Month';

var HOURS = 'Hours',
    MINUTES = 'Minutes',
    YEARMONTHDATE = 'YearMonthDate',
    YEAR = 'Year';

var COLUMNS = {};
COLUMNS[TIME] = [HOURS, MINUTES];
COLUMNS[DATE_TIME] = [YEARMONTHDATE, HOURS, MINUTES];
COLUMNS[DATE_TIME_LOCAL] = [YEARMONTHDATE, HOURS, MINUTES];
COLUMNS[DATE] = [DATE, MONTH, YEAR];
COLUMNS[MONTH] = [MONTH, YEAR];

// Hard limits for internal type. See WebCore/platform/DateComponents.h
var LIMIT_MIN = new Date(-62135596800000.0),
    LIMIT_MAX = new Date(8640000000000000.0);

function parseFromDateString(str) {
    var now = new Date(),
        match;
    if (str) {
        switch (_type) {
        case TIME:
            match = str.match(/(\d+):(\d+)/);
            _tzHours = match[1];
            _tzMinutes = match[2];
            _currentDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), _tzHours, _tzMinutes);
            break;
        case DATE:
            match = str.match(/(\d+)-(\d+)-(\d+)/);
            _currentDate = new Date(match[1], match[2] - 1, match[3]);
            break;
        case MONTH:
            match = str.match(/(\d+)-(\d+)/);
            _currentDate = new Date(match[1], match[2] - 1);
            break;
        case DATE_TIME: // fall-through
        case DATE_TIME_LOCAL:
            match = str.match(/(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)/);
            var utcTime = new Date(match[1], match[2] - 1, match[3], match[4], match[5]);
            if (match = str.match(/(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)+(\d+):(\d+)/)) { // positive timezone offset
                _tzHours = match[6];
                _tzMinutes = match[7];
                _tzOffset = (match[6] * 60 + match[7]) * 60000;
            } else if (result = str.match(/(\d+)-(\d+)-(\d+)[T ](\d+):(\d+)-(\d+):(\d+)/)) { // negative timezone offset
                _tzHours = match[6];
                _tzMinutes = match[7];
                _tzOffset = -(match[6] * 60 + match[7]) * 60000;
            }
            _currentDate = new Date(utcTime.getTime() + _tzOffset);
            break;
        }
    } else {
        switch (_type) {
        case TIME:
        case DATE_TIME:
        case DATE_TIME_LOCAL:
            _currentDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), now.getMinutes());
            break;
        case DATE:
            _currentDate = new Date(now.getFullYear(), now.getMonth(), now.getDate());
            break;
        case MONTH:
            _currentDate = new Date(now.getFullYear(), now.getMonth());
            break;
        }
    }
}

function padTwo(v) { return ('0' + v).substr(-2, 2); }
function padFour(v) { return ('000' + v).substr(-4, 4); }

function getResultString() {
    switch(_type) {
    case TIME:
        return padTwo(_currentDate.getHours()) + ':' + padTwo(_currentDate.getMinutes());
    case DATE_TIME: // fall-through
    case DATE_TIME_LOCAL: // works because _tzOffset for dtlocal is 0
        var adjustedDate = new Date(_currentDate.getTime() - _tzOffset),
            datetime = padFour(adjustedDate.getFullYear()) + '-' + padTwo(adjustedDate.getMonth() + 1) + '-' + padTwo(adjustedDate.getDate()) + 'T' + padTwo(adjustedDate.getHours()) + ':' + padTwo(adjustedDate.getMinutes());
        if (_type === DATE_TIME_LOCAL) {
            return datetime;
        } else if (!_tzOffset) {
            return datetime + 'Z';
        } else if (_tzOffset > 0) {
            return datetime + '+' + padTwo(_tzHours) + ':' + padTwo(_tzMinutes);
        } else {
            return datetime + '-' + padTwo(_tzHours) + ':' + padTwo(_tzMinutes);
        }
    case DATE:
        return padFour(_currentDate.getFullYear()) + '-' + padTwo(_currentDate.getMonth() + 1) + '-' + padTwo(_currentDate.getDate());
    case MONTH:
        return padFour(_currentDate.getFullYear()) + '-' + padTwo(_currentDate.getMonth() + 1);
    }
    return '-1';
}

function ok() {
    document.body.innerHTML = '';
    window.setValueAndClosePopup(getResultString(), window.popUp);
}

function cancel() {
    document.body.innerHTML = '';
    window.setValueAndClosePopup('-1', window.popUp);
}

function adjustColumnLabelsForValue(col) {
    var cloneDate = new Date(_currentDate.getTime()),
        offset = Math.floor(col.children.length / 2);
    switch(col.type) {
    case HOURS:
        // FIXME: 12h/24h
        cloneDate.setHours(cloneDate.getHours() - offset);
        Array.prototype.forEach.call(col.children, function (child) {
            child.innerText = padTwo(cloneDate.getHours());
            cloneDate.setHours(cloneDate.getHours() + 1);
        });
        break;
    case MINUTES:
        cloneDate.setMinutes(cloneDate.getMinutes() - offset);
        Array.prototype.forEach.call(col.children, function (child) {
            child.innerText = padTwo(cloneDate.getMinutes());
            cloneDate.setMinutes(cloneDate.getMinutes() + 1);
        });
        break;
    case YEARMONTHDATE:
        // FIXME: show the year
        cloneDate.setDate(cloneDate.getDate() - offset);
        Array.prototype.forEach.call(col.children, function (child) {
            var dateMonth = document.createElement('div'),
                weekday = document.createElement('div');
            dateMonth.innerText = cloneDate.getDate() + ' ' + _shortMonthLabels[cloneDate.getMonth()]; // FIXME: should localize date as a whole instead of concatenating individual components
            weekday.innerText = _daysOfWeekLabels[cloneDate.getDay()];
            child.innerHTML = '';
            child.appendChild(dateMonth);
            child.appendChild(weekday);
            cloneDate.setDate(cloneDate.getDate() + 1);
        });
        break;
    case DATE:
        cloneDate.setDate(cloneDate.getDate() - offset);
        Array.prototype.forEach.call(col.children, function (child) {
            child.innerText = cloneDate.getDate();
            cloneDate.setDate(cloneDate.getDate() + 1);
        });
        break;
    case MONTH:
        cloneDate.setDate(1); // Otherwise the loop might skip shorter months
        cloneDate.setMonth(cloneDate.getMonth() - offset);
        Array.prototype.forEach.call(col.children, function (child) {
            child.innerText = _longMonthLabels[cloneDate.getMonth()];
            cloneDate.setMonth(cloneDate.getMonth() + 1);
        });
        break;
    case YEAR:
        cloneDate.setYear(cloneDate.getFullYear() - offset);
        Array.prototype.forEach.call(col.children, function (child) {
            child.innerText = padFour(cloneDate.getFullYear());
            cloneDate.setYear(cloneDate.getFullYear() + 1);
        });
        break;
    }
}

function beginScroll(evt) {
    _dragging = true;
    _firstY = evt.clientY || evt.touches[0].screenY;
    _scrollListener = scroll.bind(this);
    _endScrollListener = endScroll.bind(this);
    document.addEventListener('mousemove', _scrollListener);
    document.addEventListener('touchmove', _scrollListener);
    document.addEventListener('mouseup', _endScrollListener);
    document.addEventListener('touchend', _endScrollListener);
}

function scroll(evt) {
    if (_dragging) {
        var clientY = evt.clientY || evt.touches[0].screenY;
        this.getElementsByClassName('tall-bit')[0].style.webkitTransform = 'translateY(' + (clientY - _firstY + _baseOffset) + 'px) translateZ(0)';
    }
}

function endScroll(evt) {
    if (!_dragging) {
        return;
    }

    _dragging = false;
    document.removeEventListener('mousemove', _scrollListener);
    document.removeEventListener('touchmove', _scrollListener);
    document.removeEventListener('mouseup', _endScrollListener);
    document.removeEventListener('touchend', _endScrollListener);
    var clientY = evt.clientY || evt.changedTouches[0].screenY;
    var dy = clientY - _firstY,
        dItems = Math.floor(dy / ITEM_HEIGHT),
        extra = dy % ITEM_HEIGHT;
    if (extra < 0) {
        dItems++;
    }
    // Fudge: which item is actually mostly in the window?
    if (extra > ITEM_HEIGHT / 2) {
        // you've moved down more than half the next element, move some more
        dItems++;
        extra -= ITEM_HEIGHT;
    } else if (extra < -ITEM_HEIGHT / 2) {
        dItems--;
        extra += ITEM_HEIGHT;
    }
    var oldDate = new Date(_currentDate.getTime());
    switch(this.type) {
    case HOURS:
    case MINUTES:
    case DATE:
    case MONTH:
        _currentDate['set' + this.type](_currentDate['get' + this.type]() - dItems);
        break;
    case YEAR:
        _currentDate.setFullYear(_currentDate.getFullYear() - dItems);
        break;
    case YEARMONTHDATE:
        _currentDate.setDate(_currentDate.getDate() - dItems);
        break;
    }

    // TODO: animate the extraneous column changes
    // animate the one changed tallbit manually
    var tallBit = this.getElementsByClassName('tall-bit')[0];
    tallBit.style.webkitTransition = '-webkit-transform ' + Math.abs(extra * 2) + 'ms ease-out';
    tallBit.style.webkitTransform = 'translateY(' + (_baseOffset + dy - extra) + 'px) translateZ(0)';
    // use a timer instead of webkitTransitionEnd in case webkitTransitionEnd doesn't fire (happens if it skips all frames)
    setTimeout(function () {
        tallBit.style.webkitTransition = '';
        var tallBits = document.getElementsByClassName('tall-bit');
        Array.prototype.forEach.call(tallBits, function (tall) {
            switch(tall.type) {
            case HOURS:
            case MINUTES:
            case DATE:
            case MONTH:
                if (oldDate['get' + tall.type]() !== _currentDate['get' + tall.type]()) {
                    adjustColumnLabelsForValue(tall);
                }
                break;
            case YEAR:
                if (oldDate.getFullYear() !== _currentDate.getFullYear()) {
                    adjustColumnLabelsForValue(tall);
                }
                break;
            case YEARMONTHDATE:
                if (oldDate.getFullYear() !== _currentDate.getFullYear()
                    || oldDate.getMonth() !== _currentDate.getMonth()
                    || oldDate.getDate() !== _currentDate.getDate()
                ) {
                    adjustColumnLabelsForValue(tall);
                }
                break;
            }
        });
        resetPositions();
    }, Math.abs(extra * 2) + 1);
}

function createColumn(type) {
    var col = document.createElement('div'),
        tallBit = document.createElement('div');
    col.className = 'column ' + type;
    col.type = type;
    tallBit.className = 'tall-bit';
    tallBit.type = type;
    col.appendChild(tallBit);

    var numCells = Math.ceil(Math.max(screen.height, screen.width) / ITEM_HEIGHT) * 2 + 1;
    for (var i = 0; i < numCells; ++i) {
        var cell = document.createElement('div');
        cell.className = 'cell';
        tallBit.appendChild(cell);
    }

    adjustColumnLabelsForValue(tallBit);

    col.addEventListener('mousedown', beginScroll);
    col.addEventListener('touchstart', beginScroll);

    return col;
}

function resetPositions() {
    var tallBits = document.getElementsByClassName('tall-bit');
    Array.prototype.forEach.call(tallBits, function (tallBit) {
        tallBit.style.webkitTransform = 'translateY(' + _baseOffset + 'px) translateZ(0)';
    });
}

function show(pickerParams) {
    _type = pickerParams.type;
    parseFromDateString(pickerParams.initialValue);
    _min = pickerParams.min; // FIXME: min not supported
    _max = pickerParams.max; // FIXME: max not supported
    _step = pickerParams.step; // FIXME: step not supported
    // FIXME: disabled not supported (need to get this state passed in)

    _shortMonthLabels = pickerParams.uiText.shortMonthLabels;
    _longMonthLabels = pickerParams.uiText.monthLabels;
    _daysOfWeekLabels = pickerParams.uiText.daysOfWeekLabels;
    _amPmLabels = pickerParams.uiText.amPmLabels;

    if (!_currentDate) {
        // Parse failed
        cancel();
    }

    if (_currentDate < LIMIT_MIN) {
        _currentDate = new Date(LIMIT_MIN.getTime());
    } else if (_currentDate > LIMIT_MAX) {
        _currentDate = new Date(LIMIT_MAX.getTime());
    }

    // Set up the UI
    var popup = document.createElement('div');
    popup.className = popup.id = 'popup-area';
    popup.dir = pickerParams.direction;
    var header = document.createElement('div');
    header.className = 'popup-header';
    header.innerText = pickerParams.uiText.title;
    popup.appendChild(header);
    var content = document.createElement('div');
    content.className = 'popup-content';
    content.dir = 'ltr'; // FIXME: RTL UI specifications not done yet
    content.id = 'popup-content-time';
    popup.appendChild(content);

    COLUMNS[_type].forEach(function (type) {
        content.appendChild(createColumn(type));
    });

    var rowHighlightContainer = document.createElement('div'),
        filler1 = document.createElement('div'),
        selectedRowHighlight = document.createElement('div'),
        filler2 = document.createElement('div');
    rowHighlightContainer.className = 'row-highlight-container';
    selectedRowHighlight.className = 'row-highlight';
    filler1.className = filler2.className = 'row-highlight-filler';
    rowHighlightContainer.appendChild(filler1);
    rowHighlightContainer.appendChild(selectedRowHighlight);
    rowHighlightContainer.appendChild(filler2);
    content.appendChild(rowHighlightContainer);

    var okButton = document.createElement('button'),
        cancelButton = document.createElement('button'),
        buttons = document.createElement('div');
    buttons.className = 'popup-buttons';
    okButton.className = 'popup-button';
    okButton.innerText = pickerParams.uiText.doneButtonLabel;
    okButton.addEventListener('click', ok);
    cancelButton.className = 'popup-button';
    cancelButton.innerText = pickerParams.uiText.cancelButtonLabel;
    cancelButton.addEventListener('click', cancel);
    buttons.appendChild(cancelButton);
    buttons.appendChild(okButton);

    popup.appendChild(buttons);

    document.body.appendChild(popup);

    _baseOffset = Math.floor(document.getElementsByClassName('column')[0].clientHeight / 2 - document.getElementsByClassName('tall-bit')[0].clientHeight / 2);
    resetPositions();
}

window.popupcontrol = window.popupcontrol || {};
window.popupcontrol.show = show;
}());