text:
/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50 */
/*global define, $, CodeMirror, window */

/**
 * EditorManager owns the UI for the editor area. This essentially mirrors the 'current document'
 * property maintained by DocumentManager's model.
 *
 * Note that there is a little bit of unusual overlap between EditorManager and DocumentManager:
 * because the Document state is actually stored in the CodeMirror editor UI, DocumentManager is
 * not a pure headless model. Each Document encapsulates an editor instance, and thus EditorManager
 * must have some knowledge about Document's internal state (we access its _editor property).
 *
 * This module dispatches the following events:
 *    - activeEditorChange --  Fires after the active editor (full or inline) changes and size/visibility
 *                             are complete. Doesn't fire when editor temporarily loses focus to a non-editor
 *                             control (e.g. search toolbar or modal dialog, or window deactivation). Does
 *                             fire when focus moves between inline editor and its full-size container.
 *                             This event tracks getActiveEditor() changes, while DocumentManager's
 *                             currentDocumentChange tracks getCurrentFullEditor() changes.
 *                             The 2nd arg to the listener is which Editor became active; the 3rd arg is
 *                             which Editor is deactivated as a result. Either one may be null.
 *                             NOTE (#1257): getFocusedEditor() sometimes lags behind this event. Listeners
 *                             should use the arguments or call getActiveEditor() to reliably see which Editor
 *                             just gained focus.
 */
