<commit_before>// collab
export { default as ChangeStore } from './collab/ChangeStore'
export { default as ClientConnection } from './collab/ClientConnection'
export { default as CollabClient } from './collab/CollabClient'
export { default as CollabEngine } from './collab/CollabEngine'
export { default as CollabServer } from './collab/CollabServer'
export { default as CollabSession } from './collab/CollabSession'
export { default as DocumentClient } from './collab/DocumentClient'
export { default as DocumentEngine } from './collab/DocumentEngine'
export { default as DocumentServer } from './collab/DocumentServer'
export { default as SnapshotEngine } from './collab/SnapshotEngine'
export { default as SnapshotStore } from './collab/SnapshotStore'
export { default as WebSocketConnection } from './collab/WebSocketConnection'
export { default as CollabServerConfigurator } from './collab/CollabServerConfigurator'
export { default as CollabServerPackage } from './collab/CollabServerPackage'

// model
export { default as annotationHelpers } from './model/annotationHelpers'
export { default as BlockNode } from './model/BlockNode'
export { default as Container } from './model/Container'
export { default as ContainerAnnotation } from './model/ContainerAnnotation'
export { default as PropertyAnnotation } from './model/PropertyAnnotation'
export { default as Document } from './model/Document'
export { default as DocumentChange } from './model/DocumentChange'
export { default as documentHelpers } from './model/documentHelpers'
export { default as DocumentIndex } from './model/DocumentIndex'
export { default as DocumentNode } from './model/DocumentNode'
export { default as EditorSession } from './model/EditorSession'
export { default as DOMExporter } from './model/DOMExporter'
export { default as DOMImporter } from './model/DOMImporter'
export { default as FileManager } from './model/FileManager'
export { default as FileProxy } from './model/FileProxy'
export { default as Fragmenter } from './model/Fragmenter'
export { default as HTMLExporter } from './model/HTMLExporter'
export { default as HTMLImporter } from './model/HTMLImporter'
export { default as InlineNode } from './model/InlineNode'
export { default as JSONConverter } from './model/JSONConverter'
export { default as Marker } from './model/Marker'
export { default as NodeIndex } from './model/data/NodeIndex'
export { default as TextBlock } from './model/TextBlock'
export { default as TextNode } from './model/TextNode'
export { default as Selection } from './model/Selection'
export { default as XMLExporter } from './model/XMLExporter'
export { default as XMLImporter } from './model/XMLImporter'

// packages
export { default as BasePackage } from './packages/base/BasePackage'
export { default as BlockquotePackage } from './packages/blockquote/BlockquotePackage'
export { default as CodePackage } from './packages/code/CodePackage'
export { default as EmphasisPackage } from './packages/emphasis/EmphasisPackage'
export { default as ImagePackage } from './packages/image/ImagePackage'
export { default as InlineWrapperPackage } from './packages/inline-wrapper/InlineWrapperPackage'
export { default as OverlayPackage } from './packages/overlay/OverlayPackage'
export { default as ParagraphPackage } from './packages/paragraph/ParagraphPackage'
export { default as PersistencePackage } from './packages/persistence/PersistencePackage'
export { default as StrongPackage } from './packages/strong/StrongPackage'
export { default as SubscriptPackage } from './packages/subscript/SubscriptPackage'
export { default as SuperscriptPackage } from './packages/superscript/SuperscriptPackage'

// file
export { default as FilePackage } from './packages/file/FilePackage'
export { default as FileNode } from './packages/file/FileNode'

// heading
export { default as HeadingPackage } from './packages/heading/HeadingPackage'
export { default as HeadingMacro } from './packages/heading/HeadingMacro'

// base
export { default as SwitchTextTypeTool } from './packages/switch-text-type/SwitchTextTypeTool'
export { default as SwitchTextTypeCommand } from './packages/switch-text-type/SwitchTextTypeCommand'

// prose-editor
export { default as ProseEditorPackage } from './packages/prose-editor/ProseEditorPackage'
export { default as ProseEditor } from './packages/prose-editor/ProseEditor'
export { default as ProseArticle } from './packages/prose-editor/ProseArticle'

// link
export { default as LinkPackage } from './packages/link/LinkPackage'
export { default as EditLinkTool } from './packages/link/EditLinkTool'
export { default as Link } from './packages/link/Link'
export { default as LinkCommand } from './packages/link/LinkCommand'
export { default as LinkComponent } from './packages/link/LinkComponent'

// table
export { default as TablePackage } from './packages/table/TablePackage'
export { default as Table } from './packages/table/Table'
export { default as TableCell } from './packages/table/TableCell'

// inline-node
export { default as InsertInlineNodeCommand } from './packages/inline-node/InsertInlineNodeCommand'
export { default as EditInlineNodeCommand } from './packages/inline-node/EditInlineNodeCommand'
export { default as InlineNodeComponent } from './packages/inline-node/InlineNodeComponent'

// button
export { default as Button } from './packages/button/Button'

// scroll-pane
export { default as ScrollPanePackage } from './packages/scroll-pane/ScrollPanePackage'
export { default as ScrollPane } from './packages/scroll-pane/ScrollPane'

// body-scroll-pane
export { default as BodyScrollPanePackage } from './packages/body-scroll-pane/BodyScrollPanePackage'
export { default as BodyScrollPane } from './packages/body-scroll-pane/BodyScrollPane'

// spell-check
export { default as SpellCheckPackage } from './packages/spell-check/SpellCheckPackage'
export { default as SpellCheckManager } from './packages/spell-check/SpellCheckManager'

// split-pane
export { default as SplitPanePackage } from './packages/split-pane/SplitPanePackage'
export { default as SplitPane } from './packages/split-pane/SplitPane'

// scrollbar
export { default as ScrollbarPackage } from './packages/scrollbar/ScrollbarPackage'
export { default as Scrollbar } from './packages/scrollbar/Scrollbar'

// layout
export { default as LayoutPackage } from './packages/layout/LayoutPackage'
export { default as Layout } from './packages/layout/Layout'

export { default as ListPackage } from './packages/list/ListPackage'

// grid
export { default as GridPackage } from './packages/grid/GridPackage'
export { default as Grid } from './packages/grid/Grid'

// drop-teaser
export { default as DropTeaser } from './packages/drop-teaser/DropTeaser'

// tabbed-pane
export { default as TabbedPanePackage } from './packages/tabbed-pane/TabbedPanePackage'
export { default as TabbedPane } from './packages/tabbed-pane/TabbedPane'

// modal
export { default as ModalPackage } from './packages/modal/ModalPackage'
export { default as Modal } from './packages/modal/Modal'

// input
export { default as InputPackage } from './packages/input/InputPackage'
export { default as Input } from './packages/input/Input'

// responsive application
export { default as ResponsiveApplication } from './packages/responsive-application/ResponsiveApplication'

// toc
export { default as TOC } from './packages/toc/TOC'
export { default as TOCProvider } from './packages/toc/TOCProvider'

// tools
export { default as ToolDropdown } from './packages/tools/ToolDropdown'
export { default as Tool } from './packages/tools/Tool'
export { default as Toolbar } from './packages/tools/Toolbar'
export { default as Toolbox } from './packages/tools/Toolbox'

// surface
export { default as Surface } from './packages/surface/Surface'

// ui
export { default as AbstractEditor } from './ui/AbstractEditor'
export { default as AnnotationCommand } from './ui/AnnotationCommand'
export { default as EditAnnotationCommand } from './ui/EditAnnotationCommand'
export { default as AnnotationComponent } from './ui/AnnotationComponent'
export { default as AnnotationTool } from './ui/AnnotationTool'
export { default as BlockNodeComponent } from './ui/BlockNodeComponent'
export { default as Command } from './ui/Command'
export { default as Component } from './ui/Component'
export { default as ContainerEditor } from './ui/ContainerEditor'
export { default as DragAndDropHandler } from './ui/DragAndDropHandler'
export { default as FontAwesomeIcon } from './ui/FontAwesomeIcon'
export { default as InsertNodeCommand } from './ui/InsertNodeCommand'
export { default as Highlights } from './ui/Highlights'
export { default as RenderingEngine } from './ui/RenderingEngine'
export { default as Router } from './ui/Router'
export { default as TextBlockComponent } from './ui/TextBlockComponent'
export { default as TextPropertyComponent } from './ui/TextPropertyComponent'
export { default as TextPropertyEditor } from './ui/TextPropertyEditor'
export { default as UnsupportedNodeComponent } from './ui/UnsupportedNodeComponent'

// util
export { default as ArrayIterator } from './util/ArrayIterator'
export { default as Configurator } from './util/Configurator'
export { default as EventEmitter } from './util/EventEmitter'
export { default as Factory } from './util/Factory'
export { default as forEach } from './util/forEach'
export { default as inBrowser } from './util/inBrowser'
export { default as map } from './util/map'
export { default as makeMap } from './util/makeMap'
export { default as keys } from './util/keys'
export { default as platform } from './util/platform'
export { default as Registry } from './util/Registry'
export { default as request } from './util/request'
export { default as sendRequest } from './util/sendRequest'
export { default as SubstanceError } from './util/SubstanceError'
export { default as substanceGlobals } from './util/substanceGlobals'
export { default as TreeIndex } from './util/TreeIndex'
export { default as uuid } from './util/uuid'
export { series } from './util/async'

// dom
export { default as DefaultDOMElement } from './dom/DefaultDOMElement'

// aliases (mainly for backward compatibility)
export { default as ProseEditorConfigurator } from './util/Configurator'
<commit_msg>expose more utils<commit_after>// collab
export { default as ChangeStore } from './collab/ChangeStore'
export { default as ClientConnection } from './collab/ClientConnection'
export { default as CollabClient } from './collab/CollabClient'
export { default as CollabEngine } from './collab/CollabEngine'
export { default as CollabServer } from './collab/CollabServer'
export { default as CollabSession } from './collab/CollabSession'
export { default as DocumentClient } from './collab/DocumentClient'
export { default as DocumentEngine } from './collab/DocumentEngine'
export { default as DocumentServer } from './collab/DocumentServer'
export { default as SnapshotEngine } from './collab/SnapshotEngine'
export { default as SnapshotStore } from './collab/SnapshotStore'
export { default as WebSocketConnection } from './collab/WebSocketConnection'
export { default as CollabServerConfigurator } from './collab/CollabServerConfigurator'
export { default as CollabServerPackage } from './collab/CollabServerPackage'