define(function (require, exports, module) {
    "use strict";

    // Load dependent modules
    var AppInit             = require("utils/AppInit"),
        FileUtils           = require("file/FileUtils"),
        Commands            = require("command/Commands"),
        CommandManager      = require("command/CommandManager"),
        DocumentManager     = require("document/DocumentManager"),
        PerfUtils           = require("utils/PerfUtils"),
        Editor              = require("editor/Editor").Editor,
        InlineTextEditor    = require("editor/InlineTextEditor").InlineTextEditor,
        KeyEvent            = require("utils/KeyEvent"),
        EditorUtils         = require("editor/EditorUtils"),
        ViewUtils           = require("utils/ViewUtils"),
        StatusBar           = require("widgets/StatusBar"),
        Strings             = require("strings"),
        StringUtils         = require("utils/StringUtils");

    /** @type {jQueryObject} DOM node that contains all editors (visible and hidden alike) */
    var _editorHolder = null;

    /**
     * Currently visible full-size Editor, or null if no editors open
     * @type {?Editor}
     */
    var _currentEditor = null;
    /** @type {?Document} */
    var _currentEditorsDocument = null;

    /**
     * Currently focused Editor (full-size, inline, or otherwise)
     * @type {?Editor}
     */
    var _lastFocusedEditor = null;

    /**
     * Registered inline-editor widget providers. See {@link #registerInlineEditProvider()}.
     * @type {Array.<function(...)>}
     */
    var _inlineEditProviders = [];

    /* StatusBar indicators */
    var $modeInfo,
        $cursorInfo,
        $fileInfo,
        $indentType,
        $indentWidthLabel,
        $indentWidthInput;

    /**
     * Adds keyboard command handlers to an Editor instance.
     * @param {Editor} editor
     * @param {!Object.<string,function(Editor)>} to destination key mapping
     * @param {!Object.<string,function(Editor)>} from source key mapping
     */
    function mergeExtraKeys(editor, to, from) {
        // Merge in the additionalKeys we were passed
        function wrapEventHandler(externalHandler) {
            return function (instance) {
                externalHandler(editor);
            };
        }
        var key;
        for (key in from) {
            if (from.hasOwnProperty(key)) {
                if (to.hasOwnProperty(key)) {
                    console.log("Warning: overwriting standard Editor shortcut " + key);
                }
                to[key] = (editor !== null) ? wrapEventHandler(from[key]) : from[key];
            }
        }
    }

    /**
     * Creates a new Editor bound to the given Document. The editor's mode is inferred based on the
     * file extension. The editor is appended to the given container as a visible child.
     * @param {!Document} doc  Document for the Editor's content
     * @param {!boolean} makeMasterEditor  If true, the Editor will set itself as the private "master"
     *          Editor for the Document. If false, the Editor will attach to the Document as a "slave."
     * @param {!jQueryObject} container  Container to add the editor to.
     * @param {{startLine: number, endLine: number}=} range If specified, range of lines within the document
     *          to display in this editor. Inclusive.
     * @return {Editor} the newly created editor.
     */
    function _createEditorForDocument(doc, makeMasterEditor, container, range, additionalKeys) {
        var mode = EditorUtils.getModeFromFileExtension(doc.file.fullPath);

        return new Editor(doc, makeMasterEditor, mode, container, additionalKeys, range);
    }

    /**
     * @private
     * Bound to Ctrl+E on outermost editors.
     * @param {!Editor} editor the candidate host editor
     * @return {$.Promise} a promise that will be resolved when an InlineWidget
     *      is created or rejected when no inline editors are available.
     */
    function _openInlineWidget(editor) {
        PerfUtils.markStart(PerfUtils.INLINE_EDITOR_OPEN);

        // Run through inline-editor providers until one responds
        var pos = editor.getCursorPos(),
            inlinePromise,
            i,
            result = new $.Deferred();

        for (i = 0; i < _inlineEditProviders.length && !inlinePromise; i++) {
            var provider = _inlineEditProviders[i];
            inlinePromise = provider(editor, pos);
        }

        // If one of them will provide a widget, show it inline once ready
        if (inlinePromise) {
            inlinePromise.done(function (inlineWidget) {
                editor.addInlineWidget(pos, inlineWidget);
                PerfUtils.addMeasurement(PerfUtils.INLINE_EDITOR_OPEN);
                result.resolve();
            }).fail(function () {
                // terminate timer that was started above
                PerfUtils.finalizeMeasurement(PerfUtils.INLINE_EDITOR_OPEN);
                result.reject();
            });
        } else {
            // terminate timer that was started above
            PerfUtils.finalizeMeasurement(PerfUtils.INLINE_EDITOR_OPEN);
            result.reject();
        }

        return result.promise();
    }

    /**
     * Removes the given widget UI from the given hostEditor (agnostic of what the widget's content
     * is). The widget's onClosed() callback will be run as a result.
     * @param {!Editor} hostEditor The editor containing the widget.
     * @param {!InlineWidget} inlineWidget The inline widget to close.
     * @param {!boolean} moveFocus  If true, focuses hostEditor and ensures the cursor position lies
     *      near the inline's location.
     */
    function closeInlineWidget(hostEditor, inlineWidget, moveFocus) {
        if (moveFocus) {
            // Place cursor back on the line just above the inline (the line from which it was opened)
            // If cursor's already on that line, leave it be to preserve column position
            var widgetLine = hostEditor._codeMirror.getInlineWidgetInfo(inlineWidget.id).line;
            var cursorLine = hostEditor.getCursorPos().line;
            if (cursorLine !== widgetLine) {
                hostEditor.setCursorPos({ line: widgetLine, pos: 0 });
            }

            hostEditor.focus();
        }

        hostEditor.removeInlineWidget(inlineWidget);
    }

    /**
     * Registers a new inline provider. When _openInlineWidget() is called each registered inline
     * widget is called and asked if it wants to provide an inline widget given the current cursor
     * location and document.
     * @param {function} provider
     *      Parameters:
     *      {!Editor} editor, {!{line:Number, ch:Number}} pos
     *
     *      Returns:
     *      {$.Promise} a promise that will be resolved with an inlineWidget
     *      or null to indicate the provider doesn't create an editor in this case
     */
    function registerInlineEditProvider(provider) {
        _inlineEditProviders.push(provider);
    }

    /**
     * @private
     * Given a host editor, return a list of all Editors in all its open inline widgets. (Ignoring
     * any other inline widgets that might be open but don't contain Editors).
     * @param {!Editor} hostEditor
     * @return {Array.<Editor>}
     *
     */
    function getInlineEditors(hostEditor) {
        var inlineEditors = [];

        if (hostEditor) {
            hostEditor.getInlineWidgets().forEach(function (widget) {
                if (widget instanceof InlineTextEditor) {
                    inlineEditors = inlineEditors.concat(widget.editors);
                }
            });
        }

        return inlineEditors;
    }

    /**
     * @private
     * Creates a new "full-size" (not inline) Editor for the given Document, and sets it as the
     * Document's master backing editor. The editor is not yet visible; to show it, use
     * DocumentManager.setCurrentDocument().
     * Semi-private: should only be called within this module or by Document.
     * @param {!Document} document  Document whose main/full Editor to create
     */
    function _createFullEditorForDocument(document) {
        // Create editor; make it initially invisible
        var container = _editorHolder.get(0);
        var editor = _createEditorForDocument(document, true, container);
        editor.setVisible(false);
    }

    /** Returns the visible full-size Editor corresponding to DocumentManager.getCurrentDocument() */
    function getCurrentFullEditor() {
        // This *should* always be equivalent to DocumentManager.getCurrentDocument()._masterEditor
        return _currentEditor;
    }

    /**
     * Creates a new inline Editor instance for the given Document. The editor's mode is inferred
     * based on the file extension. The editor is not yet visible or attached to a host editor.
     * @param {!Document} doc  Document for the Editor's content
     * @param {?{startLine:Number, endLine:Number}} range  If specified, all lines outside the given
     *      range are hidden from the editor. Range is inclusive. Line numbers start at 0.
     * @param {HTMLDivContainer} inlineContent
     * @param  {function(inlineWidget)} closeThisInline
     *
     * @return {{content:DOMElement, editor:Editor}}
     */
    function createInlineEditorForDocument(doc, range, inlineContent, additionalKeys) {
        // Create the Editor
        var inlineEditor = _createEditorForDocument(doc, false, inlineContent, range, additionalKeys);

        return { content: inlineContent, editor: inlineEditor };
    }

    /**
     * Disposes the given Document's full-size editor if the doc is no longer "open" from the user's
     * standpoint - not in the working set and not currentDocument).
     *
     * Destroying the full-size editor releases ONE ref to the Document; if inline editors or other
     * UI elements are still referencing the Document it will still be 'open' (kept alive) from
     * DocumentManager's standpoint. However, destroying the full-size editor does remove the backing
     * "master" editor from the Document, rendering it immutable until either inline-editor edits or
     * currentDocument change triggers _createFullEditorForDocument() full-size editor again.
     *
     * In certain edge cases, this is called directly by DocumentManager; see _gcDocuments() for details.
     *
     * @param {!Document} document Document whose "master" editor we may destroy
     */
    function _destroyEditorIfUnneeded(document) {
        var editor = document._masterEditor;

        if (!editor) {
            return;
        }

        // If outgoing editor is no longer needed, dispose it
        var isCurrentDocument = (DocumentManager.getCurrentDocument() === document);
        var isInWorkingSet = (DocumentManager.findInWorkingSet(document.file.fullPath) !== -1);
        if (!isCurrentDocument && !isInWorkingSet) {
            // Destroy the editor widget (which un-refs the Document and reverts it to read-only mode)
            editor.destroy();

            // Our callers should really ensure this, but just for safety...
            if (_currentEditor === editor) {
                _currentEditorsDocument = null;
                _currentEditor = null;
            }
        }
    }

    /**
     * Returns focus to the last visible editor that had focus. If no editor visible, does nothing.
     * This function should be called to restore editor focus after it has been temporarily
     * removed. For example, after a dialog with editable text is closed.
     */
    function focusEditor() {
        if (_lastFocusedEditor) {
            _lastFocusedEditor.focus();
        }
    }

    /**
     * Calculates the available height for the full-size Editor (or the no-editor placeholder),
     * accounting for the current size of all visible panels, toolbar, & status bar.
     * @return {number}
     */
    function _calcEditorHeight() {
        var availableHt = $(".content").height();

        _editorHolder.siblings().each(function (i, elem) {
            var $elem = $(elem);
            if ($elem.css("display") !== "none") {
                availableHt -= $elem.outerHeight();
            }
        });
        return availableHt;
    }

    /**
     * Resize the editor. This must be called any time the contents of the editor area are swapped
     * or any time the editor area might change height. EditorManager takes care of calling this when
     * the Editor is swapped, and on window resize. But anyone who changes size/visiblity of editor
     * area siblings (toolbar, status bar, bottom panels) *must* manually call resizeEditor().
     *
     * @param {boolean=} skipRefresh For internal use, to avoid redundant refresh()es during window resize
     */
    function resizeEditor(skipRefresh) {
        if (!_editorHolder) {
            return;  // still too early during init
        }

        var editorAreaHt = _calcEditorHeight();
        _editorHolder.height(editorAreaHt);    // affects size of "not-editor" placeholder as well

        if (_currentEditor) {
            $(_currentEditor.getScrollerElement()).height(editorAreaHt);
            if (!skipRefresh) {
                _currentEditor.refresh();
            }
        }
    }

    /**
     * NJ's editor-resizing fix. Whenever the window resizes, we immediately adjust the editor's
     * height.
     */
    function _updateEditorDuringResize() {
        // skipRefresh=true since CodeMirror will call refresh() itself when it sees the resize event
        resizeEditor(true);
    }

    /**
     * @private
     * @param {?Editor} current
     */
    function _notifyActiveEditorChanged(current) {
        // Skip if the Editor that gained focus was already the most recently focused editor.
        // This may happen e.g. if the window loses then regains focus.
        if (_lastFocusedEditor === current) {
            return;
        }
        var previous = _lastFocusedEditor;
        _lastFocusedEditor = current;

        $(exports).triggerHandler("activeEditorChange", [current, previous]);
    }

    /**
     * @private
     */
    function _doShow(document) {
        // Show new editor
        _currentEditorsDocument = document;
        _currentEditor = document._masterEditor;

        _currentEditor.setVisible(true);
        _currentEditor.focus();

        // Window may have been resized since last time editor was visible, so kick it now
        resizeEditor();
    }

    /**
     * Make the given document's editor visible in the UI, hiding whatever was
     * visible before. Creates a new editor if none is assigned.
     * @param {!Document} document
     */
    function _showEditor(document) {
        // Hide whatever was visible before
        if (!_currentEditor) {
            $("#not-editor").css("display", "none");
        } else {
            _currentEditor.setVisible(false);
            _destroyEditorIfUnneeded(_currentEditorsDocument);
        }

        // Ensure a main editor exists for this document to show in the UI
        if (!document._masterEditor) {
            // Editor doesn't exist: populate a new Editor with the text
            _createFullEditorForDocument(document);
        }

        _doShow(document);
    }

    /** Hide the currently visible editor and show a placeholder UI in its place */
    function _showNoEditor() {
        if (_currentEditor) {
            _currentEditor.setVisible(false);
            _destroyEditorIfUnneeded(_currentEditorsDocument);

            _currentEditorsDocument = null;
            _currentEditor = null;

            $("#not-editor").css("display", "");

            // No other Editor is gaining focus, so in this one special case we must trigger event manually
            _notifyActiveEditorChanged(null);
        }
    }

    /** Handles changes to DocumentManager.getCurrentDocument() */
    function _onCurrentDocumentChange() {
        var doc = DocumentManager.getCurrentDocument(),
            container = _editorHolder.get(0);

        var perfTimerName = PerfUtils.markStart("EditorManager._onCurrentDocumentChange():\t" + (!doc || doc.file.fullPath));

        // Remove scroller-shadow from the current editor
        if (_currentEditor) {
            ViewUtils.removeScrollerShadow(container, _currentEditor);
        }

        // Update the UI to show the right editor (or nothing), and also dispose old editor if no
        // longer needed.
        if (doc) {
            _showEditor(doc);
            ViewUtils.addScrollerShadow(container, _currentEditor);
        } else {
            _showNoEditor();
        }

        PerfUtils.addMeasurement(perfTimerName);
    }

    /** Handles removals from DocumentManager's working set list */
    function _onWorkingSetRemove(event, removedFile) {
        // There's one case where an editor should be disposed even though the current document
        // didn't change: removing a document from the working set (via the "X" button). (This may
        // also cover the case where the document WAS current, if the editor-swap happens before the
        // removal from the working set.
        var doc = DocumentManager.getOpenDocumentForPath(removedFile.fullPath);
        if (doc) {
            _destroyEditorIfUnneeded(doc);
        }
        // else, file was listed in working set but never shown in the editor - ignore
    }

    function _onWorkingSetRemoveList(event, removedFiles) {
        removedFiles.forEach(function (removedFile) {
            _onWorkingSetRemove(event, removedFile);
        });
    }

    // Note: there are several paths that can lead to an editor getting destroyed
    //  - file was in working set, but not in current editor; then closed (via working set "X" button)
    //      --> handled by _onWorkingSetRemove()
    //  - file was in current editor, but not in working set; then navigated away from
    //      --> handled by _onCurrentDocumentChange()
    //  - file was in current editor, but not in working set; then closed (via File > Close) (and thus
    //    implicitly navigated away from)
    //      --> handled by _onCurrentDocumentChange()
    //  - file was in current editor AND in working set; then closed (via File > Close OR working set
    //    "X" button) (and thus implicitly navigated away from)
    //      --> handled by _onWorkingSetRemove() currently, but could be _onCurrentDocumentChange()
    //      just as easily (depends on the order of events coming from DocumentManager)

    /**
     * Designates the DOM node that will contain the currently active editor instance. EditorManager
     * will own the content of this DOM node.
     * @param {!jQueryObject} holder
     */
    function setEditorHolder(holder) {
        if (_currentEditor) {
            throw new Error("Cannot change editor area after an editor has already been created!");
        }

        _editorHolder = holder;

        resizeEditor();  // if no files open at startup, we won't get called back later to resize the "no-editor" placeholder
    }

    /**
     * Returns the currently focused inline widget.
     * @returns {?{widget:!InlineTextEditor, editor:!Editor}}
     */
    function getFocusedInlineWidget() {
        var result = null;

        if (_currentEditor) {
            _currentEditor.getInlineWidgets().forEach(function (widget) {
                if (widget instanceof InlineTextEditor) {
                    widget.editors.forEach(function (editor) {
                        if (editor.hasFocus()) {
                            result = { widget: widget, editor: editor };
                        }
                    });
                }
            });
        }

        return result;
    }

    function _getFocusedInlineEditor() {
        var focusedInline = getFocusedInlineWidget();
        if (focusedInline) {
            return focusedInline.editor;
        }

        return null;
    }

    /**
     * Returns the currently focused editor instance (full-sized OR inline editor).
     * This function is similar to getActiveEditor(), with one main difference: this
     * function will only return editors that currently have focus, whereas
     * getActiveEditor() will return the last visible editor that was given focus (but
     * may not currently have focus because, for example, a dialog with editable text
     * is open).
     * @returns {Editor}
     */
    function getFocusedEditor() {
        if (_currentEditor) {

            // See if any inlines have focus
            var focusedInline = _getFocusedInlineEditor();
            if (focusedInline) {
                return focusedInline;
            }

            // otherwise, see if full-sized editor has focus
            if (_currentEditor.hasFocus()) {
                return _currentEditor;
            }
        }

        return null;
    }

    /**
     * Returns the current active editor (full-sized OR inline editor). This editor may not
     * have focus at the moment, but it is visible and was the last editor that was given
     * focus. Returns null if no editors are active.
     * @see getFocusedEditor()
     * @returns {Editor}
     */
    function getActiveEditor() {
        return _lastFocusedEditor;
    }

    /**
     * Toggle Quick Edit command handler
     * @return {!Promise} A promise resolved with true if an inline editor
     *   is opened or false when closed. The promise is rejected if there
     *   is no current editor or an inline editor is not created.
     */
    function _toggleQuickEdit() {
        var result = new $.Deferred();

        if (_currentEditor) {
            var inlineWidget = null,
                focusedWidgetResult = getFocusedInlineWidget();

            if (focusedWidgetResult) {
                inlineWidget = focusedWidgetResult.widget;
            }

            if (inlineWidget) {
                // an inline widget's editor has focus, so close it
                PerfUtils.markStart(PerfUtils.INLINE_EDITOR_CLOSE);
                inlineWidget.close();
                PerfUtils.addMeasurement(PerfUtils.INLINE_EDITOR_CLOSE);

                // return a resolved promise to CommandManager
                result.resolve(false);
            } else {
                // main editor has focus, so create an inline editor
                _openInlineWidget(_currentEditor).done(function () {
                    result.resolve(true);
                }).fail(function () {
                    result.reject();
                });
            }
        } else {
            // Can not open an inline editor without a host editor
            result.reject();
        }

        return result.promise();
    }

    function _updateModeInfo(editor) {
        $modeInfo.text(StatusBar.getModeDisplayString(editor.getModeForDocument()));
    }

    function _updateFileInfo(editor) {
        $fileInfo.text(StringUtils.format(Strings.STATUSBAR_LINE_COUNT, editor.lineCount()));
    }

    function _updateIndentType() {
        var indentWithTabs = Editor.getUseTabChar();
        $indentType.text(indentWithTabs ? Strings.STATUSBAR_TAB_SIZE : Strings.STATUSBAR_SPACES);
        $indentType.attr("title", indentWithTabs ? Strings.STATUSBAR_INDENT_TOOLTIP_SPACES : Strings.STATUSBAR_INDENT_TOOLTIP_TABS);
        $indentWidthLabel.attr("title", indentWithTabs ? Strings.STATUSBAR_INDENT_SIZE_TOOLTIP_TABS : Strings.STATUSBAR_INDENT_SIZE_TOOLTIP_SPACES);
    }

    function _getIndentSize() {
        return Editor.getUseTabChar() ? Editor.getTabSize() : Editor.getIndentUnit();
    }

    function _updateIndentSize() {
        var size = _getIndentSize();
        $indentWidthLabel.text(size);
        $indentWidthInput.val(size);
    }

    function _toggleIndentType() {
        Editor.setUseTabChar(!Editor.getUseTabChar());
        _updateIndentType();
        _updateIndentSize();
    }

    function _updateCursorInfo(event, editor) {
        editor = editor || getFocusedEditor();

        // compute columns, account for tab size
        var cursor = editor.getCursorPos(true);

        $cursorInfo.text(StringUtils.format(Strings.STATUSBAR_CURSOR_POSITION, cursor.line + 1, cursor.ch + 1));
    }

    function _changeIndentWidth(value) {
        $indentWidthLabel.removeClass("hidden");
        $indentWidthInput.addClass("hidden");

        // remove all event handlers from the input field
        $indentWidthInput.off("blur keyup");

        // restore focus to the editor
        focusEditor();

        if (!value || isNaN(value)) {
            return;
        }

        if (Editor.getUseTabChar()) {
            Editor.setTabSize(Math.max(Math.min(value, 10), 1));
        } else {
            Editor.setIndentUnit(Math.max(Math.min(value, 10), 1));
        }

        // update indicator
        _updateIndentSize();

        // column position may change when tab size changes
        _updateCursorInfo();
    }

    function _onActiveEditorChange(event, current, previous) {
        if (previous) {
            $(previous).off("cursorActivity.statusbar");
            $(previous).off("change.statusbar");
        }

        if (!current) {
            StatusBar.hide();  // calls resizeEditor() if needed
        } else {
            StatusBar.show();  // calls resizeEditor() if needed

            $(current).on("cursorActivity.statusbar", _updateCursorInfo);
            $(current).on("change.statusbar", function () {
                // async update to keep typing speed smooth
                window.setTimeout(function () { _updateFileInfo(current); }, 0);
            });

            _updateCursorInfo(null, current);
            _updateModeInfo(current);
            _updateFileInfo(current);
            _updateIndentType();
            _updateIndentSize();
        }
    }

    function _onFileNameChange(event, oldName, newName) {

        // The current document file entry has already been updated.
        // We only need to update the editor mode to match the new file extension
        var editor = getCurrentFullEditor();

        if (editor && editor.document.file.fullPath === newName) {
            editor.setModeForDocument(
                EditorUtils.getModeFromFileExtension(editor.document.file.fullPath)
            );
        }
    }

    function _init() {
        StatusBar.init($(".main-view .content"));

        $modeInfo           = $("#status-mode");
        $cursorInfo         = $("#status-cursor");
        $fileInfo           = $("#status-file");
        $indentType         = $("#indent-type");
        $indentWidthLabel   = $("#indent-width-label");
        $indentWidthInput   = $("#indent-width-input");

        // indentation event handlers
        $indentType.on("click", _toggleIndentType);
        $indentWidthLabel
            .on("click", function () {
                // update the input value before displaying
                $indentWidthInput.val(_getIndentSize());

                $indentWidthLabel.addClass("hidden");
                $indentWidthInput.removeClass("hidden");
                $indentWidthInput.focus();

                $indentWidthInput
                    .on("blur", function () {
                        _changeIndentWidth($indentWidthInput.val());
                    })
                    .on("keyup", function (event) {
                        if (event.keyCode === KeyEvent.DOM_VK_RETURN) {
                            $indentWidthInput.blur();
                        } else if (event.keyCode === KeyEvent.DOM_VK_ESCAPE) {
                            _changeIndentWidth(false);
                        }
                    });
            });

        $indentWidthInput.focus(function () { $indentWidthInput.select(); });

        _onActiveEditorChange(null, getFocusedEditor(), null);
    }

    // Initialize: command handlers
    CommandManager.register(Strings.CMD_TOGGLE_QUICK_EDIT, Commands.TOGGLE_QUICK_EDIT, _toggleQuickEdit);

    // Initialize: register listeners
    $(DocumentManager).on("currentDocumentChange", _onCurrentDocumentChange);
    $(DocumentManager).on("workingSetRemove", _onWorkingSetRemove);
    $(DocumentManager).on("workingSetRemoveList", _onWorkingSetRemoveList);
    $(DocumentManager).on("fileNameChange", _onFileNameChange);

    // Add this as a capture handler so we're guaranteed to run it before the editor does its own
    // refresh on resize.
    window.addEventListener("resize", _updateEditorDuringResize, true);

    // Initialize: status bar focused listener
    $(exports).on("activeEditorChange", _onActiveEditorChange);

    AppInit.htmlReady(_init);

    // For unit tests and internal use only
    exports._init = _init;
    exports._openInlineWidget = _openInlineWidget;
    exports._notifyActiveEditorChanged = _notifyActiveEditorChanged;
    exports._createFullEditorForDocument = _createFullEditorForDocument;
    exports._destroyEditorIfUnneeded = _destroyEditorIfUnneeded;

    // Define public API
    exports.setEditorHolder = setEditorHolder;
    exports.getCurrentFullEditor = getCurrentFullEditor;
    exports.createInlineEditorForDocument = createInlineEditorForDocument;
    exports.focusEditor = focusEditor;
    exports.getFocusedEditor = getFocusedEditor;
    exports.getActiveEditor = getActiveEditor;
    exports.getFocusedInlineWidget = getFocusedInlineWidget;
    exports.resizeEditor = resizeEditor;
    exports.registerInlineEditProvider = registerInlineEditProvider;
    exports.getInlineEditors = getInlineEditors;
    exports.closeInlineWidget = closeInlineWidget;
    exports.mergeExtraKeys = mergeExtraKeys;
});