// model
export { default as annotationHelpers } from './model/annotationHelpers'
export { default as BlockNode } from './model/BlockNode'
export { default as Container } from './model/Container'
export { default as ContainerAnnotation } from './model/ContainerAnnotation'
export { default as PropertyAnnotation } from './model/PropertyAnnotation'
export { default as Document } from './model/Document'
export { default as DocumentChange } from './model/DocumentChange'
export { default as documentHelpers } from './model/documentHelpers'
export { default as DocumentIndex } from './model/DocumentIndex'
export { default as DocumentNode } from './model/DocumentNode'
export { default as EditorSession } from './model/EditorSession'
export { default as DOMExporter } from './model/DOMExporter'
export { default as DOMImporter } from './model/DOMImporter'
export { default as FileManager } from './model/FileManager'
export { default as FileProxy } from './model/FileProxy'
export { default as Fragmenter } from './model/Fragmenter'
export { default as HTMLExporter } from './model/HTMLExporter'
export { default as HTMLImporter } from './model/HTMLImporter'
export { default as InlineNode } from './model/InlineNode'
export { default as JSONConverter } from './model/JSONConverter'
export { default as Marker } from './model/Marker'
export { default as NodeIndex } from './model/data/NodeIndex'
export { default as TextBlock } from './model/TextBlock'
export { default as TextNode } from './model/TextNode'
export { default as Selection } from './model/Selection'
export { default as XMLExporter } from './model/XMLExporter'
export { default as XMLImporter } from './model/XMLImporter'

// packages
export { default as BasePackage } from './packages/base/BasePackage'
export { default as BlockquotePackage } from './packages/blockquote/BlockquotePackage'
export { default as CodePackage } from './packages/code/CodePackage'
export { default as EmphasisPackage } from './packages/emphasis/EmphasisPackage'
export { default as ImagePackage } from './packages/image/ImagePackage'
export { default as InlineWrapperPackage } from './packages/inline-wrapper/InlineWrapperPackage'
export { default as OverlayPackage } from './packages/overlay/OverlayPackage'
export { default as ParagraphPackage } from './packages/paragraph/ParagraphPackage'
export { default as PersistencePackage } from './packages/persistence/PersistencePackage'
export { default as StrongPackage } from './packages/strong/StrongPackage'
export { default as SubscriptPackage } from './packages/subscript/SubscriptPackage'
export { default as SuperscriptPackage } from './packages/superscript/SuperscriptPackage'

// file
export { default as FilePackage } from './packages/file/FilePackage'
export { default as FileNode } from './packages/file/FileNode'

// heading
export { default as HeadingPackage } from './packages/heading/HeadingPackage'
export { default as HeadingMacro } from './packages/heading/HeadingMacro'

// base
export { default as SwitchTextTypeTool } from './packages/switch-text-type/SwitchTextTypeTool'
export { default as SwitchTextTypeCommand } from './packages/switch-text-type/SwitchTextTypeCommand'

// prose-editor
export { default as ProseEditorPackage } from './packages/prose-editor/ProseEditorPackage'
export { default as ProseEditor } from './packages/prose-editor/ProseEditor'
export { default as ProseArticle } from './packages/prose-editor/ProseArticle'

// link
export { default as LinkPackage } from './packages/link/LinkPackage'
export { default as EditLinkTool } from './packages/link/EditLinkTool'
export { default as Link } from './packages/link/Link'
export { default as LinkCommand } from './packages/link/LinkCommand'
export { default as LinkComponent } from './packages/link/LinkComponent'

// table
export { default as TablePackage } from './packages/table/TablePackage'
export { default as Table } from './packages/table/Table'
export { default as TableCell } from './packages/table/TableCell'

// inline-node
export { default as InsertInlineNodeCommand } from './packages/inline-node/InsertInlineNodeCommand'
export { default as EditInlineNodeCommand } from './packages/inline-node/EditInlineNodeCommand'
export { default as InlineNodeComponent } from './packages/inline-node/InlineNodeComponent'

// button
export { default as Button } from './packages/button/Button'

// scroll-pane
export { default as ScrollPanePackage } from './packages/scroll-pane/ScrollPanePackage'
export { default as ScrollPane } from './packages/scroll-pane/ScrollPane'

// body-scroll-pane
export { default as BodyScrollPanePackage } from './packages/body-scroll-pane/BodyScrollPanePackage'
export { default as BodyScrollPane } from './packages/body-scroll-pane/BodyScrollPane'

// spell-check
export { default as SpellCheckPackage } from './packages/spell-check/SpellCheckPackage'
export { default as SpellCheckManager } from './packages/spell-check/SpellCheckManager'

// split-pane
export { default as SplitPanePackage } from './packages/split-pane/SplitPanePackage'
export { default as SplitPane } from './packages/split-pane/SplitPane'

// scrollbar
export { default as ScrollbarPackage } from './packages/scrollbar/ScrollbarPackage'
export { default as Scrollbar } from './packages/scrollbar/Scrollbar'

// layout
export { default as LayoutPackage } from './packages/layout/LayoutPackage'
export { default as Layout } from './packages/layout/Layout'

export { default as ListPackage } from './packages/list/ListPackage'

// grid
export { default as GridPackage } from './packages/grid/GridPackage'
export { default as Grid } from './packages/grid/Grid'

// drop-teaser
export { default as DropTeaser } from './packages/drop-teaser/DropTeaser'

// tabbed-pane
export { default as TabbedPanePackage } from './packages/tabbed-pane/TabbedPanePackage'
export { default as TabbedPane } from './packages/tabbed-pane/TabbedPane'

// modal
export { default as ModalPackage } from './packages/modal/ModalPackage'
export { default as Modal } from './packages/modal/Modal'

// input
export { default as InputPackage } from './packages/input/InputPackage'
export { default as Input } from './packages/input/Input'

// responsive application
export { default as ResponsiveApplication } from './packages/responsive-application/ResponsiveApplication'

// toc
export { default as TOC } from './packages/toc/TOC'
export { default as TOCProvider } from './packages/toc/TOCProvider'

// tools
export { default as ToolDropdown } from './packages/tools/ToolDropdown'
export { default as Tool } from './packages/tools/Tool'
export { default as Toolbar } from './packages/tools/Toolbar'
export { default as Toolbox } from './packages/tools/Toolbox'

// surface
export { default as Surface } from './packages/surface/Surface'

// ui
export { default as AbstractEditor } from './ui/AbstractEditor'
export { default as AnnotationCommand } from './ui/AnnotationCommand'
export { default as EditAnnotationCommand } from './ui/EditAnnotationCommand'
export { default as AnnotationComponent } from './ui/AnnotationComponent'
export { default as AnnotationTool } from './ui/AnnotationTool'
export { default as BlockNodeComponent } from './ui/BlockNodeComponent'
export { default as Command } from './ui/Command'
export { default as Component } from './ui/Component'
export { default as ContainerEditor } from './ui/ContainerEditor'
export { default as DragAndDropHandler } from './ui/DragAndDropHandler'
export { default as FontAwesomeIcon } from './ui/FontAwesomeIcon'
export { default as InsertNodeCommand } from './ui/InsertNodeCommand'
export { default as Highlights } from './ui/Highlights'
export { default as RenderingEngine } from './ui/RenderingEngine'
export { default as Router } from './ui/Router'
export { default as TextBlockComponent } from './ui/TextBlockComponent'
export { default as TextPropertyComponent } from './ui/TextPropertyComponent'
export { default as TextPropertyEditor } from './ui/TextPropertyEditor'
export { default as UnsupportedNodeComponent } from './ui/UnsupportedNodeComponent'

// util
export { default as ArrayIterator } from './util/ArrayIterator'
export { default as Configurator } from './util/Configurator'
export { default as EventEmitter } from './util/EventEmitter'
export { default as Factory } from './util/Factory'
export { default as forEach } from './util/forEach'
export { default as inBrowser } from './util/inBrowser'
export { default as map } from './util/map'
export { default as makeMap } from './util/makeMap'
export { default as keys } from './util/keys'
export { default as platform } from './util/platform'
export { default as Registry } from './util/Registry'
export { default as request } from './util/request'
export { default as sendRequest } from './util/sendRequest'
export { default as SubstanceError } from './util/SubstanceError'
export { default as substanceGlobals } from './util/substanceGlobals'
export { default as TreeIndex } from './util/TreeIndex'
export { default as uuid } from './util/uuid'

export { default as isArray } from './util/isArray'
export { default as isArrayEqual } from './util/isArrayEqual'
export { default as isBoolean } from './util/isBoolean'
export { default as isEqual } from './util/isEqual'
export { default as isFunction } from './util/isFunction'
export { default as isNil } from './util/isNil'
export { default as isNumber } from './util/isNumber'
export { default as isObject } from './util/isObject'
export { default as isPlainObject } from './util/isPlainObject'
export { default as isString } from './util/isString'

export { series } from './util/async'

// dom
export { default as DefaultDOMElement } from './dom/DefaultDOMElement'

// aliases (mainly for backward compatibility)
export { default as ProseEditorConfigurator } from './util/Configurator'
<|endoftext|>


<commit_before>define(["js/core/Bindable", "sprd/util/ProductUtil", "sprd/entity/ConcreteElement"], function (Bindable, ProductUtil, ConcreteElement) {

    return Bindable.inherit('sprd.manager.PrintTypeEqualizer', {
            inject: {
                concreteElement: ConcreteElement
            },

            _setUp: function () {
                this.callBase();

                this.$.concreteElement.bind('getProduct().configurations', 'add', this._handleConfigurationAdd, this);
                this.$.concreteElement.bind('getProduct().configurations', 'remove', this._handleConfigurationRemove, this);
                this.$.concreteElement.bind('getProduct().configurations', 'item:printTypeSwitched', this._handlePrintTypeTransformed, this);
            },

            _tearDown: function () {
                this.callBase();

                this.$.concreteElement.unbind('getProduct().configurations', 'add', this._handleConfigurationAdd, this);
                this.$.concreteElement.unbind('getProduct().configurations', 'remove', this._handleConfigurationRemove, this);
                this.$.concreteElement.unbind('getProduct().configurations', 'item:printTypeSwitched', this._handlePrintTypeTransformed, this);
            },

            _handleConfigurationAdd: function (e) {
                this.equalizeConfigurations(this.$.concreteElement.getProduct(), e.$.item.$.printArea, e.$.item.$.printType);
            },

            _handleConfigurationRemove: function (e) {
                this.revertEqualization(this.$.concreteElement.getProduct(), e.$.item.$.printArea);
            },

            _handlePrintTypeTransformed: function (e) {
                this.equalizeConfigurations(this.$.concreteElement.getProduct(), e.$.item.$.printArea, e.$.item.$.printType, e.$.item);
            },

            revertEqualization: function (product, printArea) {
                var targetPrintType;

                if (!product) {
                    return;
                }

                var configurations = product.getConfigurationsOnPrintAreas([printArea]);

                for (var i = 0; i < configurations.length; i++) {
                    var config = configurations[i];
                    if (config.$.originalPrintType) {
                        targetPrintType = config.$.originalPrintType;
                        break;
                    }
                }

                this.equalizeConfigurations(product, printArea, targetPrintType);
            },

            equalizeConfigurations: function (product, printArea, targetPrintType, excludedConfiguration) {
                if (!printArea || !product || this.$equalizingConfigurations) {
                    return;
                }

                function checkPrintTypeForConfigurations(printType) {
                    for (i = 0; i < configurations.length; i++) {
                        config = configurations[i];
                        if (excludedConfiguration !== config) {
                            possiblePrintTypes = config.getPossiblePrintTypesForPrintArea(printArea, appearanceId);

                            if (possiblePrintTypes.indexOf(printType) === -1 || !config.isPrintTypeAvailable(printType)) {
                                return false;
                            }
                        }
                    }
                    return true;
                }

                var configurations = product.getConfigurationsOnPrintAreas([printArea]);
                if (configurations.length > 1) {
                    this.$equalizingConfigurations = true;

                    var appearanceId = product.get('appearance.id');
                    var possiblePrintTypesOnPrintArea = ProductUtil.getPossiblePrintTypesForPrintAreas([printArea], appearanceId),
                        possiblePrintType,
                        possiblePrintTypes,
                        config,
                        i;

                    // if we have a target print type
                    // check if this fits for all
                    if (targetPrintType) {
                        if (checkPrintTypeForConfigurations(targetPrintType)) {
                            possiblePrintType = targetPrintType;
                        }
                    }

                    if (!possiblePrintType && !excludedConfiguration) {
                        for (var j = 0; j < possiblePrintTypesOnPrintArea.length; j++) {
                            if (checkPrintTypeForConfigurations(possiblePrintTypesOnPrintArea[j])) {
                                possiblePrintType = possiblePrintTypesOnPrintArea[j];
                                break;
                            }
                        }
                    }

                    // switch print type
                    if (possiblePrintType) {
                        for (i = 0; i < configurations.length; i++) {
                            config = configurations[i];
                            if (excludedConfiguration !== config) {
                                config.set('originalPrintType', config.$.printType, {silent: true});
                                config.set('printType', possiblePrintType, {
                                    printTypeEqualized: true,
                                    printTypeTransformed: true
                                });
                            }
                        }
                    }

                    this.$equalizingConfigurations = false;
                }
            }
        },

        {
            getPreferredPrintType: function (product, printArea, possiblePrintTypes) {
                var configurations = product.getConfigurationsOnPrintAreas(printArea);
                if (configurations && configurations.length) {
                    // first sort the possible print types by the configurations that are on print area
                    // so when the first configuration has flock then he returns flock
                    var config,
                        configPrintTypes;
                    for (var k = configurations.length - 1; k >= 0; k--) {
                        config = configurations[k];
                        var index = possiblePrintTypes.indexOf(config.$.printType);
                        if (index > 0) {
                            possiblePrintTypes.unshift(config.$.printType);
                            possiblePrintTypes.slice(index, 1);
                        }
                    }

                    var appearanceId = product.get('appearance.id'),
                        cache = {};
                    for (var j = 0; j < possiblePrintTypes.length; j++) {
                        var possiblePrintType = possiblePrintTypes[j];
                        var fitsForAll = true;
                        for (var i = 0; i < configurations.length; i++) {
                            config = configurations[i];
                            configPrintTypes = cache[config.$cid] || config.getPossiblePrintTypesForPrintArea(printArea, appearanceId);
                            // if config on same printarea
                            // AND has DD print type
                            // AND this print type is supported
                            // use this print type
                            cache[config.$cid] = configPrintTypes;

                            if (configPrintTypes.indexOf(possiblePrintType) === -1 || possiblePrintTypes.indexOf(possiblePrintType) === -1 || !config.isPrintTypeAvailable(possiblePrintType)) {
                                fitsForAll = false;
                                break;
                            }
                        }
                        if (fitsForAll) {
                            return possiblePrintType;
                        }
                    }
                }
                return null;
            }

        })

});<commit_msg>DEV-84082 - Print plot when possible<commit_after>define(["js/core/Bindable", "sprd/util/ProductUtil", "sprd/entity/ConcreteElement"], function (Bindable, ProductUtil, ConcreteElement) {

    return Bindable.inherit('sprd.manager.PrintTypeEqualizer', {
            inject: {
                concreteElement: ConcreteElement
            },

            _setUp: function () {
                this.callBase();

                this.$.concreteElement.bind('getProduct().configurations', 'add', this._handleConfigurationAdd, this);
                this.$.concreteElement.bind('getProduct().configurations', 'remove', this._handleConfigurationRemove, this);
                this.$.concreteElement.bind('getProduct().configurations', 'item:printTypeSwitched', this._handlePrintTypeTransformed, this);
            },

            _tearDown: function () {
                this.callBase();

                this.$.concreteElement.unbind('getProduct().configurations', 'add', this._handleConfigurationAdd, this);
                this.$.concreteElement.unbind('getProduct().configurations', 'remove', this._handleConfigurationRemove, this);
                this.$.concreteElement.unbind('getProduct().configurations', 'item:printTypeSwitched', this._handlePrintTypeTransformed, this);
            },

            _handleConfigurationAdd: function (e) {
                this.equalizeConfigurations(this.$.concreteElement.getProduct(), e.$.item.$.printArea, e.$.item.$.printType);
            },

            _handleConfigurationRemove: function (e) {
                this.revertEqualization(this.$.concreteElement.getProduct(), e.$.item.$.printArea);
            },

            _handlePrintTypeTransformed: function (e) {
                this.equalizeConfigurations(this.$.concreteElement.getProduct(), e.$.item.$.printArea, e.$.item.$.printType, e.$.item);
            },

            revertEqualization: function (product, printArea) {
                var targetPrintType;

                if (!product) {
                    return;
                }

                var configurations = product.getConfigurationsOnPrintAreas([printArea]);

                for (var i = 0; i < configurations.length; i++) {
                    var config = configurations[i];
                    if (config.$.originalPrintType) {
                        targetPrintType = config.$.originalPrintType;
                        break;
                    }
                }

                if (!targetPrintType) {
                    var firstConfiguration = configurations[0];
                    var printTypes = firstConfiguration.getPossiblePrintTypesForPrintArea(printArea, product.get('appearance.id'));
                    printTypes.sort(function (p1, p2) {
                        return p1.$.weight > p2.$.weight ? 1 : -1;
                    });
                    for (var j = 0; j < printTypes.length; j++) {
                        var printType = printTypes[j];
                        if (printType.isPrintColorColorSpace()) {
                            firstConfiguration.set('printType', printType);
                            targetPrintType = printType;
                            break;
                        }
                    }
                }

                this.equalizeConfigurations(product, printArea, targetPrintType);
            },

            equalizeConfigurations: function (product, printArea, targetPrintType, excludedConfiguration) {
                if (!printArea || !product || this.$equalizingConfigurations) {
                    return;
                }

                function checkPrintTypeForConfigurations(printType) {
                    for (i = 0; i < configurations.length; i++) {
                        config = configurations[i];
                        if (excludedConfiguration !== config) {
                            possiblePrintTypes = config.getPossiblePrintTypesForPrintArea(printArea, appearanceId);

                            if (possiblePrintTypes.indexOf(printType) === -1 || !config.isPrintTypeAvailable(printType)) {
                                return false;
                            }
                        }
                    }
                    return true;
                }

                var configurations = product.getConfigurationsOnPrintAreas([printArea]);
                if (configurations.length > 1) {
                    this.$equalizingConfigurations = true;

                    var appearanceId = product.get('appearance.id');
                    var possiblePrintTypesOnPrintArea = ProductUtil.getPossiblePrintTypesForPrintAreas([printArea], appearanceId),
                        possiblePrintType,
                        possiblePrintTypes,
                        config,
                        i;

                    // if we have a target print type
                    // check if this fits for all
                    if (targetPrintType) {
                        if (checkPrintTypeForConfigurations(targetPrintType)) {
                            possiblePrintType = targetPrintType;
                        }
                    }

                    if (!possiblePrintType && !excludedConfiguration) {
                        for (var j = 0; j < possiblePrintTypesOnPrintArea.length; j++) {
                            if (checkPrintTypeForConfigurations(possiblePrintTypesOnPrintArea[j])) {
                                possiblePrintType = possiblePrintTypesOnPrintArea[j];
                                break;
                            }
                        }
                    }

                    // switch print type
                    if (possiblePrintType) {
                        for (i = 0; i < configurations.length; i++) {
                            config = configurations[i];
                            if (excludedConfiguration !== config) {
                                if (possiblePrintType !== config.$.printType) {
                                    config.set('originalPrintType', config.$.printType, {silent: true});
                                }
                                config.set('printType', possiblePrintType, {
                                    printTypeEqualized: true,
                                    printTypeTransformed: true
                                });
                            }
                        }
                    }

                    this.$equalizingConfigurations = false;
                }
            }
        },

        {
            getPreferredPrintType: function (product, printArea, possiblePrintTypes) {
                var configurations = product.getConfigurationsOnPrintAreas(printArea);
                if (configurations && configurations.length) {
                    // first sort the possible print types by the configurations that are on print area
                    // so when the first configuration has flock then he returns flock
                    var config,
                        configPrintTypes;
                    for (var k = configurations.length - 1; k >= 0; k--) {
                        config = configurations[k];
                        var index = possiblePrintTypes.indexOf(config.$.printType);
                        if (index > 0) {
                            possiblePrintTypes.unshift(config.$.printType);
                            possiblePrintTypes.slice(index, 1);
                        }
                    }

                    var appearanceId = product.get('appearance.id'),
                        cache = {};
                    for (var j = 0; j < possiblePrintTypes.length; j++) {
                        var possiblePrintType = possiblePrintTypes[j];
                        var fitsForAll = true;
                        for (var i = 0; i < configurations.length; i++) {
                            config = configurations[i];
                            configPrintTypes = cache[config.$cid] || config.getPossiblePrintTypesForPrintArea(printArea, appearanceId);
                            // if config on same printarea
                            // AND has DD print type
                            // AND this print type is supported
                            // use this print type
                            cache[config.$cid] = configPrintTypes;

                            if (configPrintTypes.indexOf(possiblePrintType) === -1 || possiblePrintTypes.indexOf(possiblePrintType) === -1 || !config.isPrintTypeAvailable(possiblePrintType)) {
                                fitsForAll = false;
                                break;
                            }
                        }
                        if (fitsForAll) {
                            return possiblePrintType;
                        }
                    }
                }
                return null;
            }

        })

});<|endoftext|>