redpajama_set_name: RedPajamaGithub


text:
Les serps, serpents (Serpentes) o ofidis (Ophidia) són un subordre de sauròpsids (rèptils) amb el cos molt allargat i mancats de potes. Se les pot distingir de les sargantanes sense potes per la seva manca de parpelles i d'orelles externes. Com tots els escatosos, les serps són vertebrats amniotes ectoterms coberts per escates. Com les sargantanes, de les quals evolucionaren, tenen un crani d'articulació laxa, i la majoria poden dislocar el maxil·lar inferior per tal d'ingerir preses molt més grans que el seu propi cap. Per tal d'acomodar el seu cos estret, els òrgans parells de les serps (com ara els ronyons) es troben l'un al davant de l'altre en lloc d'estar al costat, i només tenen un pulmó funcional. Algunes espècies conserven una pelvis amb un parell d'urpes vestigials a banda i banda de la cloaca.

Les serps han colonitzat un ampli ventall d'hàbitats de tot el món, excepte a Alaska i el nord del Canadà al continent americà, Groenlàndia, Islàndia, Irlanda i l'extrem nord d'Escandinàvia i Rússia a Euràsia, i l'Antàrtida i Nova Zelanda al sud. Se'n reconeixen quinze famílies, que inclouen 456 gèneres i més de 2.900 espècies. La seva mida varia des dels 10 cm de llarg de la minúscula Leptotyphlops carlae fins als 7,6 metres de les anacondes i els pitons. Titanoboa, descoberta recentment, fou una serp del Paleocè que assolí una llargada de 13 metres. Es creu que les serps evolucionaren de sargantanes excavadores o aquàtiques durant el període Cretaci (fa uns 150 milions d'anys). La diversitat de serps modernes aparegué durant el Paleocè (entre fa  i fa  milions d'anys).

La majoria d'espècies no són verinoses, i les que ho són utilitzen el verí més aviat per matar i sotmetre les preses que per autodefensa. Tanmateix, algunes tenen un verí prou potent com per a causar lesions doloroses o, fins i tot, la mort als humans.

Característiques

Les serps tenen les parpelles soldades i transparents, no tenen timpà, tenen la llengua llarga, bífida i evaginable, la mandíbula està dividida en dues parts unides per un lligament elàstic, i moltes espècies tenen glàndules verinoses i dents adaptades a la inoculació de verí; el crani molt mòbil (cinètic) a causa de la pèrdua o reducció de diversos ossos. Tenen una sola filera d'escates ventrals; tenen un sol pulmó (el dret). Són poiquilotermes, és a dir, no poden regular la temperatura del cos i això fa que aquesta depengui de la del medi.

Pell
La pell està recoberta per escates, quan la muden, és dita «camisa», «despullada» o «esquira» de la serp. La major part de les serps utilitzen escates especialitzades de la part ventral per a desplaçar-se, aferrant-s'hi a les superfícies. Les seves parpelles es troben permanentment tancades, però són en realitat escates transparents. Les serps canvien de pell periòdicament. A diferència d'altres rèptils, el canvi o muda de pell és fet en una peça, com si estirés una mitja. Això es fa a mesura que l'animal creix i a més, per reparar ferides i alliberar-se de paràsits externs. La renovació periòdica ha convertit a la serp en un símbol de salut i medicina, com es mostra a la vara d'Asclepi (vegeu Asclepi).

Locomoció
La locomoció es realitza mitjançant ondulacions laterals del cos, les escates ventrals eixamplades de moltes serps impedeixen el lliscament. Algunes serps, com certes boes i els escurçons poden desplaçar-se també mitjançant moviments musculars de les escates ventrals amb el seu cos estès gairebé en línia recta.

Esquelet

L'esquelet té moltes vèrtebres, 200 en l'escurçó i 400 en els pitons. El crani està molt modificat respecte al model bàsic diàpsid. Els ossos de la mandíbula superior estan feblement units a la resta del crani i el quadrat es pot moure lliurement i posseeix potents músculs refractors, el que permet una enorme obertura de les mandíbules i la deglució de grans preses senceres. Les dents són agudes i corbades cap enrere i s'implanten tant al paladar com en el maxil·lar i el dental. Les boes i els pitons posseeixen rudiments de les extremitats posteriors i de les seves cintures; en aquestes serps es poden veure unes arpes en la part externa i a cada costat de la cloaca que tenen un cert paper en el coit.

Dentadura

Hi ha diversos tipus de dents, segons l'os sobre el qual s'implantin: maxil·lars, pterigoides, palatins, dentari i premaxil·lars. Les dents maxil·lars són les més variades i les úniques que poden estar associades a glàndules verinoses, es poden distingir quatre tipus principals:

 Àglif
Són dents massisses, prènsils, corbades cap enrere per subjectar la presa i no estan dissenyades per inocular verí. És el cas de molts colúbrids, boids i pitònids. En general són serps inofensives per l'home, amb excepció de les grans constrictores (pitons, anacondes).

 Opistòglif
Són dents acanalades situades a la part posterior de la mandíbula i connectades amb glàndules de verí, constituint un sistema d'inoculació primitiu. Atès que per injectar el verí ha de mossegar amb la part posterior de la boca, normalment són poc perilloses per a l'home. Aquest és el cas de la serp verda (Malpolon monspessulanus). No obstant això, les espècies de gran mida poden produir greus mossegades i fins i tot la mort, com Dispholidus typus, de l'Àfrica subsahariana.

 Proteròglif
Són dents petites i fixeos situades en la part davantera de la boca, amb un canal més o menys tancat. Les cobres i les mambes posseeixen aquestes dents. Algunes espècies, com la cobra escopidora (Naja nigricollis), els tenen modificats per escopir el verí a més de quatre metres de distància.

 Solenòglif
Es tracta de dos llargs ullals mòbils en la part anterior de la mandíbula, són buits amb un canal interior tancat i connectat amb glàndules verinoses. Els ullals es pleguen sobre el paladar superior quan l'animal tanca la boca i es redrecen ràpidament quan l'obre. És el sistema d'inoculació més eficaç.
Aquest tipus de dentadura és característic dels vipèrids.

Òrgans interns

L'aparell respiratori i les vísceres estan molt modificats, ja que el cos tubular de la serp requereix que tots els òrgans siguin allargats i prims. La glotis pot projectar-se cap endavant per mantenir obert el conducte respiratori durant la ingestió de la presa i, en algunes espècies una part de la tràquea està especialitzada en la respiració, constituint un pulmó traqueal. El pulmó esquerre sol estar reduït o de vegades -fins i tot- pot faltar, i les altres vísceres parelles solen situar-se a diferents nivells en cada costat. Posseeixen una parella d'òrgans reproductors.

Oïda
A causa de les seves característiques anatòmiques, s'ha considerat sovint que les serps són sordes. Les darreres investigacions dels herpetòlegs han demostrat que les serps tenen una capacitat auditiva comparable a la de les sargantanes.

Les serps tenen unes estructures situades a cada costat del cap que els permet sentir-hi. La pell i un teixit muscular a cada banda del cap, protegeixen un osset mòbil, anomenat columel·la, el qual fa petits desplaçaments com a resposta a les ones sonores. El moviment de la columel·la és transferit a través d'estructures intermèdies a la còclea, en la qual es produeixen uns senyals elèctrics en les seves cèl·lules piloses que es corresponen amb les ones de so, relatives al rang de freqüència determinada, que permet percebre el seu sistema auditiu, i transferides al cervell.

Per tant, al contrari del que es pensa habitualment, les serps tenen oïda per percebre sons transmesos a través de l'aire. El que passa, per una banda, és que no es veuen. Per altra banda, la seva oïda està preparada per percebre sons de baixa freqüència. Aquests sons, segons estudis recents, se situen en una freqüència d'entre 200-300 Hz, mentre que en els humans el seu espectre màxim d'audició se situa d'entre 15-20.000 Hz.

No és, doncs, que siguin sordes sinó que senten sons greus i dins d'un rang molt limitat, 200-300 Hz. Tots els sons que estan per sobre o per sota d'aquesta freqüència no els poden sentir. Segons estudis de la Universitat de Las Palmas de Gran Canaria, l'orella de les serps està mancada de part externa, o orella externa. Presenten una orella interna i una orella mitjana sense timpà. Només poden percebre sons de baixa freqüència.

És, possiblement, a causa d'aquesta limitació auditiva, que han desenvolupat un altre sistema a través del qual poden percebre vibracions del terra o de qualsevol objecte amb el qual estiguin en contacte. Les vibracions de terra passen a través dels músculs del ventre a uns receptors especials situats a tot el llarg del llom i són transmeses al cervell.

Verí
Moltes espècies utilitzen verí per immobilitzar o matar les seves preses. El verí és una secreció modificada emmagatzemada a les glàndules verinoses i que s'injecta a la pressa gràcies als ullals. L'aparició de la glàndula verinosa es creu que es va produir fa aproximadament 200 milions d'anys durant l'evolució dels rèptils escatosos, però no és fins fa 10-15 milions d'anys que diferents grups de serps van desenvolupar de forma independent mecanismes d'injecció del verí. Així, les serps denominades opistoglifes van desenvolupar en una de les dents posteriors de cada meitat de la mandíbula superior un canal que facilita el pas del verí. Aquest tipus de dentadura és freqüent en els colúbrids. Els protetoglifs (elàpids) posseeixen un o més ullals a la part anterior dels maxil·lars. Finalment, els solenoglifs (vipèrids) posseeixen el sistema d'injecció més elaborat, on l'ullal és una dent molt llarga, el canal d'injecció està tancat en tota la seva extensió i actuen com a veritables agulles hipodèrmiques que es claven profundament i injecten el verí.

El verí de les serps és amb freqüència específic per a les seves preses, i el seu paper com a mecanisme defensiu és secundari.
El verí, igual que totes les secrecions salivals, posseeix agents que realitzen una predigestió dels aliments, per tant, fins i tot les serps "no verinoses" poden causar danys en els teixits.

El verí està constituït per una complexa barreja d'unes poques famílies de proteïnes que actuen com neurotoxines (que ataquen el sistema nerviós), hemotoxines (que danyen la sang), citotoxines (danyen els teixits) i moltes altres substàncies que poden afectar l'organisme de diferents maneres. L'abundància relativa d'aquestes proteïnes presenta una elevada variabilitat a nivell de gènere, d'espècie, poblacional i, inclús, una variabilitat relacionada amb l'estadi de desenvolupament de l'organisme (ontogenètica). D'entre les proteïnes que trobem al verí de les serps podem diferenciar aquelles que presenten una activitat enzimàtica i aquelles que no. Pertanyents a aquest darrer grup, gairebé tots els verins de serps posseeixen hialuronat, un enzim que destrueix l'àcid hialurònic, que és el ciment que manté unit el teixit conjuntiu que, per tant es disgrega facilitant així la ràpida difusió del verí.

Austràlia és el lloc del món amb major nombre d'espècies verinoses; però només es produeix una mort per mossegada a l'any de mitjana. En canvi, a l'Índia, es produeixen 250.000 mossegades anuals que produeixen unes 50.000 morts. A Espanya es produeixen l'any 1500 mossegades d'escurçons, de les quals entre 3 i 5 provoquen la mort de la víctima.

Història natural

Dieta

Totes les serps són estrictament carnívores, alimentant-se de petits animals com ara sargantanes, altres serps, petits mamífers, ocells, ous, peixos, cargols o insectes. Com que les serps no poden mastegar ni tallar el seu aliment a trossos, es veuen obligades a empassar-se la presa sencera. La mida corporal d'un cos influeix de manera important en els seus costums alimentaris: les serps més petites es mengen preses més petites. Els pitons juvenils poden començar alimentant-se de sargantanes o ratolins i canviar a petits cérvols o antílops quan esdevenen adults, per exemple.

La mandíbula d'una serp és una estructura complexa. Al contrari del que diu la creença popular que les serps es poden dislocar la mandíbula, les serps tenen un maxil·lar inferior molt flexible, amb dues meitats que no estan unides rígidament, i nombroses altres articulacions al crani (vegeu crani de les serps), cosa que els permet obrir la boca prou per a empassar-se la presa sencera, encara que tingui un major diàmetre que la serp mateixa, car les serps no masteguen. Per exemple la serp menjadora d'ous africana té una mandíbula flexible adaptada per menjar-se ous molt més grans que el diàmetre del seu cap. Aquesta serp manca de dents, però té unes prominències òssies a la vora interior de la columna vertebral que es fan servir per ajudar a trencar la closca dels ous que s'empassa la serp.

Mentre que la majoria de serps s'alimenten d'una varietat de preses, algunes espècies s'especialitzen. Les cobres reials i les serps anellades blanques-i-negres d'Austràlia es mengen altres serps. Pareas iwesakii i altres colúbrids de la subfamíla dels pareatins, que es mengen cargols, tenen més dents al costat dret de la boca que a l'esquerre, car la closca de les seves preses sol ser una espiral en la direcció de les agulles del rellotge.

Algunes serps tenen una mossegada verinosa que fan servir per matar la presa abans de menjar-se-la. Altres serps maten la presa per constricció, mentre que d'altres se l'empassen sencera i encara vivent.

Després de menjar, les serps esdevenen dorments mentre es produeix la digestió. La digestió és una activitat intensa, especialment després de consumir una presa molt gran. En les espècies que només s'alimenten esporàdicament, l'intestí sencer entra en un estat reduït entre àpats per estalviar energia, i l'aparell digestiu és sobreregulat a la seva màxima capacitat en les 48 hores que segueixen el consum d'una presa. Com que són de sang freda (ectotermes), la temperatura ambiental té un paper important en la digestió de les serps. La temperatura ideal perquè les serps digereixin l'aliment és de 30 °C. La digestió de les serps requereix tanta energia metabòlica que en Crotalus durissus, el cròtal tropical, s'ha observat un increment de la temperatura corporal de fins a 1,2 °C per sobre del medi que l'envolta. Per aquest motiu, una serp que sigui molestada després d'haver menjat recentment sovint regurgitarà la seva presa per a poder fugir de l'amenaça percebuda. Si no se la molesta, el procés digestiu d'una serp és molt eficaç, i els seus enzims digestius ho dissolen i absorbeixen tot excepte el pèl i les urpes de la presa, que són expulsats juntament amb els residus.

Reproducció
La majoria de les serps es reprodueixen ponent ous (ovoviviparisme), però algunes espècies han desenvolupat un tipus de viviparisme. El cos de la mare reté els ous fins que les cries estan totalment formades per viure d'una manera independent. En alguns casos el grup sencer dona a llum cries totalment formades, mentre que altres grups poden estar formats per membres que donen a llum cries formades, com per membres que ponen ous. Per exemple, dins de la família dels bòids totes les boes pareixen animals ja formats, mentre que els pitons ponen ous.

Diversitat
Les serps presenten una radiació adaptativa gairebé tan àmplia com els llangardaixos, encara que la variació estructural no és tan gran.

Boes i pitons
Les famílies dels bòids i dels pitònids reuneixen les espècies més primitives de serps, com ho prova el fet que encara conservin rudiments de potes posteriors.
No tenen verí i maten a les seves preses per constricció, enrotllant al seu voltant fins que s'asfixien.
Inclouen les serps actuals més voluminoses, com l'anaconda i el pitó reticulat.
Els pitons mesuren normalment entre 1 i 6 m, encara que algunes espècies estan entre les serps més llargues existents, el pitó reticulat ostenta el rècord de la serp més llarga, amb 10,32 m.

Colobres
La majoria de les serps vivents pertanyen a la família dels Colubridae, que comprèn moltes espècies inofensives i de mitja grandària com la colobra d'aigua europea (Natrix maura), la serp llisa meridional (Coronella girondica) o la serp blanca (Elaphe scalaris), i algunes moderadament verinoses, amb dents situades en la part posterior de la boca, com la serp verda (Malpolon monspessulanus); la serp arborícola del Cap (Dispholidus) és una de les poques espècies la mossegada de la qual pot ser mortal per a l'home.

Cobres, mambes i corals
La família dels elàpids inclou les cobres, les serps de corall, les mambes com la mamba negra i les serps marines totes elles extremadament verinoses i potencialment mortals per a l'home, els ullals són petits i estan situats en la part davantera de la boca; el seu verí té una acció principalment neurotòxica.
Totes les serps verinoses australianes pertanyen a aquest grup.
Els elàpids terrestres són similars als colúbrids; gairebé tots tenen cossos llargs i fins, caps coberts per grans escates i no sempre diferenciades del coll, i ulls amb pupil·les rodones.
A més, el seu comportament és, en general, bastant actiu, i moltes espècies són ovípares.
Les mambes (Dendroaspis) són arborícoles i són molt àgils i ràpides.
Les serps de corall posseeixen els seus vius colors d'advertiment, ja que són molt verinoses (aposematisme), entre els quals predominen groc, vermell i negre, no són molt perilloses per a l'home, ja que són de petita grandària i obren poc la boca, cosa que fa difícil que puguin mossegar. Les cobres (Naja i Ophiophagus) són molt conegudes pel seu aspecte amenaçant i la seva mossegada; habiten en zones tropicals i desèrtiques del sud de l'Àsia i de l'Àfrica; despleguen una espècie de "caputxa" a la zona del cap i el coll quan estan irritades o en perill, gràcies a les llargues costelles cervicals, és un gest d'advertiment davant un possible enemic.

Escurçons i cròtals
La família dels vipèrids comprèn els escurçons del Vell Món i els cròtals, principalment americans, totes elles són molt verinoses i amb dos ullals proveïts d'un canal que actuen com agulles hipodèrmiques quan mosseguen per injectar verí.
El verí té una acció principalment hemolítica.
Els ullals són molt llargs i es pleguen contra el paladar quan la boca està tancada desplegant ràpidament quan la serp es disposa a atacar a la presa.
El cap és triangular i ample, i els ulls tenen la pupil·la vertical.
La majoria retenen els ous que contenen a les cries a l'interior del cos donant a llum a les cries després de l'eclosió dels ous des de l'interior del cos, és a dir, són ovovivípares.

Entre les seves espècies destaquen els escurçons europeus (Viperidae), els animals més verinosos del continent, els escurçons banyuts africans (Cerastes), l'àspid, els escurçons del Gabon (Bitis, amb els ullals més llargs de totes les serps), les serps de cascavell americanes (els cròtals Crotalus, Lachesis), etc.

Evolució
El registre fòssil de les serps és relativament pobre perquè l'esquelet de la serp és típicament petit i fràgil, fent que rarament es fossilitzin. Tanmateix, a Sud-amèrica i Àfrica s'hi han descobert espècimens de 150 milions d'anys d'antiguitat, fàcilment identificables com a serps, però amb trets esquelètics semblants als dels llangardaixos. Existeix un consens, basat en l'anatomia comparada, que les serps descendeixen dels llangardaixos. Les proves fòssils suggereixen que les serps podrien haver evolucionat de llangardaixos excavadors, com ara els varànids o un grup similar, durant el període Cretaci. Una serp fòssil primitiva, Najash rionegrina, era un animal de dues potes excavador dotat de sacre, i era completament terrestre. Un anàleg vivent d'aquests avantpassats putatius és el monitor mancat d'orelles Lanthanotus de Borneo, tot i que també és semiaquàtic. Les formes subterrànies desenvoluparen un cos adaptat per excavar i perderen les potes. Segons aquesta hipòtesi, característiques com ara les parpelles fusionades i transparents (escuts oculars) i la pèrdua d'orelles externes evolucionaren per fer front a les dificultats d'un estil de vida fossorial, com ara rascades a les còrnies o l'entrada de brutícia a les orelles. Se sap que algunes serps primitives tenien potes posteriors, però la seva pelvis manca de connexió directa amb les vèrtebres. En són exemples espècies fòssils com ara Haasiophis, Pachyrhachis i Eupodophis, que són una mica més antigues que Najash.

Els grups més primitius de serps modernes, els pitons i les boes, tenen potes posteriors vestigials; es tracta de minúsculs dits amb urpes, coneguts com a esperons anals, que fan servir per agafar-se l'una a l'altra durant la copulació. Els leptotiflòpids i els tiflòpids són altres grups en què hi ha presents vestigis de la cintura pelviana, que a vegades apareixen com a projeccions còrnies quan són visibles. Les potes anteriors estan absents en totes les serps i aquesta pèrdua està associada amb l'evolució dels gens Hox que controlen la morfogènesi de les potes. L'esquelet axial de l'avantpassat comú de les serps, com la majoria d'altres tetràpodes, tenia especialitzacions regionals que consistien en les vèrtebres cervicals, toràciques, lumbars, sacres i caudals. L'expressió dels gens Hox de l'esquelet axial encarregada del desenvolupament del tòrax esdevingué dominant al principi de l'evolució de les serps i, com a resultat, les vèrtebres anteriors als monyons de les potes posteriors (si és que n'hi ha) tenen la mateixa identitat semblant a la toràcica (excepte l'atles, l'epistrofeu i entre una i tres vèrtebres cervicals), fent que la majoria de l'esquelet de les serps es compongui d'un tòrax extremament estès. Les costelles es troben exclusivament a les vèrtebres toràciques. Les vèrtebres cervicals, lumbar i pelvianes estan molt reduïdes en nombre (només romanen 2-10 vèrtebres lumbars i pelvianes), mentre que de les vèrtebres caudals només en queda una cua curta, tot i que la cua encara és prou llarga com per a ser útil en moltes espècies, i està modificada en algunes espècies aquàtiques i arborícoles.