<commit_before>/* Purpose: Export development and production webpack configuration objects */

'use strict'

// Load modules
let env = require('./env')
let alert = require('./alert')
let fs = require('fs-extra')
let abs = require('path').resolve
let path = require('path')
let rec = require('recursive-readdir-sync')
let us = require('underscore')
let webpack = require('webpack')

// Empty cache folder
fs.emptyDirSync(abs(env.cache, 'build'))

// Create configuration
let createConfiguration = function (mode) {
  // Copy index.ejs file to cache
  try {
    fs.copySync(abs(__dirname, '../client/index.ejs'), abs(env.cache, 'index.ejs'))
  } catch (err) {
    alert('Failed to cache index.ejs file.', 'issue')
  }

  // Check mode
  if (mode !== 'development' && mode !== 'production') {
    alert('Webpack configuration needs "production" or "development" as parameter.', 'issue')
  }

  // Define loaders
  let ExtractTextPlugin = require('extract-text-webpack-plugin')
  let loaders = [
    // JS files
    {
      test: /\.js$/,
      loader: 'babel',
      include: [
        abs(__dirname, '../client'),
        abs(__dirname, '../scripts'),
        abs(env.app)
      ]
    },
    // Vue files
    {
      test: /\.vue$/,
      loader: 'vue'
    },
    // JSON files
    {
      test: /\.json$/,
      loader: 'json'
    },
    // CSS files
    {
      test: /\.css$/,
      loader: mode === 'development' ? 'vue-style-loader!css-loader' : ExtractTextPlugin.extract('css-loader' + (env.cfg.buildSourcemaps === true ? '?sourceMap' : ''))
    },
    // Image files
    {
      test: /\.(png|jpe?g|gif)(\?.*)?$/,
      loader: 'url',
      query: {
        limit: 1,
        name: 'img/[name].[hash:7].[ext]'
      }
    },
    // Preloader icon image
    {
      test: /android-chrome-192x192\.png$/,
      loader: 'url',
      query: {
        limit: 1,
        name: '[name].[ext]'
      }
    },
    // Favicon
    {
      test: /favicon\.ico$/,
      loader: 'url',
      query: {
        limit: 1,
        name: '[name].[ext]'
      }
    },
    // Loader image
    {
      test: /preloader\.svg$/,
      loader: 'url',
      query: {
        limit: 1,
        name: '[name].[ext]'
      }
    },
    // Font files
    {
      test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/,
      exclude: /preloader\.svg/,
      loader: 'url',
      query: {
        limit: 1,
        name: 'fonts/[name].[hash:7].[ext]'
      }
    }
  ]

  // Start configuration object
  let config = {
    entry: {
      app: [abs(__dirname, '../client/app.js')]
    },
    output: {
      path: mode === 'development' ? abs(env.app) : abs(env.cache, 'build/www'),
      filename: '[name].[hash:7].js'
    },
    resolve: {
      extensions: ['', '.js', '.vue', '.json'],
      alias: {
        'vue$': 'vue/dist/vue.common.js'
      }
    },
    module: {
      loaders: loaders
    },
    plugins: []
  }

  // Add themes on production build
  if (mode === 'production') {
    if (env.cfg.theme === 'ios-material' || env.cfg.theme === 'material-ios') {
      config.entry = us.extend({
        ios: [abs(__dirname, '../client/ios.js')],
        material: [abs(__dirname, '../client/material.js')]
      }, config.entry)
    } else {
      config.entry.app.unshift(abs(__dirname, '../client/' + env.cfg.theme + '.js'))
    }
  }

  // Handle image preloading
  if (env.cfg.preloadImages) {
    try {
      // List image files
      let files = rec(abs(env.app, 'images'))
      // Create preloading DIV
      let div = '
'
      files.map((file) => {
        div += '<img src="<%=require(\'' + file + '\')%>" />'
      })
      div += '
'
      // Update cached index.ejs
      let indexFile = fs.readFileSync(abs(env.cache, 'index.ejs'), 'utf8')
      indexFile = indexFile.replace('', div + '')
      fs.writeFileSync(abs(env.cache, 'index.ejs'), indexFile)
    } catch (err) {
      alert('Failed to handle image preloading.', 'issue')
    }
  }

  // Add environment variables
  let firebaseConfig = mode === 'production' ? env.cfg.firebase : env.cfg.devFirebase
  let framework = require('../package.json')
  config.plugins.push(
    new webpack.DefinePlugin({
      'process.env': {
        PROJECT_VERSION: '"' + env.pkg.version + '"',
        FRAMEWORK_VERSION: '"' + framework.version + '"',
        THEME: '"' + env.cfg.theme + '"',
        APP_ROOT_FROM_SCRIPTS: '"' + (path.relative(__dirname, env.app) + path.sep).replace(/\\/g, '\\\\\\\\') + '"',
        PROJECT_ROOT_FROM_SCRIPTS: '"' + (path.relative(__dirname, env.proj) + path.sep).replace(/\\/g, '\\\\\\\\') + '"',
        CACHE_ROOT_FROM_SCRIPTS: '"' + (path.relative(__dirname, env.cache) + path.sep).replace(/\\/g, '\\\\\\\\') + '"',
        USE_GLOBAL_DATA_OBJECT: '"' + env.cfg.useGlobalDataObject + '"',
        FONT_FRAMEWORK7: '"' + env.cfg.useIconFonts.framework7 + '"',
        FONT_MATERIAL: '"' + env.cfg.useIconFonts.material + '"',
        FONT_ION: '"' + env.cfg.useIconFonts.ion + '"',
        FONT_AWESOME: '"' + env.cfg.useIconFonts.fontawesome + '"',
        USE_FIREBASE_APP: '"' + (firebaseConfig.authDomain !== '' || firebaseConfig.databaseURL !== '' || firebaseConfig.storageBucket !== '') + '"',
        USE_FIREBASE_AUTH: '"' + (firebaseConfig.authDomain !== '') + '"',
        USE_FIREBASE_DATABASE: '"' + (firebaseConfig.databaseURL !== '') + '"',
        USE_FIREBASE_STORAGE: '"' + (firebaseConfig.storageBucket !== '') + '"',
        RESET_LOCAL_STORAGE: '"' + env.cfg.resetLocalStorageOnVersionChange + '"',
        NODE_ENV: '"' + mode + '"'
      }
    })
  )

  // Optimize ordering, reduce size
  config.plugins.push(new webpack.optimize.OccurrenceOrderPlugin())

  // Avoid exit with error in CLI
  if (mode === 'development') {
    config.plugins.push(new webpack.NoErrorsPlugin())
  }

  // Add hot file reload in development mode
  if (mode === 'development') {
    config.entry['app'].unshift(abs(__dirname, 'dev-client.js'))
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
  }

  // Extract CSS code to extra file
  if (mode === 'production') {
    config.plugins.push(
      new ExtractTextPlugin('[name].[hash:7].css')
    )
    config.vue = {
      loaders: {
        css: ExtractTextPlugin.extract('vue-style-loader', 'css-loader' + (env.cfg.buildSourcemaps === true ? '?sourceMap' : ''))
      }
    }
  }

  // Define icon tags for production
  let iconTags = ''
  if (mode === 'production') {
    iconTags = '<meta name="theme-color" content="' + env.cfg.iconBackgroundColor + '" />' +
               '<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png" />' +
               '<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />' +
               '<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />' +
               '<link rel="manifest" href="manifest.json" />'
  }

  // Plugin: HTML index file generation
  let HtmlPlugin = require('html-webpack-plugin')
  config.plugins.push(
    new HtmlPlugin({
      filename: mode === 'development' ? abs(env.app, 'index.html') : abs(env.cache, 'build/www/index.html'),
      template: abs(env.cache, 'index.ejs'),
      title: env.cfg.title,
      iconTags: iconTags, // favicon.ico will be loaded by browser default from root directory
      inject: true,
      minify: mode === 'production' ? {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      } : undefined
    })
  )

  // Add source maps
  if (mode === 'development') {
    config.devtool = '#source-map'
  } else if (mode === 'production' && env.cfg.buildSourcemaps === true) {
    config.devtool = '#source-map'
  } else {
    config.devtool = undefined
  }

  // Add JS compression
  if (mode === 'production') {
    config.plugins.push(
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    )
  }

  // Add offline support
  let OfflinePlugin = require('offline-plugin')
  if (mode === 'production') {
    config.plugins.push(new OfflinePlugin({
      version: 'v' + env.pkg.version,
      updateStrategy: 'all',
      autoUpdate: 1000 * 60 * 15,
      publicPath: '/',
      externals: [
        'offline-service-worker.js',
        'manifest.json',
        'favicon-16x16.png',
        'favicon-32x32.png',
        'android-chrome-192x192.png'
      ],
      ServiceWorker: {
        output: 'offline-service-worker.js',
        navigateFallbackURL: '/',
        events: true
      },
      AppCache: {
        directory: ''
      }
    }))
  }

  // Return object
  return config
}