Una hipòtesi alternativa, basada en la morfologia, suggereix que els avantpassats de les serps estaven relacionats amb els mosasaures (rèptils aquàtics extints del període Cretaci), que al seu torn es pensa que derivaven de varànids. Segons aquesta hipòtesi, es creu les parpelles transparents i fusionades de les serps evolucionaren per combatre les condicions marines (la pèrdua d'aigua cornial a través de l'osmosi), mentre que les orelles externes es perderen per la manca d'ús en un medi aquàtic, conduint eventualment a un animal d'aparença similar a la de les serps marines d'avui dia. Al Cretaci superior, les serps recolonitzaren la terra i assumiren el seu aspecte actual. Es coneixen restes fòssils de serps de sediments de principis del Cretaci superior, cosa que encaixa amb aquesta hipòtesi, especialment perquè són més antigues que l'espècie terrestre Najash rionegrina. L'estructura cranial similar, les potes reduïdes o absents, i altres característiques anatòmiques que es donen tant en els mosasaures com en les serps indiquen una correlació cladística positiva, tot i que algunes d'aquestes característiques no són compartides amb els varànids. En anys recents, estudis genètics han indicat que les serps no tenen una relació tan propera amb els varànids com es creia i per tant, tampoc no la tenien amb els mosasaures, l'avantpassat suggerit en la teoria aquàtica de la seva evolució. Tanmateix, hi ha més proves que relacionen els mosasaures amb les serps que amb els varànids. Restes fragmentàries del Juràssic i Cretaci inferior indiquen que el registre fòssil d'aquests grups es remunta més enllà en el temps, cosa que podria acabar refutant o confirmant qualsevol de les dues espècies.

La gran diversitat de les serps modernes aparegué al Paleocè, correlacionada amb la radiació adaptativa dels mamífers després de l'extinció dels dinosaures no aviaris. Un dels grups més comuns d'avui dia, els colúbrids, esdevingueren particularment diversos gràcies al fet que cacen rosegadors, un grup de mamífers particularment reeixit. Hi ha més de 2.900 espècies de serps, que s'estenen tant al nord com el cercle polar àrtic a Escandinàvia, i al sud fins a Austràlia i Tasmània. Les serps viuen a tots els continents tret de l'Antàrtida, dins el mar i a elevacions de fins a 4.900 metres a l'Himàlaia (Àsia). Hi ha moltes illes de les quals les serps estan notablement absents, com ara Irlanda, Islàndia i Nova Zelanda.

Taxonomia
Totes les serps pertanyen al subordre Serpentes, que al seu torn és membre de l'ordre Squamata. Aquest ordre inclou també els llangardaixos (Sauria), amb els quals les serps estan emparentades, i els Amphisbaenia, que també han perdut les potes i s'assemblen superficialment a les serps.

El subordre de les serps està dividit en dos infraordres: Alethinophidia i Scolecophidia. Aquesta separació es basa tan en característiques morfològiques i com en similituds de la seqüència d'ADN mitocondrial. Alethinophidia a vegades es divideix en Henophidia i Caenophidia, amb aquesta última formada per serps "colubroides" (colúbrids,  escurçons, elàpids,  hidròfids i  atractaspídids i acrocòrdids), mentre que les altres famílies d'aletinofidis formen Henophidia. Malgrat que no existeix avui, els Madtsoiidae, una família de serps gegants, primitives i semblants a pitons, es trobaven a Austràlia fins fa 50.000 anys, representats per gèneres com ara Wonambi.

El subordre de les serps se subdivideix en dos infraordres i 18 famílies:
 Infraordre Alethinophidia
 Família Acrochordidae
 Família Aniliidae
 Família Anomochilidae
 Família Atractaspididae
 Família Boidae
 Família Bolyeriidae
 Família Colubridae
 Família Cylindrophiidae
 Família Elapidae
 Família Loxocemidae
 Família Pythonidae
 Família Tropidophiidae
 Família Uropeltidae
 Família Viperidae
 Família Xenopeltidae
 Infraordre Scolecophidia
 Família Anomalepididae
 Família Leptotyphlopidae
 Família Typhlopidae

Filogènesi

Un arbre filogenètic dels grups actuals de serps. Cal remarcar que només indica relacions entre grups, no el temps en què es varen separar.

Aspectes culturals

Les serps han estat apreciades en diverses cultures, però repudiades en unes altres. A Roses, per exemple, entre pescadors que estan pescant hom designa amb l'eufemisme senyorita (castellanisme deferent) per superstició.

A occident, en les creences cristianes i de l'islam el dimoni ha estat representat amb les serps, en aquest cas amb Satanàs d'acord amb la Bíblia i l'Alcorà, on relata la seva condemna per temptar Adam i Eva. Fins i tot en els primers capítols i versicles de la gènesi, després de cometre la temptació, relata com Déu, a banda de dir-li que s'arrossegarà i caminarà sobre el seu pit, també hi haurà una enemistat entre ella i la dona que li mossegarà el seu taló i la dona li farà fallida el cap.
Aquest relat bíblic ha inspirat a l'església catòlica a representar la Mare de Déu com la Immaculada Concepció trepitjant a una serp tal com relata la gènesi, però el rèptil en comptes de mossegar el taló només porta una poma a la boca.
En alguns casos també s'han representat a Jesucrist trepitjant una serp, però no inspirat en la gènesi de la Bíblia sinó com una representació de lluita entre el bé i del mal, els quals també pot aplicar al cas de la Mare de Déu.

Encara que en l'islam no s'ha atribuït amb cap representació diferent a la gènesi com ho ha fet el cristianisme i encara que en el cristianisme sembla que hi ha certes contradiccions, alguns teòlegs sobre la història de Moisès diuen que per alliberar el poble hebreu segons el relat bíblic, Déu va convertir el seu bastó en una serp enmig de l'esbarzer ardent quan Moisès va entrar en contacte. D'acord amb aquesta història, s'interpreta que Déu a través de Moisès demostrava la seva fúria contra el poble egipci enfront del faraó. D'acord amb aquesta història, alguns teòlegs consideren que el bastó de Moisès és una serp d'aspecte positiu o alhora miraculós. A la Bíblia, la serp és l'animal que convenç a l'Eva per temptar Adam i prendre la fruita prohibida; és un símbol del diable, ja que els causa l'expulsió del Paradís. Per això en moltes representacions la Verge Maria apareix esclafant-la, per protegir la humanitat del seu influx.

Una serp que es menja la mateixa cua es diu Ouroboros i és el símbol de la regeneració o el temps cíclic. Per aquest motiu forma part d'amulets màgics.

La serp era un animal sagrat per als egipcis, especialment la cobra, animal que simbolitzava el Nil (tot i que en algunes representacions la serp apareix com a al·legoria del penis). A l'antic Egipte, Ouadjet (la cobra) era la «Senyora del Cel», símbol de la calor ardent del Sol i la flama del foc. Representava la força del creixement, la fertilitat del sòl i de les aigües a la mitologia egípcia. Era la deessa protectora del Baix Egipte i del faraó. No obstant això, la serp Apofis eren el símbol de les forces malèfiques que habiten el Duat, i intentava retenir la barca solar de Ra.

Igualment, les serps, tenen un paper destacat a l'hinduisme. A Grècia la majoria de criatures mitològiques destructores tenien part de serp, com l'Hidra. Forma part del caduceu dels metges, ja que coneixen les medicines per dominar-les (o usen els seus poders per a emmalaltir).

En el llunyà Orient la serp és considerat un animal sagrat, diví i protector contra les energies negatives, que representa força, energia i saviesa. A més és venerada principalment dins de la cultura hindi. En el cristianisme l'Esperit Sant és representat en un colom blanc, però aquí, el déu Xiva, és representat com una serp, sobretot una cobra.

La cultura xinesa la considera també una entitat protectora, un exemple d'això el trobem a la Gran Muralla Xinesa construïda sobre un terreny muntanyós i ubicada al centre de color groc. També ha estat utilitzada a l'una del Drac, com un símbol d'algunes arts marcials orientals. Doncs en aquest animal s'han inspirat els diferents mètodes de defensa personal a la Xina mil·lenària, principalment per mestres o senseis sobre artistes marcials. A més, dins de l'astrologia xinesa, el Signe de la Serp ocupa el 6è lloc i com a part successora del Signe del Drac, segons la filosofia xinesa, també forma part del Ying yang.

De la mateixa manera, a Centreamèrica eren venerades per gran part de les cultures que hi van florir. L'exemple més famós és el del Déu Quetzalcóatl, la Serp Emplumada, Kukulcán per als maies. També a la cultura andina, sobretot en la cultura aimara i inca, la serp també representa aspecte positiu. Per aquests natius és conegut com el "Katari", on s'ha creat els càlculs matemàtics per mesurar l'espai i el temps.

A l'antiga Roma, el déu Esculapi (déu de la medicina) adoptava forma de serp, qui ha donat nom a la serp d'Esculapi. En aquest cas les serps també eren venerades.