// Export configuration
module.exports = {
  development: createConfiguration('development'),
  production: createConfiguration('production')
}
<commit_msg>clean-up<commit_after>/* Purpose: Export development and production webpack configuration objects */

'use strict'

// Load modules
let env = require('./env')
let alert = require('./alert')
let fs = require('fs-extra')
let abs = require('path').resolve
let path = require('path')
let rec = require('recursive-readdir-sync')
let us = require('underscore')
let webpack = require('webpack')

// Empty cache folder
fs.emptyDirSync(abs(env.cache, 'build'))

// Create configuration
let createConfiguration = function (mode) {
  // Copy index.ejs file to cache
  try {
    fs.copySync(abs(__dirname, '../client/index.ejs'), abs(env.cache, 'index.ejs'))
  } catch (err) {
    alert('Failed to cache index.ejs file.', 'issue')
  }

  // Check mode
  if (mode !== 'development' && mode !== 'production') {
    alert('Webpack configuration needs "production" or "development" as parameter.', 'issue')
  }

  // Define loaders
  let ExtractTextPlugin = require('extract-text-webpack-plugin')
  let loaders = [
    // JS files
    {
      test: /\.js$/,
      loader: 'babel',
      include: [
        abs(__dirname, '../client'),
        abs(__dirname, '../scripts'),
        abs(env.app)
      ]
    },
    // Vue files
    {
      test: /\.vue$/,
      loader: 'vue'
    },
    // JSON files
    {
      test: /\.json$/,
      loader: 'json'
    },
    // CSS files
    {
      test: /\.css$/,
      loader: mode === 'development' ? 'vue-style-loader!css-loader' : ExtractTextPlugin.extract('css-loader' + (env.cfg.buildSourcemaps === true ? '?sourceMap' : ''))
    },
    // Image files
    {
      test: /\.(png|jpe?g|gif)(\?.*)?$/,
      loader: 'url',
      query: {
        limit: 1,
        name: 'img/[name].[hash:7].[ext]'
      }
    },
    // Preloader icon image
    {
      test: /android-chrome-192x192\.png$/,
      loader: 'url',
      query: {
        limit: 1,
        name: '[name].[ext]'
      }
    },
    // Favicon
    {
      test: /favicon\.ico$/,
      loader: 'url',
      query: {
        limit: 1,
        name: '[name].[ext]'
      }
    },
    // Loader image
    {
      test: /preloader\.svg$/,
      loader: 'url',
      query: {
        limit: 1,
        name: '[name].[ext]'
      }
    },
    // Font files
    {
      test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/,
      exclude: /preloader\.svg/,
      loader: 'url',
      query: {
        limit: 1,
        name: 'fonts/[name].[hash:7].[ext]'
      }
    }
  ]

  // Start configuration object
  let config = {
    entry: {
      app: [abs(__dirname, '../client/app.js')]
    },
    output: {
      path: mode === 'development' ? abs(env.app) : abs(env.cache, 'build/www'),
      filename: '[name].[hash:7].js'
    },
    resolve: {
      extensions: ['', '.js', '.vue', '.json'],
      alias: {
        'vue$': 'vue/dist/vue.common.js'
      }
    },
    module: {
      loaders: loaders
    },
    plugins: []
  }

  // Add themes on production build
  if (mode === 'production') {
    if (env.cfg.theme === 'ios-material' || env.cfg.theme === 'material-ios') {
      config.entry = us.extend({
        ios: [abs(__dirname, '../client/ios.js')],
        material: [abs(__dirname, '../client/material.js')]
      }, config.entry)
    } else {
      config.entry.app.unshift(abs(__dirname, '../client/' + env.cfg.theme + '.js'))
    }
  }

  // Handle image preloading
  if (env.cfg.preloadImages) {
    try {
      // List image files
      let files = rec(abs(env.app, 'images'))
      // Create preloading DIV
      let div = '
'
      files.map((file) => {
        div += '<img src="<%=require(\'' + file + '\')%>" />'
      })
      div += '
'
      // Update cached index.ejs
      let indexFile = fs.readFileSync(abs(env.cache, 'index.ejs'), 'utf8')
      indexFile = indexFile.replace('', div + '')
      fs.writeFileSync(abs(env.cache, 'index.ejs'), indexFile)
    } catch (err) {
      alert('Failed to handle image preloading.', 'issue')
    }
  }

  // Add environment variables
  let framework = require('../package.json')
  config.plugins.push(
    new webpack.DefinePlugin({
      'process.env': {
        PROJECT_VERSION: '"' + env.pkg.version + '"',
        FRAMEWORK_VERSION: '"' + framework.version + '"',
        THEME: '"' + env.cfg.theme + '"',
        APP_ROOT_FROM_SCRIPTS: '"' + (path.relative(__dirname, env.app) + path.sep).replace(/\\/g, '\\\\\\\\') + '"',
        PROJECT_ROOT_FROM_SCRIPTS: '"' + (path.relative(__dirname, env.proj) + path.sep).replace(/\\/g, '\\\\\\\\') + '"',
        CACHE_ROOT_FROM_SCRIPTS: '"' + (path.relative(__dirname, env.cache) + path.sep).replace(/\\/g, '\\\\\\\\') + '"',
        USE_GLOBAL_DATA_OBJECT: '"' + env.cfg.useGlobalDataObject + '"',
        FONT_FRAMEWORK7: '"' + env.cfg.useIconFonts.framework7 + '"',
        FONT_MATERIAL: '"' + env.cfg.useIconFonts.material + '"',
        FONT_ION: '"' + env.cfg.useIconFonts.ion + '"',
        FONT_AWESOME: '"' + env.cfg.useIconFonts.fontawesome + '"',
        USE_FIREBASE_APP: '"' + (firebaseConfig.authDomain !== '' || firebaseConfig.databaseURL !== '' || firebaseConfig.storageBucket !== '') + '"',
        USE_FIREBASE_AUTH: '"' + (firebaseConfig.authDomain !== '') + '"',
        USE_FIREBASE_DATABASE: '"' + (firebaseConfig.databaseURL !== '') + '"',
        USE_FIREBASE_STORAGE: '"' + (firebaseConfig.storageBucket !== '') + '"',
        RESET_LOCAL_STORAGE: '"' + env.cfg.resetLocalStorageOnVersionChange + '"',
        NODE_ENV: '"' + mode + '"'
      }
    })
  )

  // Optimize ordering, reduce size
  config.plugins.push(new webpack.optimize.OccurrenceOrderPlugin())

  // Avoid exit with error in CLI
  if (mode === 'development') {
    config.plugins.push(new webpack.NoErrorsPlugin())
  }

  // Add hot file reload in development mode
  if (mode === 'development') {
    config.entry['app'].unshift(abs(__dirname, 'dev-client.js'))
    config.plugins.push(new webpack.HotModuleReplacementPlugin())
  }

  // Extract CSS code to extra file
  if (mode === 'production') {
    config.plugins.push(
      new ExtractTextPlugin('[name].[hash:7].css')
    )
    config.vue = {
      loaders: {
        css: ExtractTextPlugin.extract('vue-style-loader', 'css-loader' + (env.cfg.buildSourcemaps === true ? '?sourceMap' : ''))
      }
    }
  }

  // Define icon tags for production
  let iconTags = ''
  if (mode === 'production') {
    iconTags = '<meta name="theme-color" content="' + env.cfg.iconBackgroundColor + '" />' +
               '<link rel="apple-touch-icon" sizes="180x180" href="apple-touch-icon.png" />' +
               '<link rel="icon" type="image/png" href="favicon-32x32.png" sizes="32x32" />' +
               '<link rel="icon" type="image/png" href="favicon-16x16.png" sizes="16x16" />' +
               '<link rel="manifest" href="manifest.json" />'
  }

  // Plugin: HTML index file generation
  let HtmlPlugin = require('html-webpack-plugin')
  config.plugins.push(
    new HtmlPlugin({
      filename: mode === 'development' ? abs(env.app, 'index.html') : abs(env.cache, 'build/www/index.html'),
      template: abs(env.cache, 'index.ejs'),
      title: env.cfg.title,
      iconTags: iconTags, // favicon.ico will be loaded by browser default from root directory
      inject: true,
      minify: mode === 'production' ? {
        removeComments: true,
        collapseWhitespace: true,
        removeAttributeQuotes: true
      } : undefined
    })
  )

  // Add source maps
  if (mode === 'development') {
    config.devtool = '#source-map'
  } else if (mode === 'production' && env.cfg.buildSourcemaps === true) {
    config.devtool = '#source-map'
  } else {
    config.devtool = undefined
  }

  // Add JS compression
  if (mode === 'production') {
    config.plugins.push(
      new webpack.optimize.UglifyJsPlugin({
        compress: {
          warnings: false
        }
      })
    )
  }

  // Add offline support
  let OfflinePlugin = require('offline-plugin')
  if (mode === 'production') {
    config.plugins.push(new OfflinePlugin({
      version: 'v' + env.pkg.version,
      updateStrategy: 'all',
      autoUpdate: 1000 * 60 * 15,
      publicPath: '/',
      externals: [
        'offline-service-worker.js',
        'manifest.json',
        'favicon-16x16.png',
        'favicon-32x32.png',
        'android-chrome-192x192.png'
      ],
      ServiceWorker: {
        output: 'offline-service-worker.js',
        navigateFallbackURL: '/',
        events: true
      },
      AppCache: {
        directory: ''
      }
    }))
  }

  // Return object
  return config
}