El basilisc és representat en algunes cultures com una gran serp amb una taca al cap amb forma de corona que mata amb la mirada o si se li veu en una rajola o en un mirall la seva mirada petrifica.

Referències

Bibliografia

 Da Nóbrega Alves RR, Da Silva Vieira WL, Gomes Santana G. 2008. Reptiles used in traditional folk medicine: conservation implications. Biodiversity and Conservation vol. 17(8): 2037-2049. Resum  a SpringerLink . Consultat el 22 de gener del 2009.

 George Albert Boulenger. The snakes of Europe, 2nd edition. London: Methuen & Co., Ltd., 1913.

Vegeu també
 Serp d'aigua
 Colobra
 Serp de corall
 Dispholidus typus

Enllaços externs

 Llista d'espècies de serps d'arreu del món (en anglès)
 What's That Snake? - eina per identificar les serps (en anglès)
 Informació sobre els ofidis (en castellà)

redpajama_set_name: RedPajamaWikipedia


text:
Home › Beth Orton "Kidsticks" LP (2016)
Anti- Records
Beth Orton "Kidsticks" LP (2016)
Details: Beth Orton "Kidsticks" on black vinyl, great condition!
Description: "Orton's sixth studio album, Kidsticks, was released on 27 May 2016, and marked a distinct turn towards a purely electronic sound, with Orton playing keyboards and synthesizers instead of acoustic guitar. The album was produced by Orton herself alongside Andrew Hung from the band Fuck Buttons, who provided drum and synth programming. The album included contributions from Chris Taylor of Grizzly Bear, George Lewis Jr from Twin Shadow, and composer Dustin O'Halloran."
TRACK LISTING SIDE A
A1. Snow
A2. Moon
A3. Petals
A4. 1973
A5. Wave
B1. Dawnstar
B2. Falling
B3. Corduroy Legs
B4. Flesh and Blood
B5. Kidsticks

redpajama_set_name: RedPajamaCommonCrawl


FRENCH shipping giant CMA CGM has announced two rate increases for December from Asia to the Middle East and from the Far East to the Indian subcontinent.
For all cargo from East Asian ports bound for Middle East and Persian Gulf ports rates will rise by US$200.
As from December 1, freight all kinds (FAK) tariff guide lines, excluding terminal handling charges at both ends will be $500 per TEU and $800 per FEU from all Chinese and Korean base ports to Dubai's Jebel Ali.
Effective December 8, rates from all Asian ports to all Middle East Gulf ports will increase to $200 per TEU.
Effective December 15, rates from all Asian ports to all Middle East Gulf ports will again increased $200 per TEU.
Also as from December 1, our FAK Tariff Guide Lines (excluding THC both ends) rates are $450 per TEU and $600 FEU from China to Mumbai's Nhava Sheva/Mundra/Hazira.


Who doesn't love to swing on the hammock? No matter whether you are swinging, sleeping or resting on a hammock, it's always entertaining. Relaxing on a hammock on the beach side sounds heaven to most of the people.
I don't think that anybody is unaware o what hammock. However, just in case if you don't know what hammock is you can see the picture below to understand. It's basically a sling which is made of either rope, fabric or netting and suspended between two points for swinging or sleeping or resting.
We have been seeing a lot of travelers getting their hammock from the local guys. Why not purchase them by yourselves and use it on the traveling destinations?
Travelers or people who like camping would be greatly benefited by getting hammocks. If you are into camping, then you will surely love the extra comfort that the hammock brings.
You can even use a hammock in your garden or the lawn in front of your house. Having a hammock chair on the lawn will be amazing if you love to read a book or want to rest quietly.
This is a very high-quality hammock which even comes with a very reasonable price tag. It's so soft that you won't even recognize whether you are sleeping in your house or the forest. This hammock is perfect for camping, traveling, boating or even in the backyard. In one word this is a multi-functional hammock. Despite being very strong, it is very lightweight. Buy From Amazon.
Looking for a comfortable and lightweight hammock to rest in your backyard? This is a colorful hammock which is easy to carry and store in a storage back. You can quickly clean the hammock if you want. Buy From Amazon.
Who doesn't fantasizes having a hammock chair in their backyard or garden? Well everybody loves to have a hammock chair in their garden. You can rest there and read a book also.
Get this hammock chair for your garden. This hammock chair is made of natural polyester and cotton fabric. It offers great design along with a vibrant color's fabric. It's the best hammock chair you can have in the garden. Buy From Amazon.
I have always dreamed of having a hanging hammock chair on my balcony. Nowadays you can get these types of hanging hammock chair to purchase. This is one kind of them.


text:
Q: Error: Missing positive glob The above message appears everytime the gulp gets to the 'markup' function.
Here is my gulpfile:
var gulp = require('gulp'),
    autoPrefixer = require('gulp-autoprefixer'),
    jade = require('gulp-jade'),
    liveReload = require('gulp-livereload'),
    sourceMaps = require('gulp-sourcemaps'),
    ts = require('gulp-typescript'),
    tsLint = require('gulp-tslint'),
    watch = require('gulp-watch'),
    sass = require('gulp-sass');

// Configuration
var config = {
    js: 'public/_assets/frontend/js',
    css: 'public/_assets/frontend/css',
    fonts: 'public/_assets/frontend/fonts',
    images: 'public/_assets/frontend/img',
    markup: 'public/'
};

// Javascript
gulp.task('scripts', function() {
    var tsResult = gulp.src(['src/ts/*.ts', 'src/ts/**/*.ts'])
        .pipe(tsLint())
        .pipe(ts({
            noImplicitAny: true
        }));

        tsResult.js
            .pipe(gulp.dest(config.js))
            .pipe(liveReload());
});

// Sass
gulp.task('sass', function() {
    return gulp.src(['src/sass/*.scss', 'src/sass/**/*.scss'])
        .pipe(watch(['src/sass/*.scss', 'src/sass/**/*.scss']))
        .pipe(sourceMaps.init())
        .pipe(sass.sync().on('error', sass.logError))
        .pipe(autoPrefixer({
            browsers: ['last 3 versions'],
            cascade: false
        }))
        .pipe(sourceMaps.write())
        .pipe(gulp.dest(config.css))
        .pipe(liveReload());
});

// jade
gulp.task('markup', function() {
    return gulp.src([['src/**/*.jade', 'src/**/_*.jade']])
        .pipe(jade({
            pretty: true
        }))
        .pipe(gulp.dest(config.markup))
        .pipe(liveReload());
});

// Images
gulp.task('images', function() {
    return gulp.src(['src/images/**/*.*', 'src/images/*.*'])
        .pipe(gulp.dest(config.images));
});

// Watch
gulp.task('watch', function() {
    liveReload.listen();
    gulp.watch(['src/ts/*.ts', 'src/ts/**/*.ts'], ['scripts']);
    gulp.watch(['src/sass/*.scss', 'src/sass/**/*.scss'], ['sass']);
    gulp.watch(['src/*.jade', 'src/**/*.jade'], ['markup']);
});

// Default Task
gulp.task('default', function() {
    gulp.start('sass', 'scripts', 'markup', 'images', 'watch');
});

// Dist Scripts
gulp.task('distScripts', function() {
    return gulp.src(['src/ts/plugins/**/*', 'src/ts/*.js'], { "base" : "./src/ts" })
        .pipe(gulp.dest(config.js));
});

// Dist Styles
gulp.task('distStyles', function() {
    return gulp.src('src/sass/**/*.css', { "base" : "./src/sass" })
        .pipe(autoPrefixer({
            browsers: ['last 3 versions'],
            cascade: false
        }))
        .pipe(gulp.dest(config.css));
});

// Dist Fonts
gulp.task('distFonts', function() {
    return gulp.src('src/fonts/**/*', { "base" : "./src/fonts" })
    .pipe(gulp.dest(config.fonts));
});

// Dist
gulp.task('dist', function() {
    gulp.start('distScripts', 'distStyles', 'images', 'distFonts');
});

Here is the message I get when I run 'gulp':
(node:9460) fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module, please update it to a more recent version. [00:39:30] Using gulpfile D:\Projects\FrontEnd\Project\gulpfile.js [00:39:30] Starting 'default'... [00:39:30] Starting 'sass'... [00:39:30] Starting 'scripts'... [00:39:30] Finished 'scripts' after 4.66 ms [00:39:30] Starting 'markup'... [00:39:30] 'markup' errored after 86 μs [00:39:30] Error: Missing positive glob
    at Object.gs.create (D:\Projects\FrontEnd\Project\node_modules\gulp\node_modules\glob-stream\index.js:73:39)
    at Gulp.src (D:\Projects\FrontEnd\Project\node_modules\gulp\node_modules\vinyl-fs\lib\src\index.js:33:23)
    at Gulp.<anonymous> (D:\Projects\FrontEnd\Project\gulpfile.js:50:14)
    at module.exports (D:\Projects\FrontEnd\Project\node_modules\orchestrator\lib\runTask.js:34:7)
    at Gulp.Orchestrator._runTask (D:\Projects\FrontEnd\Project\node_modules\orchestrator\index.js:273:3)
    at Gulp.Orchestrator._runStep (D:\Projects\FrontEnd\Project\node_modules\orchestrator\index.js:214:10)
    at D:\Projects\FrontEnd\Project\node_modules\orchestrator\index.js:279:18
    at finish (D:\Projects\FrontEnd\Project\node_modules\orchestrator\lib\runTask.js:21:8)
    at module.exports (D:\Projects\FrontEnd\Project\node_modules\orchestrator\lib\runTask.js:60:3)
    at Gulp.Orchestrator._runTask (D:\Projects\FrontEnd\Project\node_modules\orchestrator\index.js:273:3) [00:39:30] Finished 'default' after 42 ms

Any idea why? Seems like it happens when rendering Jade... All the dependencies are installed of course.

A: Seems like you are using an multidimensional array [["item1","item2"]]. To read your files with gulp.src() you should use a string like 'path/to/*.jade' or an simple onedimensional array like ["path/to/first/*.jade", "path/to/second/glob/**/*.jade"].
In your case the JADE-Task should look like this:
// jade
gulp.task('markup', function() {
    return gulp.src(['src/**/*.jade', 'src/**/_*.jade'])
        .pipe(jade({
            pretty: true
        }))
        .pipe(gulp.dest(config.markup))
        .pipe(liveReload());
});

Regarding your watch-task:
You should call your livereload in an own task as a callback of your watch-task. It is also recommended to define the root path of your destination folder, as an argument option in the liveReload() object.
// Watch
gulp.task('livereload', function() {
    return gulp.src('./dist')
       .pipe(
          liveReload({
             start: true,
             basePath: 'path/to/destination'
          })
       );
});
gulp.task('watch', ['livereload'], function() {
    liveReload.listen()
    gulp.watch(['src/ts/*.ts', 'src/ts/**/*.ts'], ['scripts']);
    gulp.watch(['src/sass/*.scss', 'src/sass/**/*.scss'], ['sass']);
    gulp.watch(['src/*.jade', 'src/**/*.jade'], ['markup']);
});

Do not forget to start your watch-task in your default-task
// Dist
gulp.task('dist', ['watch'], function() {
    gulp.start('distScripts', 'distStyles', 'images', 'distFonts');
});

redpajama_set_name: RedPajamaStackExchange


The Steel W-Beam Guardrail with Motorcyclist Protecting Device ("SPM") is composed by a continuous horizontal W-beam exposed to traffic and regularly supported by C-shaped vertical posts distributed at each two meters with rigid spacers set in between of the W-beam and each post, and with a horizontal continuous flat-trapezoidal screen, located below the W-Beam and attached to the W-Beam by means of brackets regularly distributed at the joint between W-Beam and Spacer.
What Road Restraint systems can be combined with your Motorcyclist Protection System? Steel W-Beam Guardrail composed by a continuous horizontal W-beam exposed to traffic and regularly supported by C-shaped vertical posts distributed at each two meters with rigid spacers set in between of the W-beam and each post.