// Export configuration
module.exports = {
  development: createConfiguration('development'),
  production: createConfiguration('production')
}
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular
        .module('dpStraatbeeld')
        .factory('straatbeeldApi', straatbeeldApiFactory);

    straatbeeldApiFactory.$inject = ['$q', 'STRAATBEELD_CONFIG', 'sharedConfig', 'geojson', 'api'];

    function straatbeeldApiFactory ($q, STRAATBEELD_CONFIG, sharedConfig, geojson, api) {
        const prefix = STRAATBEELD_CONFIG.STRAATBEELD_ENDPOINT_PREFIX;
        const suffix = STRAATBEELD_CONFIG.STRAATBEELD_ENDPOINT_SUFFIX;

        let cancel; // Promise to cancel any outstanding http requests

        return {
            getImageDataByLocation,
            getImageDataById
        };

        function getImageDataByLocation (location, history, key = 'panoramas') {
            if (!angular.isArray(location)) {
                return null;
            }
            const locationRange = `near=${location[1]},${location[0]}&srid=${STRAATBEELD_CONFIG.SRID}`;
            const yearRange = (history.year)
                ? `mission_year=${history.year}&mission_type=${history.missionType}`
                : 'newest_in_range=true';
            const radius = `radius=${STRAATBEELD_CONFIG.MAX_RADIUS}`;

            return getStraatbeeld(
                `${sharedConfig.API_ROOT}${prefix}/?${locationRange}&${yearRange}&${radius}`,
                key
            );
        }

        function getImageDataById (id, history, key = 'adjacencies') {
            const yearRange = (history.year)
                ? `mission_year=${history.year}&mission_type=${history.missionType}`
                : 'newest_in_range=true';
            const radius = `radius=${STRAATBEELD_CONFIG.MAX_RADIUS}`;

            return getStraatbeeld(
                `${sharedConfig.API_ROOT}${prefix}/${id}/${suffix}/?${yearRange}&${radius}`,
                key
            );
        }

        function getStraatbeeld (url, key) {
            if (cancel) {
                // Cancel any outstanding requests
                cancel.resolve();
            }
            cancel = $q.defer();
            return api.getByUrl(url, undefined, cancel)
                .then((json) => json._embedded)
                .then((data) => (data) ? data[key] : null)
                .then(imageData)
                .finally(() => cancel = null);
        }

        function imageData (response) {
            const panorama = response && response[0];
            const adjacencies = response && response.filter((adjacency) => adjacency !== panorama);

            if (panorama && angular.isObject(panorama.geometry)) {
                const formattedGeometry = {
                    coordinates: [
                        panorama.geometry.coordinates[1],
                        panorama.geometry.coordinates[0]
                    ],
                    type: panorama.geometry.type
                };

                return {
                    date: new Date(panorama.timestamp),
                    id: panorama.pano_id,
                    hotspots: adjacencies.map(function (adjacency) {
                        return {
                            id: adjacency.pano_id,
                            heading: adjacency.direction,
                            distance: adjacency.distance,
                            year: parseInt(adjacency.timestamp.substring(0, 4))
                        };
                    }),
                    location: geojson.getCenter(formattedGeometry),
                    image: {
                        baseurl: panorama.cubic_img_baseurl,
                        pattern: panorama.cubic_img_pattern,
                        preview: panorama.cubic_img_baseurl
                    }
                };
            }
            return null;
        }
    }
})();
<commit_msg>DP-5851 extra call for the ajacencies<commit_after>(function () {
    'use strict';

    angular
        .module('dpStraatbeeld')
        .factory('straatbeeldApi', straatbeeldApiFactory);

    straatbeeldApiFactory.$inject = ['$q', 'STRAATBEELD_CONFIG', 'sharedConfig', 'geojson', 'api'];

    function straatbeeldApiFactory ($q, STRAATBEELD_CONFIG, sharedConfig, geojson, api) {
        const prefix = STRAATBEELD_CONFIG.STRAATBEELD_ENDPOINT_PREFIX;
        const suffix = STRAATBEELD_CONFIG.STRAATBEELD_ENDPOINT_SUFFIX;

        let cancel; // Promise to cancel any outstanding http requests

        return {
            getImageDataByLocation,
            getImageDataById
        };

        function getImageDataByLocation (location, history, key = 'panoramas') {
            if (!angular.isArray(location)) {
                return null;
            }
            const locationRange =
                `near=${location[1]},${location[0]}&srid=${STRAATBEELD_CONFIG.SRID}&newest_in_range=true`;
            const yearRange = (history.year)
                ? `mission_year=${history.year}&mission_type=${history.missionType}`
                : '';
            const radius = `radius=${STRAATBEELD_CONFIG.MAX_RADIUS}`;

            const q = $q.defer();
            const url = `${sharedConfig.API_ROOT}${prefix}/?${locationRange}&${yearRange}&${radius}`;
            api.getByUrl(url, undefined, cancel)
                .then((json) => json._embedded)
                .then((data) => (data && data[key]) ? data[key][0] : null)
                .then((item) => {
                    q.resolve(
                        getStraatbeeld(
                            `${item._links.adjacencies.href}?${yearRange}&newest_in_range=true`,
                            'adjacencies'
                        )
                    );
                })
                .finally(() => cancel = null);

            return q.promise;
        }

        function getImageDataById (id, history, key = 'adjacencies') {
            const yearRange = (history.year)
                ? `mission_year=${history.year}&mission_type=${history.missionType}`
                : 'newest_in_range=true';
            const radius = `radius=${STRAATBEELD_CONFIG.MAX_RADIUS}`;

            return getStraatbeeld(
                `${sharedConfig.API_ROOT}${prefix}/${id}/${suffix}/?${yearRange}&${radius}`,
                key
            );
        }

        function getStraatbeeld (url, key) {
            if (cancel) {
                // Cancel any outstanding requests
                cancel.resolve();
            }
            cancel = $q.defer();
            return api.getByUrl(url, undefined, cancel)
                .then((json) => json._embedded)
                .then((data) => (data) ? data[key] : null)
                .then(imageData)
                .finally(() => cancel = null);
        }

        function imageData (response) {
            const panorama = response && response[0];
            const adjacencies = response && response.filter((adjacency) => adjacency !== panorama);

            if (panorama && angular.isObject(panorama.geometry)) {
                const formattedGeometry = {
                    coordinates: [
                        panorama.geometry.coordinates[1],
                        panorama.geometry.coordinates[0]
                    ],
                    type: panorama.geometry.type
                };

                return {
                    date: new Date(panorama.timestamp),
                    id: panorama.pano_id,
                    hotspots: adjacencies.map(function (adjacency) {
                        return {
                            id: adjacency.pano_id,
                            heading: adjacency.direction,
                            distance: adjacency.distance,
                            year: parseInt(adjacency.timestamp.substring(0, 4))
                        };
                    }),
                    location: geojson.getCenter(formattedGeometry),
                    image: {
                        baseurl: panorama.cubic_img_baseurl,
                        pattern: panorama.cubic_img_pattern,
                        preview: panorama.cubic_img_preview
                    }
                };
            }
            return null;
        }
    }
})();
<|endoftext|>


<commit_before>import React, {Component} from 'react';
import ReactDOM from 'react-dom';

import {Dummy} from '../..';

const App = class App extends Component {
    constructor(props) {
        super(props);
        this.state = {};
    }

    render() {
        return (

                <Dummy></Dummy>

        );
    }
};

ReactDOM.render(
    <App />,
    document.getElementById('example')
);
<commit_msg>fix loading library from examples<commit_after>import React, {Component} from 'react';
import ReactDOM from 'react-dom';

import {Dummy} from '../../src';

const App = class App extends Component {
    constructor(props) {
        super(props);
        this.state = {};
    }

    render() {
        return (

                <Dummy></Dummy>

        );
    }
};

ReactDOM.render(
    <App />,
    document.getElementById('example')
);
<|endoftext|>


<commit_before>Parse.Cloud.beforeSave(Parse.User, function(request, response) {
	var user = request.object;

	if(user.isNew()) {
        user.set("balance", 0);
        response.success(user);
        return;
    }

	if(user.dirty('balance')) {
		let query = new Parse.Query(Parse.User);
		query.get(user.id).then((oldUser) => {
			if (!oldUser) {
				response.success();
				return;
			}
			const value = oldUser.get("balance") - user.get("balance");

			let history = new Parse.Object("History");
			history.set("user", user);
			history.set("value", value);

			history.save().then(() => {
                response.success(user);
            },(error) => {
                response.error(error);
            });
		},(error) => {
			response.error(error);
		});
	} else {
		response.success(user);
	}
});

Parse.Cloud.beforeSave("Session", function (request, response) {
	var session = request.object;
	let query = new Parse.Query("Session");
	query.equalTo("user", session.get("user")).first((s) => {
		if(!s){
			response.success();
			return;
		}

		return s.destroy();
	}).then(() => {
		response.success();
	}, (error) => {
		response.error(error);
	})
});<commit_msg>correçãO<commit_after>Parse.Cloud.beforeSave(Parse.User, function(request, response) {
	var user = request.object;

	if(user.isNew()) {
        user.set("balance", 0);
        response.success(user);
        return;
    }

	if(user.dirty('balance')) {
		let query = new Parse.Query(Parse.User);
		query.get(user.id).then((oldUser) => {
			if (!oldUser) {
				response.success();
				return;
			}
			const value = oldUser.get("balance") - user.get("balance");

			let history = new Parse.Object("History");
			history.set("user", oldUser);
			history.set("value", value);

			history.save().then(() => {
                response.success(oldUser);
            },(error) => {
                response.error(error);
            });
		},(error) => {
			response.error(error);
		});
	} else {
		response.success(user);
	}
});

Parse.Cloud.beforeSave("Session", function (request, response) {
	var session = request.object;
	let query = new Parse.Query("Session");
	query.equalTo("user", session.get("user")).first((s) => {
		if(!s){
			response.success();
			return;
		}

		return s.destroy();
	}).then(() => {
		response.success();
	}, (error) => {
		response.error(error);
	})
});<|endoftext|>


<commit_before>import { SceneParser } from '../resources/parser/scene.js';

/**
 * @private
 * @class
 * @name Template
 * @classdesc Create a Template resource from raw database data.
 * @param {Application} app - The application.
 * @param {object} data - Asset data from the database.
 */
class Template {
    constructor(app, data) {
        this._app = app;

        this._data = data;

        this._templateRoot = null;
    }

    /**
     * @private
     * @function
     * @name Template#instantiate
     * @description Create an instance of this template.
     * @returns {Entity} The root entity of the created instance.
     */
    instantiate() {
        if (!this._templateRoot) { // at first use, after scripts are loaded
            this._parseTemplate();
        }

        return this._templateRoot.clone();
    }

    _parseTemplate() {
        var parser = new SceneParser(this._app, true);

        this._templateRoot = parser.parse(this._data);
    }
}

export { Template };
<commit_msg>Template JS docs now public (#3035)<commit_after>import { SceneParser } from '../resources/parser/scene.js';

/**
 * @class
 * @name Template
 * @classdesc Create a Template resource from raw database data.
 * @param {Application} app - The application.
 * @param {object} data - Asset data from the database.
 */
class Template {
    constructor(app, data) {
        this._app = app;

        this._data = data;

        this._templateRoot = null;
    }

    /**
     * @function
     * @name Template#instantiate
     * @description Create an instance of this template.
     * @returns {Entity} The root entity of the created instance.
     */
    instantiate() {
        if (!this._templateRoot) { // at first use, after scripts are loaded
            this._parseTemplate();
        }

        return this._templateRoot.clone();
    }

    _parseTemplate() {
        var parser = new SceneParser(this._app, true);

        this._templateRoot = parser.parse(this._data);
    }
}

export { Template };
<|endoftext|>


<commit_before>test('Dates | Traditional Chinese', function () {

  var now = new Date();
  Date.setLocale('zh-TW');

  dateEqual(Date.create('1/2/13'), new Date(2013, 1, 1), 'Date#create | Traditional Chinese | uses American style ambiguity');
  return;

  dateEqual(Date.create('2011年5月15日'), new Date(2011, 4, 15), 'Date#create | basic Traditional Chinese date');
  dateEqual(Date.create('2011年5月'), new Date(2011, 4), 'Date#create | Traditional Chinese | year and month');
  dateEqual(Date.create('5月15日'), new Date(now.getFullYear(), 4, 15), 'Date#create | Traditional Chinese | month and date');
  dateEqual(Date.create('2011年'), new Date(2011, 0), 'Date#create | Traditional Chinese | year');
  dateEqual(Date.create('5月'), new Date(now.getFullYear(), 4), 'Date#create | Traditional Chinese | month');
  dateEqual(Date.create('15日'), new Date(now.getFullYear(), now.getMonth(), 15), 'Date#create | Traditional Chinese | date');
  dateEqual(Date.create('星期一'), getDateWithWeekdayAndOffset(1), 'Date#create | Traditional Chinese | Monday');
  dateEqual(Date.create('九日'), new Date(now.getFullYear(), now.getMonth(), 9), 'Date#create | Traditional Chinese | the 9th');
  dateEqual(Date.create('二十五日'), new Date(now.getFullYear(), now.getMonth(), 25), 'Date#create | Traditional Chinese | the 25th');
  dateEqual(Date.create('二十五號'), new Date(now.getFullYear(), now.getMonth(), 25), 'Date#create | Traditional Chinese | 號 should be understood as well');

  dateEqual(Date.create('2011年5月15日 3:45'), new Date(2011, 4, 15, 3, 45), 'Date#create | basic Traditional Chinese date 3:45');
  dateEqual(Date.create('2011年5月15日 3:45pm'), new Date(2011, 4, 15, 15, 45), 'Date#create | basic Traditional Chinese date 3:45pm');
  dateEqual(Date.create('2011年5月15日 3點45分鐘'), new Date(2011, 4, 15, 3, 45), 'Date#create | basic Traditional Chinese date 3:45pm kanji');
  dateEqual(Date.create('2011年5月15日 下午3點45分鐘'), new Date(2011, 4, 15, 15, 45), 'Date#create | basic Traditional Chinese date 3:45pm kanji afternoon');

  dateEqual(Date.create('一毫秒前'), getRelativeDate(null, null, null, null, null, null,-1), 'Date#create | Traditional Chinese | one millisecond ago');
  dateEqual(Date.create('一秒鐘前'), getRelativeDate(null, null, null, null, null, -1), 'Date#create | Traditional Chinese | one second ago');
  dateEqual(Date.create('一分鐘前'), getRelativeDate(null, null, null, null, -1), 'Date#create | Traditional Chinese | one minute ago');
  dateEqual(Date.create('一小時前'), getRelativeDate(null, null, null, -1), 'Date#create | Traditional Chinese | one hour ago');
  dateEqual(Date.create('一天前'), getRelativeDate(null, null, -1), 'Date#create | Traditional Chinese | one day ago');
  dateEqual(Date.create('一週前'), getRelativeDate(null, null, -7), 'Date#create | Traditional Chinese | one week 週');
  dateEqual(Date.create('一個星期前'), getRelativeDate(null, null, -7), 'Date#create | Traditional Chinese | one week 個星期');
  dateEqual(Date.create('一個月前'), getRelativeDate(null, -1), 'Date#create | Traditional Chinese | one month ago');
  dateEqual(Date.create('一年前'), getRelativeDate(-1), 'Date#create | Traditional Chinese | one year ago');

  dateEqual(Date.create('5毫秒後'), getRelativeDate(null, null, null, null, null, null, 5), 'Date#create | Traditional Chinese | five millisecond from now');
  dateEqual(Date.create('5秒鐘後'), getRelativeDate(null, null, null, null, null, 5), 'Date#create | Traditional Chinese | five second from now');
  dateEqual(Date.create('5分鐘後'), getRelativeDate(null, null, null, null, 5), 'Date#create | Traditional Chinese | five minute from now');
  dateEqual(Date.create('5小時後'), getRelativeDate(null, null, null, 5), 'Date#create | Traditional Chinese | five hour from now');
  dateEqual(Date.create('5天後'), getRelativeDate(null, null, 5), 'Date#create | Traditional Chinese | five day from now');
  dateEqual(Date.create('5週後'), getRelativeDate(null, null, 35), 'Date#create | Traditional Chinese | five weeks from now 週');
  dateEqual(Date.create('5個星期後'), getRelativeDate(null, null, 35), 'Date#create | Traditional Chinese | five weeks from now 個星期');
  dateEqual(Date.create('5個月後'), getRelativeDate(null, 5), 'Date#create | Traditional Chinese | five months');
  dateEqual(Date.create('5年後'), getRelativeDate(5), 'Date#create | Traditional Chinese | five years from now');

  dateEqual(Date.create('２０１１年'), new Date(2011, 0), 'Date#create | Traditional Chinese | full-width year');

  dateEqual(Date.create('前天'), getRelativeDate(null, null, -2).resetTime(), 'Date#create | Traditional Chinese | 一昨日');
  dateEqual(Date.create('昨天'), getRelativeDate(null, null, -1).resetTime(), 'Date#create | Traditional Chinese | yesterday');
  dateEqual(Date.create('今天'), getRelativeDate(null, null, 0).resetTime(), 'Date#create | Traditional Chinese | today');
  dateEqual(Date.create('明天'), getRelativeDate(null, null, 1).resetTime(), 'Date#create | Traditional Chinese | tomorrow');
  dateEqual(Date.create('後天'), getRelativeDate(null, null, 2).resetTime(), 'Date#create | Traditional Chinese | 明後日');

  dateEqual(Date.create('上週'), getRelativeDate(null, null, -7), 'Date#create | Traditional Chinese | Last week');
  dateEqual(Date.create('這週'), getRelativeDate(null, null, 0), 'Date#create | Traditional Chinese | This week');
  dateEqual(Date.create('下週'), getRelativeDate(null, null, 7), 'Date#create | Traditional Chinese | Next week');

  dateEqual(Date.create('上個月'), getRelativeDate(null, -1), 'Date#create | Traditional Chinese | last month');
  dateEqual(Date.create('這個月'), getRelativeDate(null, 0), 'Date#create | Traditional Chinese | this month');
  dateEqual(Date.create('下個月'), getRelativeDate(null, 1), 'Date#create | Traditional Chinese | Next month');

  dateEqual(Date.create('去年'), getRelativeDate(-1), 'Date#create | Traditional Chinese | Last year');
  dateEqual(Date.create('明年'), getRelativeDate(1), 'Date#create | Traditional Chinese | Next year');

  dateEqual(Date.create('上週三'), getDateWithWeekdayAndOffset(3, -7), 'Date#create | Traditional Chinese | Last wednesday');
  dateEqual(Date.create('這個月'), getRelativeDate(null, 0), 'Date#create | Traditional Chinese | this month');
  dateEqual(Date.create('下週五'), getDateWithWeekdayAndOffset(5, 7), 'Date#create | Traditional Chinese | Next friday');

  equal(Date.create('2011-08-25').format(), '2011年8月25日', 'Date#create | Traditional Chinese | standard format');
  equal(Date.create('2011-08-25').format('{yyyy}年{MM}月{dd}日'), '2011年08月25日', 'Date#create | Traditional Chinese | format');

  equal(Date.create('1 second ago').relative(), '1秒鐘前', 'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 minute ago').relative(), '1分鐘前',  'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 hour ago').relative(),   '1小時前',     'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 day ago').relative(),    '1天前',    'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 week ago').relative(),   '1個星期前',  'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 month ago').relative(),  '1個月前',   'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 year ago').relative(),   '1年前',     'Date#create | Traditional Chinese | relative format past');

  equal(Date.create('2 seconds ago').relative(), '2秒鐘前', 'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 minutes ago').relative(), '2分鐘前',  'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 hours ago').relative(),   '2小時前',     'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 days ago').relative(),    '2天前',    'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 weeks ago').relative(),   '2個星期前',  'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 months ago').relative(),  '2個月前',   'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 years ago').relative(),   '2年前',     'Date#create | Traditional Chinese | relative format past');

  equal(Date.create('1 second from now').relative(), '1秒鐘後', 'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 minute from now').relative(), '1分鐘後',  'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 hour from now').relative(),   '1小時後',     'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 day from now').relative(),    '1天後',    'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 week from now').relative(),   '1個星期後',  'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 month from now').relative(),  '1個月後',   'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 year from now').relative(),   '1年後',     'Date#create | Traditional Chinese | relative format future');

  equal(Date.create('5 second from now').relative(), '5秒鐘後', 'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 minute from now').relative(), '5分鐘後',  'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 hour from now').relative(),   '5小時後',     'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 day from now').relative(),    '5天後',    'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 week from now').relative(),   '1個月後',  'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 month from now').relative(),  '5個月後',   'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 year from now').relative(),   '5年後',     'Date#create | Traditional Chinese | relative format future');

  //dateEqual(Date.create('1/2/13'), new Date(2013, 1, 1), 'Date#create | Traditional Chinese | uses American style ambiguity');

});
<commit_msg>forgot tw<commit_after>test('Dates | Traditional Chinese', function () {

  var now = new Date();
  Date.setLocale('zh-TW');

  dateEqual(Date.create('2011年5月15日'), new Date(2011, 4, 15), 'Date#create | basic Traditional Chinese date');
  dateEqual(Date.create('2011年5月'), new Date(2011, 4), 'Date#create | Traditional Chinese | year and month');
  dateEqual(Date.create('5月15日'), new Date(now.getFullYear(), 4, 15), 'Date#create | Traditional Chinese | month and date');
  dateEqual(Date.create('2011年'), new Date(2011, 0), 'Date#create | Traditional Chinese | year');
  dateEqual(Date.create('5月'), new Date(now.getFullYear(), 4), 'Date#create | Traditional Chinese | month');
  dateEqual(Date.create('15日'), new Date(now.getFullYear(), now.getMonth(), 15), 'Date#create | Traditional Chinese | date');
  dateEqual(Date.create('星期一'), getDateWithWeekdayAndOffset(1), 'Date#create | Traditional Chinese | Monday');
  dateEqual(Date.create('九日'), new Date(now.getFullYear(), now.getMonth(), 9), 'Date#create | Traditional Chinese | the 9th');
  dateEqual(Date.create('二十五日'), new Date(now.getFullYear(), now.getMonth(), 25), 'Date#create | Traditional Chinese | the 25th');
  dateEqual(Date.create('二十五號'), new Date(now.getFullYear(), now.getMonth(), 25), 'Date#create | Traditional Chinese | 號 should be understood as well');

  dateEqual(Date.create('2011年5月15日 3:45'), new Date(2011, 4, 15, 3, 45), 'Date#create | basic Traditional Chinese date 3:45');
  dateEqual(Date.create('2011年5月15日 3:45pm'), new Date(2011, 4, 15, 15, 45), 'Date#create | basic Traditional Chinese date 3:45pm');
  dateEqual(Date.create('2011年5月15日 3點45分鐘'), new Date(2011, 4, 15, 3, 45), 'Date#create | basic Traditional Chinese date 3:45pm kanji');
  dateEqual(Date.create('2011年5月15日 下午3點45分鐘'), new Date(2011, 4, 15, 15, 45), 'Date#create | basic Traditional Chinese date 3:45pm kanji afternoon');

  dateEqual(Date.create('一毫秒前'), getRelativeDate(null, null, null, null, null, null,-1), 'Date#create | Traditional Chinese | one millisecond ago');
  dateEqual(Date.create('一秒鐘前'), getRelativeDate(null, null, null, null, null, -1), 'Date#create | Traditional Chinese | one second ago');
  dateEqual(Date.create('一分鐘前'), getRelativeDate(null, null, null, null, -1), 'Date#create | Traditional Chinese | one minute ago');
  dateEqual(Date.create('一小時前'), getRelativeDate(null, null, null, -1), 'Date#create | Traditional Chinese | one hour ago');
  dateEqual(Date.create('一天前'), getRelativeDate(null, null, -1), 'Date#create | Traditional Chinese | one day ago');
  dateEqual(Date.create('一週前'), getRelativeDate(null, null, -7), 'Date#create | Traditional Chinese | one week 週');
  dateEqual(Date.create('一個星期前'), getRelativeDate(null, null, -7), 'Date#create | Traditional Chinese | one week 個星期');
  dateEqual(Date.create('一個月前'), getRelativeDate(null, -1), 'Date#create | Traditional Chinese | one month ago');
  dateEqual(Date.create('一年前'), getRelativeDate(-1), 'Date#create | Traditional Chinese | one year ago');

  dateEqual(Date.create('5毫秒後'), getRelativeDate(null, null, null, null, null, null, 5), 'Date#create | Traditional Chinese | five millisecond from now');
  dateEqual(Date.create('5秒鐘後'), getRelativeDate(null, null, null, null, null, 5), 'Date#create | Traditional Chinese | five second from now');
  dateEqual(Date.create('5分鐘後'), getRelativeDate(null, null, null, null, 5), 'Date#create | Traditional Chinese | five minute from now');
  dateEqual(Date.create('5小時後'), getRelativeDate(null, null, null, 5), 'Date#create | Traditional Chinese | five hour from now');
  dateEqual(Date.create('5天後'), getRelativeDate(null, null, 5), 'Date#create | Traditional Chinese | five day from now');
  dateEqual(Date.create('5週後'), getRelativeDate(null, null, 35), 'Date#create | Traditional Chinese | five weeks from now 週');
  dateEqual(Date.create('5個星期後'), getRelativeDate(null, null, 35), 'Date#create | Traditional Chinese | five weeks from now 個星期');
  dateEqual(Date.create('5個月後'), getRelativeDate(null, 5), 'Date#create | Traditional Chinese | five months');
  dateEqual(Date.create('5年後'), getRelativeDate(5), 'Date#create | Traditional Chinese | five years from now');

  dateEqual(Date.create('２０１１年'), new Date(2011, 0), 'Date#create | Traditional Chinese | full-width year');

  dateEqual(Date.create('前天'), getRelativeDate(null, null, -2).resetTime(), 'Date#create | Traditional Chinese | 一昨日');
  dateEqual(Date.create('昨天'), getRelativeDate(null, null, -1).resetTime(), 'Date#create | Traditional Chinese | yesterday');
  dateEqual(Date.create('今天'), getRelativeDate(null, null, 0).resetTime(), 'Date#create | Traditional Chinese | today');
  dateEqual(Date.create('明天'), getRelativeDate(null, null, 1).resetTime(), 'Date#create | Traditional Chinese | tomorrow');
  dateEqual(Date.create('後天'), getRelativeDate(null, null, 2).resetTime(), 'Date#create | Traditional Chinese | 明後日');

  dateEqual(Date.create('上週'), getRelativeDate(null, null, -7), 'Date#create | Traditional Chinese | Last week');
  dateEqual(Date.create('這週'), getRelativeDate(null, null, 0), 'Date#create | Traditional Chinese | This week');
  dateEqual(Date.create('下週'), getRelativeDate(null, null, 7), 'Date#create | Traditional Chinese | Next week');

  dateEqual(Date.create('上個月'), getRelativeDate(null, -1), 'Date#create | Traditional Chinese | last month');
  dateEqual(Date.create('這個月'), getRelativeDate(null, 0), 'Date#create | Traditional Chinese | this month');
  dateEqual(Date.create('下個月'), getRelativeDate(null, 1), 'Date#create | Traditional Chinese | Next month');

  dateEqual(Date.create('去年'), getRelativeDate(-1), 'Date#create | Traditional Chinese | Last year');
  dateEqual(Date.create('明年'), getRelativeDate(1), 'Date#create | Traditional Chinese | Next year');

  dateEqual(Date.create('上週三'), getDateWithWeekdayAndOffset(3, -7), 'Date#create | Traditional Chinese | Last wednesday');
  dateEqual(Date.create('這個月'), getRelativeDate(null, 0), 'Date#create | Traditional Chinese | this month');
  dateEqual(Date.create('下週五'), getDateWithWeekdayAndOffset(5, 7), 'Date#create | Traditional Chinese | Next friday');

  equal(Date.create('2011-08-25').format(), '2011年8月25日', 'Date#create | Traditional Chinese | standard format');
  equal(Date.create('2011-08-25').format('{yyyy}年{MM}月{dd}日'), '2011年08月25日', 'Date#create | Traditional Chinese | format');

  equal(Date.create('1 second ago').relative(), '1秒鐘前', 'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 minute ago').relative(), '1分鐘前',  'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 hour ago').relative(),   '1小時前',     'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 day ago').relative(),    '1天前',    'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 week ago').relative(),   '1個星期前',  'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 month ago').relative(),  '1個月前',   'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('1 year ago').relative(),   '1年前',     'Date#create | Traditional Chinese | relative format past');

  equal(Date.create('2 seconds ago').relative(), '2秒鐘前', 'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 minutes ago').relative(), '2分鐘前',  'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 hours ago').relative(),   '2小時前',     'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 days ago').relative(),    '2天前',    'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 weeks ago').relative(),   '2個星期前',  'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 months ago').relative(),  '2個月前',   'Date#create | Traditional Chinese | relative format past');
  equal(Date.create('2 years ago').relative(),   '2年前',     'Date#create | Traditional Chinese | relative format past');

  equal(Date.create('1 second from now').relative(), '1秒鐘後', 'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 minute from now').relative(), '1分鐘後',  'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 hour from now').relative(),   '1小時後',     'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 day from now').relative(),    '1天後',    'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 week from now').relative(),   '1個星期後',  'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 month from now').relative(),  '1個月後',   'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('1 year from now').relative(),   '1年後',     'Date#create | Traditional Chinese | relative format future');

  equal(Date.create('5 second from now').relative(), '5秒鐘後', 'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 minute from now').relative(), '5分鐘後',  'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 hour from now').relative(),   '5小時後',     'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 day from now').relative(),    '5天後',    'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 week from now').relative(),   '1個月後',  'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 month from now').relative(),  '5個月後',   'Date#create | Traditional Chinese | relative format future');
  equal(Date.create('5 year from now').relative(),   '5年後',     'Date#create | Traditional Chinese | relative format future');

  //dateEqual(Date.create('1/2/13'), new Date(2013, 1, 1), 'Date#create | Traditional Chinese | uses American style ambiguity');

});
<|endoftext|>