The lender on Thursday announced that it has digitised the application .
The bank has also extended the digitisation facility for customers seeking top-up loans .
Mumbai: ICICI Bank expects its mortgage lending portfolio to cross Rs 2 lakh crore by March 2020, paced by robust demand from buyers of affordable homes in smaller cities.


text:
Two teenagers jailed for killing man in Runcorn Date published: 5th April 2019 2.31pm
Two teenagers jailed for killing man in Runcorn
Two teenagers have been handed custodial sentences for killing an 18-year-old man outside a club in Runcorn following a feud over a girl.
Joe Ward, who turned 18 on Saturday 30 March, and a 15-year-old boy, who cannot be named for legal reasons, pleaded not guilty to the murder of fellow Runcorn resident Eddie O'Rourke.
Ward was convicted of the offence on Friday 5 April following a five-week trial at Liverpool Crown Court.
The 15-year-old boy was found guilty of manslaughter.
Ward, of Lockfield, was also convicted of possessing an offensive weapon in a public place, an offence that the 15-year-old had previously pleaded guilty to.
The teenagers returned to Liverpool Crown Court for sentencing today, Friday 24 May.
Ward was given a custodial sentence and will serve a minimum of 16 years.
The 15-year-old boy was handed a seven-year custodial sentence to be served at a young offenders' institute.
Sentencing the pair, Lord Justice King told them: "Knife crime destroys lives, including those who carry the knives.
"Had a knife never been brought to the party, Eddie O'Rourke would still be alive and neither of you would be facing the sentences you are.
"If I had the means I would educate all children to have nothing to do with knives."
Addressing Ward, he added: "My firm conclusion is that you did not act with any degree of self-defence. You intentionally went outside to have a fight of some sort.
"You are an intelligent young man with a previously good character who is described as being extremely remorseful, which I accept.
"The real tragedy is what happened to Eddie O'Rourke – and there is no justification for that. No words of mine can convey the effect that has had on his family."
Addressing the 15-year-old boy, Lord Justice King said: "I accept that you are remorseful and have no previous convictions, and it is clear that you are an intelligent boy who should have never got himself into this position.
"The fearsome knife you were carrying has brought devastation to the family of Eddie O'Rourke.
"If you were an adult your sentence would have been much longer. It is only your age that has prevented me from passing such a sentence."
The court heard that Eddie's death was the tragic result of a long-running feud with Ward.
This centred around a girl and the hostility between the pair escalated when they saw each other at a birthday party being held at the Royal British Legion on Castle Road in Halton Village on the night of Friday 7 September.
Eddie entered the club shortly before 8.25pm. The offenders had arrived just minutes earlier.
Upon seeing then 17-year-old boy Ward, Eddie gestured to the teenager to follow him outside.
He did so but CCTV footage shows that he ran straight back inside the club and was handed a large knife with a 12" blade by the 15-year-old in the doorway.
The offenders then went outside together, at which point Ward stabbed Eddie with the knife in the abdomen.
The single stab wound severed a main artery. Eddie was taken to hospital via ambulance but doctors were unable to save him and he died that night.
Knife used to kill Eddie O'Rourke
The offenders fled the scene after Eddie was stabbed but were arrested the next day.
The court heard that Ward had stabbed Eddie with a knife before, in the arm in August 2017, and that prior to his death the offender had sent messages to others in which he made threats to 'cut' him.
The jury was also told that on the week of the stabbing the 15-year-old bought a machete on the internet. A different bladed weapon was used to kill Eddie.
The 15-year-old admitted in court to habitually carrying a knife whenever he went out.
Ward claimed that he acted in self-defence in fatally stabbing Eddie while the 15-year-old pleaded not guilty to murder on the grounds of a lack of intent.
The 15-year-old argued that he did not know the knife would be used to harm someone when he handed it over to his older friend.
After hearing all of the evidence, the jury found Ward guilty of murder and the 15-year-old guilty of manslaughter.
Detective Inspector Adam Waller, who led Cheshire Constabulary's investigation into the fatal stabbing, said: "A team of officers from the force's Major Investigation Team have worked tirelessly and spent months piecing together the case.
"This included gathering vital evidence, speaking to numerous witnesses, viewing hours of CCTV footage and carrying out forensic enquiries.
"As a result of this work and the testimonies of witnesses, 18-year-old Joe Ward has been convicted of murder and a 15-year-old boy has been convicted of manslaughter.
"I would like to thank the members of the community who provided evidence to the police and acted as witnesses in the investigation. They played a vital role in securing the convictions and I cannot commend them enough for the bravery they have shown in testifying in such a high profile case for the Runcorn community.
"I would also like to take this opportunity to thank all the officers and staff involved in the investigation.
"Our thoughts remain with Eddie's family and friends as they continue to come to terms with their devastating loss.
"While his loved ones have been left heartbroken by his death, the Runcorn community as a whole have been left deeply shocked by what happened outside the Royal British Legion that night.
"For an 18-year-old man to have his life ended by the senseless actions of who were then 17 and 15-year-old boys is tragic in every sense of the word.
"It is also the ultimate example of why people shouldn't carry knives.
"Not only has a young man died but three families have been ruined as a result of a knife being carried and used that night."
Following the sentencing, DI Waller added: "Having been found guilty by a jury of killing Eddie, the two teenagers have now been handed significant custodial sentences.
"I hope that the verdicts and subsequent sentences handed out by Liverpool Crown Court give Eddie's family some closure and enable them to begin to move forward with their lives.
"I also hope that the case deters others from carrying knives."
Following the verdicts, Eddie's mum Jayne White said: "There will never be words to describe the impact Eddie's death has had on my family. I am a mother without her son and his three sisters and two brothers are without their older brother.
"The best thing in our lives has been taken away from us and my family have been left in turmoil.
"Eddie was not only my son but my best friend. Life without him starts now with the ultimate realisation that he will never walk through the door of his loving home again.
"The police investigation into Eddie's death has been brilliant. They worked so hard in preparation for the court case and have been there for me with anything I have needed.
"I would especially like to thank Nigel Power QC and DI Adam Waller and all of his team, particularly Detective Constable Amanda Antrobus, our Family Liaison Officer.
"We need to get knives off our streets. My kids and I intend to do whatever we can to support the police and our community in this regard. We need a combined approach against the impact of knife crime and we all need to take responsibility.
"We as parents need to make sure that we know what our children are doing and what they are carrying around with them.
"There is never a positive outcome to knife crime, which can have life changing consequences for everyone involved."
Chief Inspector Sarah Heath, of Runcorn Local Policing Unit (LPU), added: "We are committed to doing all that we can to tackle knife crime in the town.
"When people carry knives it is only a matter of time before someone suffers life changing injuries or is killed, and the simple fact is if you carry a knife then you are much more likely to be involved in a knife crime.
"Carrying a knife doesn't make you safer and the consequences can be devastating for all those involved.
"Knife crime is sadly a growing epidemic nationwide. It is an issue that we take extremely seriously and Runcorn LPU will ensure that anyone found to be carrying a knife or committing a knife related offence in the town is brought to justice.
"But the police cannot beat knife crime without the help of the local community and we urge anyone with information about people who may be carrying knives to come forward and speak to us or pass this information onto Crimestoppers."
To report any type of knife crime call Cheshire Constabulary on 101, or 999 in an emergency.
Information can also be passed to the force online via https://cheshire.police.uk/contact/general-enquiries.
Anyone who knows someone that carries a knife can report it to Crimestoppers, anonymously, on 0800 555 111.


text:
View basket "The Class of '79: Three students who risked their lives to destroy apartheid" has been added to your basket.
HomePolitics Kader Asmal: Politics in my blood
African Delights	R225.00
Future Inheritance: Building capacity in democratic South Africa	R260.00
Kader Asmal: Politics in my blood
Kader Asmal, lawyer and teacher, South African Cabinet minister, and the driving force behind the Irish Anti-Apartheid Movement, has been called many things – 'small, bustling, curious, courageous, indefatigable' (Irish Times) and 'dapper, combative, witty, cantankerous, sarcastic, urbane, precisely spoken' (Sunday Times). The son of a small-town shopkeeper from Natal, his life took him as far as exile in the UK, on to a senior position at Trinity College Dublin, and back to a free South Africa, governed by an exemplary Constitution, which he helped devise. These memoirs are not only Asmal's personal journey. They are also the story of South Africa's transition from apartheid to freedom and democracy, in which he played a significant role, as a member of the ANC's Constitutional Committee and negotiating team and later as an MP and Cabinet minister under Nelson Mandela and Thabo Mbeki. They provide testimony, too, to Asmal's lifelong dedication to freedom, equality and justice – ideals enshrined in the country's Bill of Rights, which he played a major part in writing.
Kader Asmal, Adrian Hadland, Moira Levy
SKU: 9781431402571 Categories: All Books, Biography, Politics
To Have and to Hold: The making of same-sex marriage in South Africa
Declassified: Moving beyond the dead-end of race in South Africa
The Class of '79: Three students who risked their lives to destroy apartheid
Future Inheritance: Building capacity in democratic South Africa
Development In A Divided Country: Vol 5
Home Affairs: Rethinking same-sex families and relationships in contemporary South Africa
South Africa's Insurgent Citizens: On dissent and the possibility of politics


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>KochLycheKvasovFamily</title>
<meta name="date" content="2017-01-04">
<link rel="stylesheet" type="text/css" href="../../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

org.drip.spline.tension

Class KochLycheKvasovFamily

java.lang.Object

org.drip.spline.tension.KochLycheKvasovFamily

public class KochLycheKvasovFamily
extends java.lang.Object

This class implements the basic framework and the family of C2 Tension Splines outlined in Koch and Lyche
        (1989), Koch and Lyche (1993), and Kvasov (2000) Papers.

 Functions exposed here implement the Basis Function Set from:
        - Hyperbolic Hat Primitive Set
        - Cubic Polynomial Numerator and Linear Rational Denominator
        - Cubic Polynomial Numerator and Quadratic Rational Denominator
        - Cubic Polynomial Numerator and Exponential Denominator

Author:

Lakshmi Krishnamurthy

Constructor Summary

Constructors

Constructor and Description

KochLycheKvasovFamily()

Method Summary

All Methods Static Methods Concrete Methods

Modifier and Type
Method and Description

static FunctionSet
FromExponentialPrimitive(ExponentialTensionSetParams etsp)

Implement the Basis Function Set from the Cubic Polynomial Numerator and Exponential Denominator

static FunctionSet
FromHyperbolicPrimitive(ExponentialTensionSetParams etsp)

Implement the Basis Function Set from the Hyperbolic Hat Primitive Set

static FunctionSet
FromRationalLinearPrimitive(ExponentialTensionSetParams etsp)

Implement the Basis Function Set from the Cubic Polynomial Numerator and Linear Rational Denominator

static FunctionSet
FromRationalQuadraticPrimitive(ExponentialTensionSetParams etsp)

Implement the Basis Function Set from the Cubic Polynomial Numerator and Quadratic Rational
  Denominator

Methods inherited from class java.lang.Object

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Detail

KochLycheKvasovFamily

public KochLycheKvasovFamily()

Method Detail

FromHyperbolicPrimitive

public static final FunctionSet FromHyperbolicPrimitive(ExponentialTensionSetParams etsp)

Implement the Basis Function Set from the Hyperbolic Hat Primitive Set

Parameters:

etsp - The Tension Function Set Parameters

Returns:

Instance of the Basis Function Set

FromRationalLinearPrimitive

public static final FunctionSet FromRationalLinearPrimitive(ExponentialTensionSetParams etsp)

Implement the Basis Function Set from the Cubic Polynomial Numerator and Linear Rational Denominator

Parameters:

etsp - The Tension Function Set Parameters

Returns:

Instance of the Basis Function Set

FromRationalQuadraticPrimitive

public static final FunctionSet FromRationalQuadraticPrimitive(ExponentialTensionSetParams etsp)

Implement the Basis Function Set from the Cubic Polynomial Numerator and Quadratic Rational
  Denominator

Parameters:

etsp - The Tension Function Set Parameters

Returns:

Instance of the Basis Function Set

FromExponentialPrimitive

public static final FunctionSet FromExponentialPrimitive(ExponentialTensionSetParams etsp)

Implement the Basis Function Set from the Cubic Polynomial Numerator and Exponential Denominator

Parameters:

etsp - The Tension Function Set Parameters

Returns:

Instance of the Basis Function Set

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method


text:
class GURL;
class SkBitmap;

namespace webui {

// Convenience routine to convert SkBitmap object to data url
// so that it can be used in WebUI.
UI_BASE_EXPORT std::string GetBitmapDataUrl(const SkBitmap& bitmap);

// Convenience routine to get data url that corresponds to given
// resource_id as a bitmap. This function does not check if the
// resource for the |resource_id| is a bitmap, therefore it is the
// caller's responsibility to make sure the resource is indeed a
// bitmap. Returns empty string if a resource does not exist for given
// |resource_id|.
UI_BASE_EXPORT std::string GetBitmapDataUrlFromResource(int resource_id);

// Extracts a disposition from click event arguments. |args| should contain
// an integer button and booleans alt key, ctrl key, meta key, and shift key
// (in that order), starting at |start_index|.
UI_BASE_EXPORT WindowOpenDisposition
    GetDispositionFromClick(const base::ListValue* args, int start_index);

// Pares a formatted scale factor string into float and sets to |scale_factor|.
UI_BASE_EXPORT bool ParseScaleFactor(const base::StringPiece& identifier,
                                     float* scale_factor);

// Parses a URL containing some path @{scale}x. If it does not contain a scale
// factor then the default scale factor is returned.
UI_BASE_EXPORT void ParsePathAndScale(const GURL& url,
                                      std::string* path,
                                      float* scale_factor);

// Helper function to set some default values (e.g., font family, size,
// language, and text direction) into the given dictionary. Requires an
// application locale (i.e. g_browser_process->GetApplicationLocale()).
UI_BASE_EXPORT void SetLoadTimeDataDefaults(
    const std::string& app_locale,
    base::DictionaryValue* localized_strings);

// Get a CSS declaration for common text styles for all of Web UI.
UI_BASE_EXPORT std::string GetWebUiCssTextDefaults();

// Appends the CSS declaration returned by GetWebUiCssTextDefaults() as an
// inline stylesheet.
UI_BASE_EXPORT void AppendWebUiCssTextDefaults(std::string* html);

// Get some common font styles for all of WebUI.
UI_BASE_EXPORT std::string GetFontFamily();
UI_BASE_EXPORT std::string GetFontSize();
UI_BASE_EXPORT std::string GetTextDirection();

}  // namespace webui

#endif  // UI_BASE_WEBUI_WEB_UI_UTIL_H_


text:
Artists · Soloists · Ferenc Vizi · piano
New Schubert album released on 26th November on the Paraty label
Born in Transylvania (Romania) in 1974, Ferenc Vizi started the piano at the age of nine with András Körtési in his native town of Reghin. Gérard Frémy, a member of the jury of the George Enescu competition, in which Ferenc Vizi won a special prize, encouraged him to come and study with him at the Paris Conservatoire, which he was able to do in 1992, thanks to a French government grant and the Yvonne Lefébure Foundation, and where he also studied with Cyril Huvé. In 1998, after graduating with a unanimous first prize at the Conservatoire, he entered the postgraduate performers' course there with Jacques Rouvier, and from 2000 to 2002 went on to study with Françoise Thinat at the Paris Ecole Normale.
Ferenc Vizi has carried off a number of prestigious international prizes: the Saratov competition in Russia, the Hamamatsu competition in Japan, the Arthur Rubinstein competition in Tel-Aviv, and the Munich ARD competition, thanks to which he was invited to perform in South America, Japan and several European countries, and to record Bartók's 2nd piano concerto with the Bayerischen Rundfunk directed by Peter Rundel for the Munich radio.
He has since performed as a recital soloist and with orchestras principally in Europe. As a chamber musician Ferenc Vizi has also performed with Henri Demarquette, Raphaël Perraud, Jean-Marc Phillips-Varjabedian, Alexis Cardenas Benoît Fromanger and Richard Galliano. In 2014 he joined the Brancusi Trio with the violinist Ann-Estelle Médouze and the cellist Laura Buruiana
Juventus Lauréat in 1995, Ferenc Vizi is regularly invited to the Théâtre de la Ville in Paris. He has also performed at Radio France, the Grand Théâtre de Bordeaux, Théâtre de Caen, Festival de l'Épau, Piano à Riom, Piano à Auxerre, Serres d'Auteuil, Piano Passion de Saint-Etienne, Musée d'Orsay and the Opéra comique in Paris, and in the Festivals of Nohant, Toulon, Périgord Noir, 1001 Notes, the Nantes Folle Journée, Festival de la Roque d'Anthéron, La Chaise Dieu, Piano(s) festival Lille, Festival d'Eté de Toulouse, the London It's all about piano festival, and numerous theatres throughout France. He has performed with the Orchestre National de Lille, Orchestre National d'Île de France, Orchestre d'Auvergne, Ensemble Orchestral des Hauts-de-Seine and performed both Tchaikovsky's 1st piano concerto and Grieg's piano concerto with the Târgu-Mures Philharmonic Orchestra from his native Romania on tour in France at the Pin Galant in Mérignac, Palais Neptune in Toulon, Cratère in Alès and at La Rampe in Échirolles. In November 2018 he played Ravel's concerto en G with the same orchestra in the Palace of Culture in Târgu-Mures. During the summer of 2016 he gave his first performance of Boulez's 12 Notations at the Juventus Festival and gave several recitals of his Blue Notes programme. Following his remarkable Diabelli Variations performance at the Théâtre de la Ville in Paris in November 2015, he has been re-invited by the Théâtre to play his Chimères & Contemplations recital programme in January 2017. 2017 also saw the first performance of a new programme Liszt, Hanover square rooms, London, 9th June 1840 in the Berlioz Festival in August, and a recital in the Degas sur tous les tons cycle at the Musée d'Orsay in Paris. In 2018 he took part in the celebrated Nantes Folle journée and gave a recital in the Liszt en Provence festival.
In 2019 Ferenc Vizi will be performing a new programme under the title of Danube that makes a musical journey along the banks of the Danube, Europe's most majestic river, on a cruise from Schubert to Enescu, but also through the Danube's traditional music heritage with its intertwining gypsy and Hungarian influences.
Ferenc Vizi has created a programme with the Ensemble Cifra that brings together Liszt's Rhapsodies with traditional Hungarian gypsy music and was first performed at the Scène nationale de Martigues and the Lisztomanias Festival in Châteauroux. Rhapsodies – Liszt and the Hungarian Gypsies has since toured extensibly throughout France, most recently at the Théâtre Impérial in Compiègne, and the Nancy and Montpellier operas.
Ferenc Vizi has recorded Beethoven's opus 111 Sonata and Schumann's Fantasia opus 17 for the Æon label, and Voyage - works by Schubert, Liszt, and Wagner / Liszt - for Satirino records. In 2013 Rhapsodies - Liszt and the Hungarian Gypsies was released by Satirino records under the title Czardas Fantasy, Mendelssohn's complete works for cello and piano with the cellist Laura Buruiana by Coviello Classics, as well as an album of works for violin and piano by Ernest Bloch with the violinist Elsa Grether on the Fuga Libera label. Ferenc's recording on Beethoven's Diabelli Variations on the Anima label was released in November 2014, followed by Romance oubliée with the cellist Hermine Horiot on the 1001 Notes label in early 2015. His recording of Schubert's Sonata in A major D 664 and the Four Impromptus D 935 for the Paraty label will be released in the autumn of 2021.
"His performance is deeply ancored in the keyboard, at times bouncy, (what an extraordinary left hand!), whose seriousness is at times enlivened by a playfulness caracteristic of the composer. Vizi likes fracture and accident as much as meditation. He gives the final variations their unfathomable melanconia, making their lines sing in such a bel canto fashion, yet never distorting the text for the sake of emotion. Ferenc Vizi is like an Old Sage."
Alain Lompech - Le Monde On a concert performance of Beethovens's Diabelli Variations
"Ferenc Vizi is one of those rare pianists whose poetic touch is never facile."
Judith Chaine - Télérama
"A born Beethovenian, an exceptional virtuoso, Ferenc Vizi is a rumanian pianiste born in 1974 about whom we will most certainly hear more. He answers the cello motives without ever distorting the score in the Kreutzer Sonata and provides a perfect accompagniment to Henri Demarquette's bow in Prokofiev's lyrical but questioning cello sonata."
Patrick Szersnovicz - Le Monde de la Musique
"…this 30 year old pianist has a pure and upright quality that immediately comes across in the music he is playing. Ones attention is instantly drawn to his uninhibited and natural performance, but above all to the irresistibly personality of a pianist for whom music seems to be above all a matter of contact and not isolation."
Olivier Bellamy - Le Monde de la Musique
"...he is one of the impressive and engaging pianists of his generation. An absolute must."
Jean Lukas - La Terrasse
"...a virtuoso with an extraordinary poetic presence, warm and intense playing..."
lain Cochard - Zurban "A few months ago I reviewed two new discs of Mendelssohn's cello music. Ultimately, neither Luca Fiorentini (Brilliant Classics) nor Gary Hoffman (La Dolce Volta) had much to say, but that certainly isn't true of this new disc from the Romanian duo of Laura Buruiana and Ferenc Vizi. Here we have a cellist with a particularly plangent tone and a pianist amply capable of bringing off Mendelssohn's fingery, virtuoso writing... These qualities are well demonstrated in such passages as the finale of the Second Sonata, which they take at a daring lick but without losing any clarity. In fact they give Isserlis and Tan a run for their money, even though the latter has the technical advantage of a shallower-toned fortepiano."
Harriet Smith, Gramophone
Photo Arthur Forjonel
Concerto repertoire
MOZART - Concerto N°9 "Jeunehomme" K 271
MOZART - Concerto N°12 in A major K 414
MOZART - Concerto N°20 in D minor K 466
BEETHOVEN - Concertos N°s 2, 3 & 5
LISZT - Concertos N°s 1, 2 & Totentanz
GRIEG - Concerto in A minor
BRAHMS - Concertos N°1 in D minor, N°2 B flat major
TCHAIKOVSKI - Concerto N°1
BARTOK - Concerto N° 2
RAVEL - Concerto in G major
Ferenc Vizi can perform Beethoven N°5, Brahms N°1 and Mozart D minor K 466 at very short notice.
He is currently working on completing the Beethoven concertos cycle, as well as several new Mozart concertos.
3rd movement, Rondo: Allegro non troppo, of Brahms's 1st piano concerto performed by Ferenc Vizi with the Târgu Mures Philharmonic Orchestra in May 2014. The complete performance can be viewed via this link.
Recital Programmes
see French page via this link
Green Trio