<commit_before>import _clone from 'lodash-es/clone';
import _map from 'lodash-es/map';
import _flattenDeep from 'lodash-es/flatten';
import { geoExtent, geoLineIntersection } from '../geo';
import { set as d3_set } from 'd3-collection';
import { utilDisplayLabel } from '../util';
import { t } from '../util/locale';
import {
    ValidationIssueType,
    ValidationIssueSeverity,
    validationIssue,
    validationIssueFix
} from './validation_issue';
import { osmNode } from '../osm';
import { actionAddMidpoint } from '../actions';
import { geoChooseEdge } from '../geo';

export function validationHighwayCrossingOtherWays(context) {
    // Check if the edge going from n1 to n2 crosses (without a connection node)
    // any edge on way. Return the corss point if so.
    function findEdgeToWayCrossCoords(n1, n2, way, graph, edgePairsVisited) {
        var crossCoords = [];
        for (var j = 0; j < way.nodes.length - 1; j++) {
            var nidA = way.nodes[j],
                nidB = way.nodes[j + 1];
            if (nidA === n1.id || nidA === n2.id ||
                nidB === n1.id || nidB === n2.id) {
                // n1 or n2 is a connection node; skip
                continue;
            }

            var edgePair = edgePairString(n1.id, n2.id, nidA, nidB);
            if (edgePairsVisited.has(edgePair)) continue;
            edgePairsVisited.add(edgePair);

            var nA = graph.entity(nidA),
                nB = graph.entity(nidB),
                point = geoLineIntersection([n1.loc, n2.loc], [nA.loc, nB.loc]);
            if (point) crossCoords.push(point);
        }
        return crossCoords;
    }

    // n1 and n2 from one edge, nA and nB from the other edge
    function edgePairString(n1, n2, nA, nB) {
        return n1 > nA ? n1 + n2 + nA + nB : nA + nB + n1 + n2;
    }

    // returns the way or its parent relation, whichever has a useful feature type
    function getFeatureWithFeatureTypeTagsForWay(way, graph) {
        if (getFeatureTypeForTags(way.tags) === null) {
            // if the way doesn't match a feature type, check is parent relations
            var parentRels = graph.parentRelations(way);
            for (var i = 0; i < parentRels.length; i++) {
                var rel = parentRels[i];
                if (getFeatureTypeForTags(rel.tags) !== null) {
                    return rel;
                }
            }
        }
        return way;
    }

    function hasTag(tags, key) {
        return tags[key] !== undefined && tags[key] !== 'no';
    }

    function getFeatureTypeForCrossingCheck(way, graph) {
        var tags = getFeatureWithFeatureTypeTagsForWay(way, graph).tags;
        return getFeatureTypeForTags(tags);
    }

    function getFeatureTypeForTags(tags) {
        if (hasTag(tags, 'highway')) return 'highway';
        if (hasTag(tags, 'building')) return 'building';
        if (hasTag(tags, 'railway')) return 'railway';
        if (hasTag(tags, 'waterway') || tags.natural === 'water') return 'water';

        return null;
    }

    function extendTagsByInferredLayer(tags, way) {
        if (!hasTag(tags, 'layer')) {
            tags.layer = way.layer().toString();
        }
        return tags;
    }

    function isLegitCrossing(way1, featureType1, way2, featureType2, graph) {
        var tags1 = _clone(getFeatureWithFeatureTypeTagsForWay(way1, graph).tags),
            tags2 = _clone(getFeatureWithFeatureTypeTagsForWay(way2, graph).tags);
        tags1 = extendTagsByInferredLayer(tags1, way1);
        tags2 = extendTagsByInferredLayer(tags2, way2);

        // For better readability, not chaining all the true conditions into one if statement.
        if ((featureType1 === 'highway' && featureType2 === 'highway') ||
            (featureType1 === 'highway' && featureType2 === 'railway') ||
            (featureType1 === 'railway' && featureType2 === 'railway')) {
            // Legit cases:
            // (1) they're on different layers
            // (2) only one of the two ways is on a bridge
            // (3) only one of the two ways is in a tunnel
            if (tags1.layer !== tags2.layer) return true;
            if (hasTag(tags1, 'bridge') && !hasTag(tags2, 'bridge')) return true;
            if (!hasTag(tags1, 'bridge') && hasTag(tags2, 'bridge')) return true;
            if (hasTag(tags1, 'tunnel') && !hasTag(tags2, 'tunnel')) return true;
            if (!hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel')) return true;
        }
        if ((featureType1 === 'highway' && featureType2 === 'water') ||
            (featureType1 === 'railway' && featureType2 === 'water')) {
            // Legit cases:
            // (1) highway/railway is on a bridge
            // (2) only one of the two ways is in a tunnel
            // (3) both are in tunnels but on different layers
            if (hasTag(tags1, 'bridge')) return true;
            if (hasTag(tags1, 'tunnel') && !hasTag(tags2, 'tunnel')) return true;
            if (!hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel')) return true;
            if (hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel') && tags1.layer !== tags2.layer) return true;
        }
        if ((featureType1 === 'highway' && featureType2 === 'building') ||
            (featureType1 === 'railway' && featureType2 === 'building')) {
            // Legit cases:
            // (1) highway/railway has a bridge or tunnel tag
            // (2) highway/railway has a covered tag
            if (hasTag(tags1, 'bridge') || hasTag(tags1, 'tunnel') || hasTag(tags1, 'covered')) return true;
        }
        if (featureType1 === 'water' && featureType2 === 'water') {
            // Legit cases:
            // (1) only one of the water is in a tunnel
            // (2) both are in tunnels but on differnt layers
            if (hasTag(tags1, 'tunnel') && !hasTag(tags2, 'tunnel')) return true;
            if (!hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel')) return true;
            if (hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel') && tags1.layer !== tags2.layer) return true;
        }
        if (featureType1 === 'water' && featureType2 === 'building') {
            // Legit cases:
            // (1) water is in a tunnel
            // (2) water has a covered tag
            if (hasTag(tags1, 'tunnel') || hasTag(tags1, 'covered')) return true;
        }
        if (featureType1 === 'building' && featureType2 === 'building') {
            // Legit case: they're on different layers
            if (tags1.layer !== tags2.layer) return true;
        }
        return false;
    }

    function findCrossingsByWay(entity, graph, tree, edgePairsVisited) {
        var edgeCrossInfos = [];
        if (entity.type !== 'way') return edgeCrossInfos;

        var entFeatureType = getFeatureTypeForCrossingCheck(entity, graph);
        if (entFeatureType === null) return edgeCrossInfos;

        for (var i = 0; i < entity.nodes.length - 1; i++) {
            var nid1 = entity.nodes[i],
                nid2 = entity.nodes[i + 1],
                n1 = graph.entity(nid1),
                n2 = graph.entity(nid2),
                extent = geoExtent([
                    [
                        Math.min(n1.loc[0], n2.loc[0]),
                        Math.min(n1.loc[1], n2.loc[1])
                    ],
                    [
                        Math.max(n1.loc[0], n2.loc[0]),
                        Math.max(n1.loc[1], n2.loc[1])
                    ]
                ]),
                intersected = tree.intersects(extent, graph);
            for (var j = 0; j < intersected.length; j++) {
                if (intersected[j].type !== 'way') continue;

                // only check crossing highway, waterway, building, and railway
                var way = intersected[j],
                    wayFeatureType = getFeatureTypeForCrossingCheck(way, graph);
                if (wayFeatureType === null ||
                    isLegitCrossing(entity, entFeatureType, way, wayFeatureType, graph) ||
                    isLegitCrossing(way, wayFeatureType, entity, entFeatureType, graph)) {
                    continue;
                }

                var crossCoords = findEdgeToWayCrossCoords(n1, n2, way, graph, edgePairsVisited);
                for (var k = 0; k < crossCoords.length; k++) {
                    edgeCrossInfos.push({
                        ways: [entity, way],
                        featureTypes: [entFeatureType, wayFeatureType],
                        cross_point: crossCoords[k],
                    });
                }
            }
        }
        return edgeCrossInfos;
    }

    var validation = function(entitiesToCheck, graph, tree) {
        // create one issue per crossing point
        var edgePairsVisited = d3_set(),
            issues = [];
        var waysToCheck = _flattenDeep(_map(entitiesToCheck, function(entity) {
            if (!getFeatureTypeForTags(entity.tags)) {
                return [];
            }
            if (entity.type === 'way') {
                return entity;
            } else if (entity.type === 'relation' && entity.tags.type === 'multipolygon') {
                return _map(entity.members, function(member) {
                    if (context.hasEntity(member.id)) {
                        var entity = context.entity(member.id);
                        if (entity.type === 'way') {
                            return entity;
                        }
                    }
                    return [];
                });
            }
            return [];
        }));
        for (var i = 0; i < waysToCheck.length; i++) {
            var crosses = findCrossingsByWay(waysToCheck[i], graph, tree, edgePairsVisited);
            for (var j = 0; j < crosses.length; j++) {
                var crossing = crosses[j];

                // use the entities with the tags that define the feature type
                var entities = crossing.ways.sort(function(entity1, entity2) {
                    var type1 = getFeatureTypeForCrossingCheck(entity1, graph);
                    var type2 = getFeatureTypeForCrossingCheck(entity2, graph);
                    if (type1 === type2) {
                        return utilDisplayLabel(entity1, context) > utilDisplayLabel(entity2, context);
                    } else if (type1 === 'water') {
                        return true;
                    } else if (type2 === 'water') {
                        return false;
                    }
                    return type1 < type2;
                });
                entities = _map(entities, function(way) {
                    return getFeatureWithFeatureTypeTagsForWay(way, graph);
                });

                var crossingTypeID = crossing.featureTypes.sort().join('-');

                var messageDict = {
                    feature: utilDisplayLabel(entities[0], context),
                    feature2: utilDisplayLabel(entities[1], context)
                };

                issues.push(new validationIssue({
                    type: ValidationIssueType.crossing_ways,
                    severity: ValidationIssueSeverity.warning,
                    message: t('issues.crossing_ways.message', messageDict),
                    tooltip: t('issues.crossing_ways.'+crossingTypeID+'.tip'),
                    entities: entities,
                    info: {'ways': crossing.ways},
                    coordinates: crossing.cross_point,
                    fixes: [
                        new validationIssueFix({
                            title: t('issues.fix.add_connection_vertex.title'),
                            action: function() {
                                var loc = this.issue.coordinates;
                                var ways = this.issue.info.ways;

                                context.perform(
                                    function actionConnectCrossingWays(graph) {

                                        var node = osmNode();
                                        graph = graph.replace(node);

                                        var way0 = ways[0];
                                        var choice0 = geoChooseEdge(context.childNodes(way0), loc, context.projection);
                                        var edge0 = [way0.nodes[choice0.index - 1], way0.nodes[choice0.index]];
                                        graph = actionAddMidpoint({loc: choice0.loc, edge: edge0}, node)(graph);

                                        var way1 = ways[1];
                                        var choice1 = geoChooseEdge(context.childNodes(way1), loc, context.projection);
                                        var edge1 = [way1.nodes[choice1.index - 1], way1.nodes[choice1.index]];
                                        graph = actionAddMidpoint({loc: choice1.loc, edge: edge1}, node)(graph);

                                        return graph;
                                    },
                                    t('issues.fix.add_connection_vertex.undo_redo')
                                );
                            }
                        })
                    ]
                }));
            }
        }

        return issues;
    };

    return validation;
}
<commit_msg>Update crossing_ways fix to not use the context within the action<commit_after>import _clone from 'lodash-es/clone';
import _map from 'lodash-es/map';
import _flattenDeep from 'lodash-es/flatten';
import { geoExtent, geoLineIntersection } from '../geo';
import { set as d3_set } from 'd3-collection';
import { utilDisplayLabel } from '../util';
import { t } from '../util/locale';
import {
    ValidationIssueType,
    ValidationIssueSeverity,
    validationIssue,
    validationIssueFix
} from './validation_issue';
import { osmNode } from '../osm';
import { actionAddMidpoint } from '../actions';
import { geoChooseEdge } from '../geo';

export function validationHighwayCrossingOtherWays(context) {
    // Check if the edge going from n1 to n2 crosses (without a connection node)
    // any edge on way. Return the corss point if so.
    function findEdgeToWayCrossCoords(n1, n2, way, graph, edgePairsVisited) {
        var crossCoords = [];
        for (var j = 0; j < way.nodes.length - 1; j++) {
            var nidA = way.nodes[j],
                nidB = way.nodes[j + 1];
            if (nidA === n1.id || nidA === n2.id ||
                nidB === n1.id || nidB === n2.id) {
                // n1 or n2 is a connection node; skip
                continue;
            }

            var edgePair = edgePairString(n1.id, n2.id, nidA, nidB);
            if (edgePairsVisited.has(edgePair)) continue;
            edgePairsVisited.add(edgePair);

            var nA = graph.entity(nidA),
                nB = graph.entity(nidB),
                point = geoLineIntersection([n1.loc, n2.loc], [nA.loc, nB.loc]);
            if (point) crossCoords.push(point);
        }
        return crossCoords;
    }

    // n1 and n2 from one edge, nA and nB from the other edge
    function edgePairString(n1, n2, nA, nB) {
        return n1 > nA ? n1 + n2 + nA + nB : nA + nB + n1 + n2;
    }

    // returns the way or its parent relation, whichever has a useful feature type
    function getFeatureWithFeatureTypeTagsForWay(way, graph) {
        if (getFeatureTypeForTags(way.tags) === null) {
            // if the way doesn't match a feature type, check is parent relations
            var parentRels = graph.parentRelations(way);
            for (var i = 0; i < parentRels.length; i++) {
                var rel = parentRels[i];
                if (getFeatureTypeForTags(rel.tags) !== null) {
                    return rel;
                }
            }
        }
        return way;
    }

    function hasTag(tags, key) {
        return tags[key] !== undefined && tags[key] !== 'no';
    }

    function getFeatureTypeForCrossingCheck(way, graph) {
        var tags = getFeatureWithFeatureTypeTagsForWay(way, graph).tags;
        return getFeatureTypeForTags(tags);
    }

    function getFeatureTypeForTags(tags) {
        if (hasTag(tags, 'highway')) return 'highway';
        if (hasTag(tags, 'building')) return 'building';
        if (hasTag(tags, 'railway')) return 'railway';
        if (hasTag(tags, 'waterway') || tags.natural === 'water') return 'water';

        return null;
    }

    function extendTagsByInferredLayer(tags, way) {
        if (!hasTag(tags, 'layer')) {
            tags.layer = way.layer().toString();
        }
        return tags;
    }

    function isLegitCrossing(way1, featureType1, way2, featureType2, graph) {
        var tags1 = _clone(getFeatureWithFeatureTypeTagsForWay(way1, graph).tags),
            tags2 = _clone(getFeatureWithFeatureTypeTagsForWay(way2, graph).tags);
        tags1 = extendTagsByInferredLayer(tags1, way1);
        tags2 = extendTagsByInferredLayer(tags2, way2);

        // For better readability, not chaining all the true conditions into one if statement.
        if ((featureType1 === 'highway' && featureType2 === 'highway') ||
            (featureType1 === 'highway' && featureType2 === 'railway') ||
            (featureType1 === 'railway' && featureType2 === 'railway')) {
            // Legit cases:
            // (1) they're on different layers
            // (2) only one of the two ways is on a bridge
            // (3) only one of the two ways is in a tunnel
            if (tags1.layer !== tags2.layer) return true;
            if (hasTag(tags1, 'bridge') && !hasTag(tags2, 'bridge')) return true;
            if (!hasTag(tags1, 'bridge') && hasTag(tags2, 'bridge')) return true;
            if (hasTag(tags1, 'tunnel') && !hasTag(tags2, 'tunnel')) return true;
            if (!hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel')) return true;
        }
        if ((featureType1 === 'highway' && featureType2 === 'water') ||
            (featureType1 === 'railway' && featureType2 === 'water')) {
            // Legit cases:
            // (1) highway/railway is on a bridge
            // (2) only one of the two ways is in a tunnel
            // (3) both are in tunnels but on different layers
            if (hasTag(tags1, 'bridge')) return true;
            if (hasTag(tags1, 'tunnel') && !hasTag(tags2, 'tunnel')) return true;
            if (!hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel')) return true;
            if (hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel') && tags1.layer !== tags2.layer) return true;
        }
        if ((featureType1 === 'highway' && featureType2 === 'building') ||
            (featureType1 === 'railway' && featureType2 === 'building')) {
            // Legit cases:
            // (1) highway/railway has a bridge or tunnel tag
            // (2) highway/railway has a covered tag
            if (hasTag(tags1, 'bridge') || hasTag(tags1, 'tunnel') || hasTag(tags1, 'covered')) return true;
        }
        if (featureType1 === 'water' && featureType2 === 'water') {
            // Legit cases:
            // (1) only one of the water is in a tunnel
            // (2) both are in tunnels but on differnt layers
            if (hasTag(tags1, 'tunnel') && !hasTag(tags2, 'tunnel')) return true;
            if (!hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel')) return true;
            if (hasTag(tags1, 'tunnel') && hasTag(tags2, 'tunnel') && tags1.layer !== tags2.layer) return true;
        }
        if (featureType1 === 'water' && featureType2 === 'building') {
            // Legit cases:
            // (1) water is in a tunnel
            // (2) water has a covered tag
            if (hasTag(tags1, 'tunnel') || hasTag(tags1, 'covered')) return true;
        }
        if (featureType1 === 'building' && featureType2 === 'building') {
            // Legit case: they're on different layers
            if (tags1.layer !== tags2.layer) return true;
        }
        return false;
    }

    function findCrossingsByWay(entity, graph, tree, edgePairsVisited) {
        var edgeCrossInfos = [];
        if (entity.type !== 'way') return edgeCrossInfos;

        var entFeatureType = getFeatureTypeForCrossingCheck(entity, graph);
        if (entFeatureType === null) return edgeCrossInfos;

        for (var i = 0; i < entity.nodes.length - 1; i++) {
            var nid1 = entity.nodes[i],
                nid2 = entity.nodes[i + 1],
                n1 = graph.entity(nid1),
                n2 = graph.entity(nid2),
                extent = geoExtent([
                    [
                        Math.min(n1.loc[0], n2.loc[0]),
                        Math.min(n1.loc[1], n2.loc[1])
                    ],
                    [
                        Math.max(n1.loc[0], n2.loc[0]),
                        Math.max(n1.loc[1], n2.loc[1])
                    ]
                ]),
                intersected = tree.intersects(extent, graph);
            for (var j = 0; j < intersected.length; j++) {
                if (intersected[j].type !== 'way') continue;

                // only check crossing highway, waterway, building, and railway
                var way = intersected[j],
                    wayFeatureType = getFeatureTypeForCrossingCheck(way, graph);
                if (wayFeatureType === null ||
                    isLegitCrossing(entity, entFeatureType, way, wayFeatureType, graph) ||
                    isLegitCrossing(way, wayFeatureType, entity, entFeatureType, graph)) {
                    continue;
                }

                var crossCoords = findEdgeToWayCrossCoords(n1, n2, way, graph, edgePairsVisited);
                for (var k = 0; k < crossCoords.length; k++) {
                    edgeCrossInfos.push({
                        ways: [entity, way],
                        featureTypes: [entFeatureType, wayFeatureType],
                        cross_point: crossCoords[k],
                    });
                }
            }
        }
        return edgeCrossInfos;
    }

    var validation = function(entitiesToCheck, graph, tree) {
        // create one issue per crossing point
        var edgePairsVisited = d3_set(),
            issues = [];
        var waysToCheck = _flattenDeep(_map(entitiesToCheck, function(entity) {
            if (!getFeatureTypeForTags(entity.tags)) {
                return [];
            }
            if (entity.type === 'way') {
                return entity;
            } else if (entity.type === 'relation' && entity.tags.type === 'multipolygon') {
                return _map(entity.members, function(member) {
                    if (context.hasEntity(member.id)) {
                        var entity = context.entity(member.id);
                        if (entity.type === 'way') {
                            return entity;
                        }
                    }
                    return [];
                });
            }
            return [];
        }));
        for (var i = 0; i < waysToCheck.length; i++) {
            var crosses = findCrossingsByWay(waysToCheck[i], graph, tree, edgePairsVisited);
            for (var j = 0; j < crosses.length; j++) {
                var crossing = crosses[j];

                // use the entities with the tags that define the feature type
                var entities = crossing.ways.sort(function(entity1, entity2) {
                    var type1 = getFeatureTypeForCrossingCheck(entity1, graph);
                    var type2 = getFeatureTypeForCrossingCheck(entity2, graph);
                    if (type1 === type2) {
                        return utilDisplayLabel(entity1, context) > utilDisplayLabel(entity2, context);
                    } else if (type1 === 'water') {
                        return true;
                    } else if (type2 === 'water') {
                        return false;
                    }
                    return type1 < type2;
                });
                entities = _map(entities, function(way) {
                    return getFeatureWithFeatureTypeTagsForWay(way, graph);
                });

                var crossingTypeID = crossing.featureTypes.sort().join('-');

                var messageDict = {
                    feature: utilDisplayLabel(entities[0], context),
                    feature2: utilDisplayLabel(entities[1], context)
                };

                issues.push(new validationIssue({
                    type: ValidationIssueType.crossing_ways,
                    severity: ValidationIssueSeverity.warning,
                    message: t('issues.crossing_ways.message', messageDict),
                    tooltip: t('issues.crossing_ways.'+crossingTypeID+'.tip'),
                    entities: entities,
                    info: {'ways': crossing.ways},
                    coordinates: crossing.cross_point,
                    fixes: [
                        new validationIssueFix({
                            title: t('issues.fix.add_connection_vertex.title'),
                            action: function() {
                                var loc = this.issue.coordinates;
                                var ways = this.issue.info.ways;

                                context.perform(
                                    function actionConnectCrossingWays(graph) {

                                        var node = osmNode();
                                        graph = graph.replace(node);

                                        var way0 = graph.entity(ways[0].id);
                                        var choice0 = geoChooseEdge(graph.childNodes(way0), loc, context.projection);
                                        var edge0 = [way0.nodes[choice0.index - 1], way0.nodes[choice0.index]];
                                        graph = actionAddMidpoint({loc: choice0.loc, edge: edge0}, node)(graph);

                                        var way1 = graph.entity(ways[1].id);
                                        var choice1 = geoChooseEdge(graph.childNodes(way1), loc, context.projection);
                                        var edge1 = [way1.nodes[choice1.index - 1], way1.nodes[choice1.index]];
                                        graph = actionAddMidpoint({loc: choice1.loc, edge: edge1}, node)(graph);

                                        return graph;
                                    },
                                    t('issues.fix.add_connection_vertex.undo_redo')
                                );
                            }
                        })
                    ]
                }));
            }
        }

        return issues;
    };

    return validation;
}
<|endoftext|>


<commit_before>// @flow

import invariant from 'invariant';
import * as React from 'react';
import { Text } from 'react-native';

import { getMessageTitle } from 'lib/shared/message-utils';
import { threadIsGroupChat } from 'lib/shared/thread-utils';
import { stringForUser } from 'lib/shared/user-utils';
import {
  type MessageInfo,
  messageTypes,
  type ComposableMessageInfo,
  type RobotextMessageInfo,
} from 'lib/types/message-types';
import { type ThreadInfo } from 'lib/types/thread-types';
import { connect } from 'lib/utils/redux-utils';

import { SingleLine } from '../components/single-line.react';
import { getDefaultTextMessageRules } from '../markdown/rules.react';
import type { AppState } from '../redux/redux-setup';
import { styleSelector } from '../themes/colors';

type Props = {|
  +messageInfo: MessageInfo,
  +threadInfo: ThreadInfo,
  // Redux state
  +styles: typeof styles,
|};
class MessagePreview extends React.PureComponent<Props> {
  render() {
    const messageInfo: ComposableMessageInfo | RobotextMessageInfo =
      this.props.messageInfo.type === messageTypes.SIDEBAR_SOURCE
        ? this.props.messageInfo.sourceMessage
        : this.props.messageInfo;
    const unreadStyle = this.props.threadInfo.currentUser.unread
      ? this.props.styles.unread
      : null;
    const messageTitle = getMessageTitle(
      messageInfo,
      this.props.threadInfo,
      getDefaultTextMessageRules().simpleMarkdownRules,
    );
    if (messageInfo.type === messageTypes.TEXT) {
      let usernameText = null;
      if (
        threadIsGroupChat(this.props.threadInfo) ||
        this.props.threadInfo.name !== '' ||
        messageInfo.creator.isViewer
      ) {
        const userString = stringForUser(messageInfo.creator);
        const username = `${userString}: `;
        usernameText = (
          <Text style={[this.props.styles.username, unreadStyle]}>
            {username}
          </Text>
        );
      }
      return (
        <Text
          style={[this.props.styles.lastMessage, unreadStyle]}
          numberOfLines={1}
        >
          {usernameText}
          {messageTitle}
        </Text>
      );
    } else {
      invariant(
        messageInfo.type !== messageTypes.SIDEBAR_SOURCE,
        'Sidebar source should not be handled here',
      );
      return (
        <SingleLine
          style={[
            this.props.styles.lastMessage,
            this.props.styles.preview,
            unreadStyle,
          ]}
        >
          {messageTitle}
        </SingleLine>
      );
    }
  }
}

const styles = {
  lastMessage: {
    color: 'listForegroundTertiaryLabel',
    flex: 1,
    fontSize: 16,
    paddingLeft: 10,
  },
  preview: {
    color: 'listForegroundQuaternaryLabel',
  },
  unread: {
    color: 'listForegroundLabel',
  },
  username: {
    color: 'listForegroundQuaternaryLabel',
  },
};
const stylesSelector = styleSelector(styles);

export default connect((state: AppState) => ({
  styles: stylesSelector(state),
}))(MessagePreview);
<commit_msg>[native] Use hook instead of connect function and HOC in MessagePreview<commit_after>// @flow

import invariant from 'invariant';
import * as React from 'react';
import { Text } from 'react-native';

import { getMessageTitle } from 'lib/shared/message-utils';
import { threadIsGroupChat } from 'lib/shared/thread-utils';
import { stringForUser } from 'lib/shared/user-utils';
import {
  type MessageInfo,
  messageTypes,
  type ComposableMessageInfo,
  type RobotextMessageInfo,
} from 'lib/types/message-types';
import { type ThreadInfo } from 'lib/types/thread-types';

import { SingleLine } from '../components/single-line.react';
import { getDefaultTextMessageRules } from '../markdown/rules.react';
import { useStyles } from '../themes/colors';

type Props = {|
  +messageInfo: MessageInfo,
  +threadInfo: ThreadInfo,
|};
function MessagePreview(props: Props) {
  const styles = useStyles(unboundStyles);
  const messageInfo: ComposableMessageInfo | RobotextMessageInfo =
    props.messageInfo.type === messageTypes.SIDEBAR_SOURCE
      ? props.messageInfo.sourceMessage
      : props.messageInfo;
  const unreadStyle = props.threadInfo.currentUser.unread
    ? styles.unread
    : null;
  const messageTitle = getMessageTitle(
    messageInfo,
    props.threadInfo,
    getDefaultTextMessageRules().simpleMarkdownRules,
  );
  if (messageInfo.type === messageTypes.TEXT) {
    let usernameText = null;
    if (
      threadIsGroupChat(props.threadInfo) ||
      props.threadInfo.name !== '' ||
      messageInfo.creator.isViewer
    ) {
      const userString = stringForUser(messageInfo.creator);
      const username = `${userString}: `;
      usernameText = (
        <Text style={[styles.username, unreadStyle]}>{username}</Text>
      );
    }
    return (
      <Text style={[styles.lastMessage, unreadStyle]} numberOfLines={1}>
        {usernameText}
        {messageTitle}
      </Text>
    );
  } else {
    invariant(
      messageInfo.type !== messageTypes.SIDEBAR_SOURCE,
      'Sidebar source should not be handled here',
    );
    return (
      <SingleLine style={[styles.lastMessage, styles.preview, unreadStyle]}>
        {messageTitle}
      </SingleLine>
    );
  }
}

const unboundStyles = {
  lastMessage: {
    color: 'listForegroundTertiaryLabel',
    flex: 1,
    fontSize: 16,
    paddingLeft: 10,
  },
  preview: {
    color: 'listForegroundQuaternaryLabel',
  },
  unread: {
    color: 'listForegroundLabel',
  },
  username: {
    color: 'listForegroundQuaternaryLabel',
  },
};

export default MessagePreview;
<|endoftext|>


<commit_before>'use strict';

angular.module('users')
    .factory('Authentication', ['$rootScope', '$http', '$q', 'Identity',
        function($rootScope, $http, $q, Identity) {
            var baseApiUrl = 'http://localhost:3310';

            function signup (user) {
                var deferred = $q.defer();

                var req = {
                    method: 'POST',
                    url: baseApiUrl + '/auth/signup',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    transformRequest: function(obj) {
                        var str = [];

                        for(var p in obj) {
                            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                        }

                        return str.join("&");
                    },
                    data: user
                };

                $http(req)
                    .success(function (data, status, headers, config) {
                        console.log('Success: ', data);

                        Identity.setCurrentUser(data.user);
                        $rootScope.$broadcast('login');

                        deferred.resolve(true);
                    })
                    .error(function (data, status, headers, config) {
                        // Handle error correctly
                        console.error('Error: ', data.message);

                        deferred.reject();
                    });

                return deferred.promise;
            }

            function login (user){
                var deferred = $q.defer();

                var req = {
                    method: 'POST',
                    url: baseApiUrl + '/auth/login',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    transformRequest: function(obj) {
                        var str = [];
                        for(var p in obj)
                            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                        return str.join("&");
                    },
                    data: user
                };

                $http(req)
                    .success(function (data, status, headers, config) {
                        Identity.setCurrentUser(data.user);
                        $rootScope.$broadcast('login');

                        deferred.resolve(true);
                    })
                    .error(function (data, status, headers, config) {
                        deferred.reject(data.message);
                    });

                return deferred.promise;
            }

            function logout () {
                var deferred = $q.defer();

                $http.get(baseApiUrl + '/auth/logout')
                    .success(function() {
                        Identity.setCurrentUser(undefined);
                        $rootScope.$broadcast('logout');

                        deferred.resolve();
                    });

                return deferred.promise;
            }

            return {
                signup: signup,
                login: login,
                logout: logout
            };
        }
    ]);<commit_msg>Fix for not using baseUrl.<commit_after>'use strict';

angular.module('users')
    .factory('Authentication', ['$rootScope', '$http', '$q', 'Identity',
        function($rootScope, $http, $q, Identity) {

            function signup (user) {
                var deferred = $q.defer();

                var req = {
                    method: 'POST',
                    url: '/auth/signup',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    transformRequest: function(obj) {
                        var str = [];

                        for(var p in obj) {
                            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                        }

                        return str.join("&");
                    },
                    data: user
                };

                $http(req)
                    .success(function (data, status, headers, config) {
                        console.log('Success: ', data);

                        Identity.setCurrentUser(data.user);
                        $rootScope.$broadcast('login');

                        deferred.resolve(true);
                    })
                    .error(function (data, status, headers, config) {
                        // Handle error correctly
                        console.error('Error: ', data.message);

                        deferred.reject();
                    });

                return deferred.promise;
            }

            function login (user){
                var deferred = $q.defer();

                var req = {
                    method: 'POST',
                    url: '/auth/login',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    transformRequest: function(obj) {
                        var str = [];
                        for(var p in obj)
                            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
                        return str.join("&");
                    },
                    data: user
                };

                $http(req)
                    .success(function (data, status, headers, config) {
                        Identity.setCurrentUser(data.user);
                        $rootScope.$broadcast('login');

                        deferred.resolve(true);
                    })
                    .error(function (data, status, headers, config) {
                        deferred.reject(data.message);
                    });

                return deferred.promise;
            }

            function logout () {
                var deferred = $q.defer();

                $http.get('/auth/logout')
                    .success(function() {
                        Identity.setCurrentUser(undefined);
                        $rootScope.$broadcast('logout');

                        deferred.resolve();
                    });

                return deferred.promise;
            }

            return {
                signup: signup,
                login: login,
                logout: logout
            };
        }
    ]);<|endoftext|>


<commit_before>var _ = require("lodash");
var $ = require("jquery");

var _stories = {};

/**
 * 获取目前已加载的所有日报内容的缓存（以 Id 进行检索，无序，请勿用 index 检索）。
 */
function getStories()
{
    return _stories;
}

var _today = null;

/**
 * 获取知乎日报当前日期，例如"20170727"。
 */
function getToday()
{
    return _today;
}

/**
 * 获取最新热门日报的索引。
 */
function getTopStoryIndexes(callback)
{
    $.get("/api/4/news/top", function (data)
    {
        if (!_.isEqual(_today, data.date))
        {
            _today = data.date;
        }
        callback(data);
    });
}

/**
 * 获取指定日期的日报的索引。
 * @param String p_date 指定的日期。如果小于 20130519，返回值为 {}。
 */
function getStoryIndexes(callback, p_date)
{
    if (_.isEmpty(_today))
    {
        $.get("/api/4/news/before", function (data)
        {
            if (!_.isEqual(_today, data.date))
            {
                _today = data.date;
            }
            callback(data);
        });
    }
    else
    {
        $.get("/api/4/news/before/" + p_date, callback);
    }
}

/**
 * 获取指定唯一标识的日报。
 * @param String p_id 指定的唯一标识。
 */
function getStory(callback, p_id)
{
    $.get("/api/4/news/" + p_id, function (data)
    {
        _stories[p_id] = data;
        callback(data);
    });
}

module.exports.getTopStoryIndexes = getTopStoryIndexes;
module.exports.getStoryIndexes = getStoryIndexes;
module.exports.getStory = getStory;

module.exports.getStories = getStories;
module.exports.getToday = getToday;<commit_msg>fix a bug of getStoryIndexes() & remove _today<commit_after>var _ = require("lodash");
var $ = require("jquery");

var _stories = {};

/**
 * 获取目前已从服务端获取到的所有日报内容的缓存（以日报 id 进行检索，无序，请勿用 index 检索）。
 */
function getFetchedStories()
{
    return _stories;
}

/**
 * 获取最新热门日报的索引。
 */
function getTopStoryIndexes(callback)
{
    $.get("/api/4/news/top", function (p_data)
    {
        callback(p_data);
    });
}

/**
 * 获取指定日期的日报的索引。
 * @param String p_date 指定的日期。如果未指定，则返回最新日报的索引；如果小于 20130519，则返回 {}。
 */
function getStoryIndexes(callback, p_date)
{
    if (_.isEmpty(p_date))
    {
        $.get("/api/4/news/before", function (p_data)
        {
            callback(p_data);
        });
    }
    else
    {
        $.get("/api/4/news/before/" + p_date, callback);
    }
}

/**
 * 获取指定唯一标识的日报。
 * @param String p_id 指定的唯一标识。
 */
function getStory(callback, p_id)
{
    $.get("/api/4/news/" + p_id, function (p_data)
    {
        _stories[p_id] = p_data;
        callback(p_data);
    });
}

module.exports.getTopStoryIndexes = getTopStoryIndexes;
module.exports.getStoryIndexes = getStoryIndexes;
module.exports.getStory = getStory;

module.exports.getFetchedStories = getFetchedStories;<|endoftext|>


<commit_before>/**
 * Takes a map and a set of streets, and visualizes them as segments on the map.
 * @param map Map on which the streets are rendered.
 * @param params Object that includes properties that can change the process of street rendering.
 * @param params.labelPopup {boolean} whether to include a validation popup on labels on the map.
 * @param params.auditedStreetColor {string} color to use for audited streets on the map.
 * @param params.unauditedStreetColor {string} optional color to use for unaudited streets on the map.
 * @param streetData Data about streets to visualize.
*/
function InitializeStreets(map, params, streetData) {
    let streetLayer;
    let distanceAudited = 0;  // Distance audited in km.
    let hasUnauditedStreets = params.unauditedStreetColor != null;

    function onEachStreetFeature(feature, layer) {
        if (feature.properties && feature.properties.type) {
            layer.bindPopup(feature.properties.type);
        }
        layer.on({
            'add': function () {
                layer.bringToBack()
            }
        })
    }
    // Render street segments.
    streetLayer = L.geoJson(streetData, {
        pointToLayer: L.mapbox.marker.style,
        style: function (feature) {
            let style = {
                color: !hasUnauditedStreets || feature.properties.audited ? params.auditedStreetColor : params.unauditedStreetColor,
                opacity: 0.75,
                'stroke-width': 3,
                weight: 3
            };
            return style;
        },
        onEachFeature: onEachStreetFeature
    })
        .addTo(map);
    if (params.useTotalAuditedDistance) {
        // Calculate total distance audited in km/miles depending on the measurement system used in the user's country.
        for (let i = streetData.features.length - 1; i >= 0; i--) {
            if (!hasUnauditedStreets || streetData.features[i].properties.audited) {
                distanceAudited += turf.length(streetData.features[i], {units: i18next.t('common:unit-distance')});
            }
        }
        document.getElementById(params.progressElement).innerHTML = distanceAudited.toPrecision(2) + ' ' + i18next.t('common:unit-distance-abbreviation');
        // Get total reward if a turker.
        if (params.userRole === 'Turker') {
            $.ajax({
                async: true,
                url: '/rewardEarned',
                type: 'get',
                success: function(rewardData) {
                    document.getElementById('td-total-reward-earned').innerHTML = '$' + rewardData.reward_earned.toFixed(2);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console.log(thrownError);
                }
            })
        }
    }
    return streetLayer;
}
<commit_msg>LabelMap streets now change width on hover<commit_after>/**
 * Takes a map and a set of streets, and visualizes them as segments on the map.
 * @param map Map on which the streets are rendered.
 * @param params Object that includes properties that can change the process of street rendering.
 * @param params.labelPopup {boolean} whether to include a validation popup on labels on the map.
 * @param params.auditedStreetColor {string} color to use for audited streets on the map.
 * @param params.unauditedStreetColor {string} optional color to use for unaudited streets on the map.
 * @param streetData Data about streets to visualize.
*/
function InitializeStreets(map, params, streetData) {
    let streetLayer;
    let distanceAudited = 0;  // Distance audited in km.
    let hasUnauditedStreets = params.unauditedStreetColor != null;

    function onEachStreetFeature(feature, layer) {
        layer.on({
            'mouseover': function () {
                this.setStyle({ weight: 5 });
                },
            'mouseout': function() {
                this.setStyle({ weight: 3 });
            }
        });
    }
    // Render street segments.
    streetLayer = L.geoJson(streetData, {
        pointToLayer: L.mapbox.marker.style,
        style: function (feature) {
            let style = {
                color: !hasUnauditedStreets || feature.properties.audited ? params.auditedStreetColor : params.unauditedStreetColor,
                opacity: 0.75,
                'stroke-width': 3,
                weight: 3
            };
            return style;
        },
        onEachFeature: onEachStreetFeature
    })
        .addTo(map);
    if (params.useTotalAuditedDistance) {
        // Calculate total distance audited in km/miles depending on the measurement system used in the user's country.
        for (let i = streetData.features.length - 1; i >= 0; i--) {
            if (!hasUnauditedStreets || streetData.features[i].properties.audited) {
                distanceAudited += turf.length(streetData.features[i], {units: i18next.t('common:unit-distance')});
            }
        }
        document.getElementById(params.progressElement).innerHTML = distanceAudited.toPrecision(2) + ' ' + i18next.t('common:unit-distance-abbreviation');
        // Get total reward if a turker.
        if (params.userRole === 'Turker') {
            $.ajax({
                async: true,
                url: '/rewardEarned',
                type: 'get',
                success: function(rewardData) {
                    document.getElementById('td-total-reward-earned').innerHTML = '$' + rewardData.reward_earned.toFixed(2);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    console.log(thrownError);
                }
            })
        }
    }
    return streetLayer;
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/

CKEDITOR.themes.add('default',(function(){return{build:function(a,b){var c=a.name,d=a.element,e=a.elementMode;if(!d||e==CKEDITOR.ELEMENT_MODE_NONE)return;if(e==CKEDITOR.ELEMENT_MODE_REPLACE)d.hide();var f=a.fire('themeSpace',{space:'top',html:''}).html,g=a.fire('themeSpace',{space:'contents',html:''}).html,h=a.fireOnce('themeSpace',{space:'bottom',html:''}).html,i=g&&a.config.height,j=a.config.tabIndex||a.element.getAttribute('tabindex')||0;if(!g)i='auto';else if(!isNaN(i))i+='px';var k='',l=a.config.width;if(l){if(!isNaN(l))l+='px';k+='width: '+l+';';}var m=CKEDITOR.dom.element.createFromHtml([''+'

',f,'

',g,'

',h,'

'].join(''));m.getChild([0,0,0,0,0]).unselectable();m.getChild([0,0,0,0,2]).unselectable();if(e==CKEDITOR.ELEMENT_MODE_REPLACE)m.insertAfter(d);else d.append(m);a.container=m;a.fireOnce('themeLoaded');a.fireOnce('uiReady');},buildDialog:function(a){var b=CKEDITOR.tools.getNextNumber(),c=CKEDITOR.dom.element.createFromHtml(['

X

',CKEDITOR.env.ie?'':'','
'].join('').replace(/#/g,'_'+b).replace(/%/g,'cke_dialog_')),d=c.getChild([0,0]);
d.getChild(0).unselectable();d.getChild(1).unselectable();return{element:c,parts:{dialog:c.getChild(0),title:d.getChild(0),close:d.getChild(1),tabs:d.getChild(2),contents:d.getChild(3),footer:d.getChild(4)}};},destroy:function(a){var b=a.container;if(CKEDITOR.env.ie){b.setStyle('display','none');var c=document.body.createTextRange();c.moveToElementText(b.$);try{c.select();}catch(d){}}if(b)b.remove();if(a.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE){a.element.show();delete a.element;}}};})());CKEDITOR.editor.prototype.getThemeSpace=function(a){var b='cke_'+a,c=this._[b]||(this._[b]=CKEDITOR.document.getById(b+'_'+this.name));return c;};CKEDITOR.editor.prototype.resize=function(a,b,c,d){var e=/^\d+$/;if(e.test(a))a+='px';var f=CKEDITOR.document.getById('cke_contents_'+this.name),g=d?f.getAscendant('table').getParent():f.getAscendant('table').getParent().getParent().getParent();CKEDITOR.env.webkit&&g.setStyle('display','none');g.setStyle('width',a);if(CKEDITOR.env.webkit){g.$.offsetWidth;g.setStyle('display','');}var h=c?0:(g.$.offsetHeight||0)-(f.$.clientHeight||0);f.setStyle('height',Math.max(b-h,0)+'px');this.fire('resize');};CKEDITOR.editor.prototype.getResizable=function(){return this.container.getChild([0,0]);};
<commit_msg>Update cKEditor second take<commit_after>/*
Copyright (c) 2003-2011, CKSource - Frederico Knabben. All rights reserved.
For licensing, see LICENSE.html or http://ckeditor.com/license
*/

CKEDITOR.themes.add('default',(function(){var a={};function b(c,d){var e,f;f=c.config.sharedSpaces;f=f&&f[d];f=f&&CKEDITOR.document.getById(f);if(f){var g=''+''+''+''+''+'
'+'
',h=f.append(CKEDITOR.dom.element.createFromHtml(g,f.getDocument()));if(f.getCustomData('cke_hasshared'))h.hide();else f.setCustomData('cke_hasshared',1);e=h.getChild([0,0,0,0]);!c.sharedSpaces&&(c.sharedSpaces={});c.sharedSpaces[d]=e;c.on('focus',function(){for(var i=0,j,k=f.getChildren();j=k.getItem(i);i++){if(j.type==CKEDITOR.NODE_ELEMENT&&!j.equals(h)&&j.hasClass('cke_shared'))j.hide();}h.show();});c.on('destroy',function(){h.remove();});}return e;};return{build:function(c,d){var e=c.name,f=c.element,g=c.elementMode;if(!f||g==CKEDITOR.ELEMENT_MODE_NONE)return;if(g==CKEDITOR.ELEMENT_MODE_REPLACE)f.hide();var h=c.fire('themeSpace',{space:'top',html:''}).html,i=c.fire('themeSpace',{space:'contents',html:''}).html,j=c.fireOnce('themeSpace',{space:'bottom',html:''}).html,k=i&&c.config.height,l=c.config.tabIndex||c.element.getAttribute('tabindex')||0;if(!i)k='auto';else if(!isNaN(k))k+='px';var m='',n=c.config.width;if(n){if(!isNaN(n))n+='px';m+='width: '+n+';';}var o=h&&b(c,'top'),p=b(c,'bottom');o&&(o.setHtml(h),h='');p&&(p.setHtml(j),j='');var q='';if(a[c.skinClass])q='';else a[c.skinClass]=1;var r=CKEDITOR.dom.element.createFromHtml([''+''+c.lang.editor+''+'

',h,'

',i,'

',j,'

'+q+''+''+''].join(''));
r.getChild([1,0,0,0,0]).unselectable();r.getChild([1,0,0,0,2]).unselectable();if(g==CKEDITOR.ELEMENT_MODE_REPLACE)r.insertAfter(f);else f.append(r);c.container=r;r.disableContextMenu();c.on('contentDirChanged',function(s){var t=(c.lang.dir!=s.data?'add':'remove')+'Class';r.getChild(1)[t]('cke_mixed_dir_content');var u=this.sharedSpaces&&this.sharedSpaces[this.config.toolbarLocation];u&&u.getParent().getParent()[t]('cke_mixed_dir_content');});c.fireOnce('themeLoaded');c.fireOnce('uiReady');},buildDialog:function(c){var d=CKEDITOR.tools.getNextNumber(),e=CKEDITOR.dom.element.createFromHtml(['

X'+'

'+'
'+'
'+'	'+'
'+'
'+'	'+'
'+'
'+'
'+'

'+'

'+'

'+'

'+'

'+'

'+'

'+'

'+'
'+'
',CKEDITOR.env.ie?'':'','
'].join('').replace(/#/g,'_'+d).replace(/%/g,'cke_dialog_')),f=e.getChild([0,0,0,0,0]),g=f.getChild(0),h=f.getChild(1);if(CKEDITOR.env.ie&&!CKEDITOR.env.ie6Compat){var i=CKEDITOR.env.isCustomDomain(),j='javascript:void(function(){'+encodeURIComponent('document.open();'+(i?'document.domain="'+document.domain+'";':'')+'document.close();')+'}())',k=CKEDITOR.dom.element.createFromHtml('');k.appendTo(f.getParent());}g.unselectable();h.unselectable();return{element:e,parts:{dialog:e.getChild(0),title:g,close:h,tabs:f.getChild(2),contents:f.getChild([3,0,0,0]),footer:f.getChild([3,0,1,0])}};
},destroy:function(c){var d=c.container,e=c.element;if(d){d.clearCustomData();d.remove();}if(e){e.clearCustomData();c.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE&&e.show();delete c.element;}}};})());CKEDITOR.editor.prototype.getThemeSpace=function(a){var b='cke_'+a,c=this._[b]||(this._[b]=CKEDITOR.document.getById(b+'_'+this.name));return c;};CKEDITOR.editor.prototype.resize=function(a,b,c,d){var j=this;var e=j.container,f=CKEDITOR.document.getById('cke_contents_'+j.name),g=CKEDITOR.env.webkit&&j.document&&j.document.getWindow().$.frameElement,h=d?e.getChild(1):e;h.setSize('width',a,true);g&&(g.style.width='1%');var i=c?0:(h.$.offsetHeight||0)-(f.$.clientHeight||0);f.setStyle('height',Math.max(b-i,0)+'px');g&&(g.style.width='100%');j.fire('resize');};CKEDITOR.editor.prototype.getResizable=function(a){return a?CKEDITOR.document.getById('cke_contents_'+this.name):this.container;};
<|endoftext|>


<commit_before>export default {
  translations: {

    'da': {
      'months': {
        'original': ['Januar', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø']
    },

    'en': {
      'months': {
        'original': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      },
      'days': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
    },

    'es': {
      'months': {
        'original': ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
        'abbr': ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic']
      },
      'days': ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sab']
    },

    'fi': {
      'months': {
        'original': ['tammikuu', 'helmikuu', 'maaliskuu', 'huhtikuu', 'toukokuu', 'kesäkuu', 'heinäkuu', 'elokuu', 'syyskuu', 'lokakuu', 'marraskuu', 'joulukuu'],
        'abbr': ['tammi', 'helmi', 'maalis', 'huhti', 'touko', 'kesä', 'heinä', 'elo', 'syys', 'loka', 'marras', 'joulu']
      },
      'days': ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la']
    },

    'fr': {
      'months': {
        'original': ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
        'abbr': ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Déc']
      },
      'days': ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam']
    },

    'hr': {
      'months': {
        'original': ['Siječanj', 'Veljača', 'Ožujak', 'Travanj', 'Svibanj', 'Lipanj', 'Srpanj', 'Kolovoz', 'Rujan', 'Listopad', 'Studeni', 'Prosinac'],
        'abbr': ['Sij', 'Velj', 'Ožu', 'Tra', 'Svi', 'Lip', 'Srp', 'Kol', 'Ruj', 'Lis', 'Stu', 'Pro']
      },
      'days': ['Ned', 'Pon', 'Uto', 'Sri', 'Čet', 'Pet', 'Sub']
    },

    'it': {
      'months': {
        'original': ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
        'abbr': ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic']
      },
      'days': ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab']
    },

    'lt': {
      'months': {
        'original': ['Sausis', 'Vasaris', 'Kovas', 'Balandis', 'Gegužė', 'Birželis', 'Liepa', 'Rugpjūtis', 'Rugsėjis', 'Spalis', 'Lapkritis', 'Gruodis'],
        'abbr': ['Sau', 'Vas', 'Kov', 'Bal', 'Geg', 'Bir', 'Lie', 'Rugp', 'Rugs', 'Spa', 'Lap', 'Gru']
      },
      'days': ['Sek', 'Pir', 'Ant', 'Tre', 'Ket', 'Pen', 'Šeš']
    },

    'nl': {
      'months': {
        'original': ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
        'abbr': ['jan', 'feb', 'maa', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec']
      },
      'days': ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za']
    },

    'de': {
      'months': {
        'original': ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
        'abbr': ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
      },
      'days': ['So.', 'Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.']
    },

    'pt-br': {
      'months': {
        'original': ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
        'abbr': ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
      },
      'days': ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab']
    },

    'vi': {
      'months': {
        'original': ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'],
        'abbr': ['T 01', 'T 02', 'T 03', 'T 04', 'T 05', 'T 06', 'T 07', 'T 08', 'T 09', 'T 10', 'T 11', 'T 12']
      },
      'days': ['CN', 'Thứ 2', 'Thứ 3', 'Thứ 4', 'Thứ 5', 'Thứ 6', 'Thứ 7']
    },

    'zh': {
      'months': {
        'original': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
        'abbr': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
      },
      'days': ['日', '一', '二', '三', '四', '五', '六']
    },

    'ja': {
      'months': {
        'original': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        'abbr': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
      },
      'days': ['日', '月', '火', '水', '木', '金', '土']
    },

    'he': {
      'months': {
        'original': ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'],
        'abbr': ['ינו', 'פבר', 'מרץ', 'אפר', 'מאי', 'יונ', 'יול', 'אוג', 'ספט', 'אוק', 'נוב', 'דצמ']
      },
      'days': ['א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ש']
    },

    'cs': {
      'months': {
        'original': ['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
        'abbr': ['led', 'úno', 'bře', 'dub', 'kvě', 'čer', 'čec', 'srp', 'zář', 'říj', 'lis', 'pro']
      },
      'days': ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so']
    },

    'ru': {
      'months': {
        'original': ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
        'abbr': ['Янв', 'Февр', 'Март', 'Апр', 'Май', 'Июнь', 'Июль', 'Авг', 'Сент', 'Окт', 'Нояб', 'Дек']
      },
      'days': ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
    },

    'bg': {
      'months': {
        'original': ['Януари', 'Февруари', 'Март', 'Април', 'Май', 'Юни', 'Юли', 'Август', 'Септември', 'Октомври', 'Ноември', 'Декември'],
        'abbr': ['Ян', 'Фев', 'Мар', 'Апр', 'Май', 'Юни', 'Юли', 'Авг', 'Сеп', 'Окт', 'Ное', 'Дек']
      },
      'days': ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
    },

    'sv': {
      'months': {
        'original': ['Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      },
      'days': ['Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör']
    },

    'th': {
      'months': {
        'original': ['มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'],
        'abbr': ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.']
      },
      'days': ['อา', 'จ', 'อ', 'พ', 'พฤ', 'ศ', 'ส']
    },

    'ro': {
      'months': {
        'original': ['Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie'],
        'abbr': ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sep', 'Oct', 'Noi', 'Dec']
      },
      'days': ['D', 'L', 'Ma', 'Mi', 'J', 'V', 'S']
    },

    'sl-si': {
      'months': {
        'original': ['Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Avg', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Ned', 'Pon', 'Tor', 'Sre', 'Čet', 'Pet', 'Sob']
    }

  }

}
<commit_msg>Polish translation<commit_after>export default {
  translations: {

    'da': {
      'months': {
        'original': ['Januar', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø']
    },

    'en': {
      'months': {
        'original': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      },
      'days': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
    },

    'es': {
      'months': {
        'original': ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
        'abbr': ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic']
      },
      'days': ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sab']
    },

    'fi': {
      'months': {
        'original': ['tammikuu', 'helmikuu', 'maaliskuu', 'huhtikuu', 'toukokuu', 'kesäkuu', 'heinäkuu', 'elokuu', 'syyskuu', 'lokakuu', 'marraskuu', 'joulukuu'],
        'abbr': ['tammi', 'helmi', 'maalis', 'huhti', 'touko', 'kesä', 'heinä', 'elo', 'syys', 'loka', 'marras', 'joulu']
      },
      'days': ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la']
    },

    'fr': {
      'months': {
        'original': ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
        'abbr': ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Juin', 'Juil', 'Août', 'Sep', 'Oct', 'Nov', 'Déc']
      },
      'days': ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam']
    },

    'hr': {
      'months': {
        'original': ['Siječanj', 'Veljača', 'Ožujak', 'Travanj', 'Svibanj', 'Lipanj', 'Srpanj', 'Kolovoz', 'Rujan', 'Listopad', 'Studeni', 'Prosinac'],
        'abbr': ['Sij', 'Velj', 'Ožu', 'Tra', 'Svi', 'Lip', 'Srp', 'Kol', 'Ruj', 'Lis', 'Stu', 'Pro']
      },
      'days': ['Ned', 'Pon', 'Uto', 'Sri', 'Čet', 'Pet', 'Sub']
    },

    'it': {
      'months': {
        'original': ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
        'abbr': ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic']
      },
      'days': ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab']
    },

    'lt': {
      'months': {
        'original': ['Sausis', 'Vasaris', 'Kovas', 'Balandis', 'Gegužė', 'Birželis', 'Liepa', 'Rugpjūtis', 'Rugsėjis', 'Spalis', 'Lapkritis', 'Gruodis'],
        'abbr': ['Sau', 'Vas', 'Kov', 'Bal', 'Geg', 'Bir', 'Lie', 'Rugp', 'Rugs', 'Spa', 'Lap', 'Gru']
      },
      'days': ['Sek', 'Pir', 'Ant', 'Tre', 'Ket', 'Pen', 'Šeš']
    },

    'nl': {
      'months': {
        'original': ['januari', 'februari', 'maart', 'april', 'mei', 'juni', 'juli', 'augustus', 'september', 'oktober', 'november', 'december'],
        'abbr': ['jan', 'feb', 'maa', 'apr', 'mei', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec']
      },
      'days': ['zo', 'ma', 'di', 'wo', 'do', 'vr', 'za']
    },

    'de': {
      'months': {
        'original': ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
        'abbr': ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
      },
      'days': ['So.', 'Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.']
    },

    'pt-br': {
      'months': {
        'original': ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
        'abbr': ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
      },
      'days': ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab']
    },

    'vi': {
      'months': {
        'original': ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'],
        'abbr': ['T 01', 'T 02', 'T 03', 'T 04', 'T 05', 'T 06', 'T 07', 'T 08', 'T 09', 'T 10', 'T 11', 'T 12']
      },
      'days': ['CN', 'Thứ 2', 'Thứ 3', 'Thứ 4', 'Thứ 5', 'Thứ 6', 'Thứ 7']
    },

    'zh': {
      'months': {
        'original': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
        'abbr': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
      },
      'days': ['日', '一', '二', '三', '四', '五', '六']
    },

    'ja': {
      'months': {
        'original': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        'abbr': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
      },
      'days': ['日', '月', '火', '水', '木', '金', '土']
    },

    'he': {
      'months': {
        'original': ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'],
        'abbr': ['ינו', 'פבר', 'מרץ', 'אפר', 'מאי', 'יונ', 'יול', 'אוג', 'ספט', 'אוק', 'נוב', 'דצמ']
      },
      'days': ['א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ש']
    },

    'cs': {
      'months': {
        'original': ['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
        'abbr': ['led', 'úno', 'bře', 'dub', 'kvě', 'čer', 'čec', 'srp', 'zář', 'říj', 'lis', 'pro']
      },
      'days': ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so']
    },

    'ru': {
      'months': {
        'original': ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
        'abbr': ['Янв', 'Февр', 'Март', 'Апр', 'Май', 'Июнь', 'Июль', 'Авг', 'Сент', 'Окт', 'Нояб', 'Дек']
      },
      'days': ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
    },

    'bg': {
      'months': {
        'original': ['Януари', 'Февруари', 'Март', 'Април', 'Май', 'Юни', 'Юли', 'Август', 'Септември', 'Октомври', 'Ноември', 'Декември'],
        'abbr': ['Ян', 'Фев', 'Мар', 'Апр', 'Май', 'Юни', 'Юли', 'Авг', 'Сеп', 'Окт', 'Ное', 'Дек']
      },
      'days': ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
    },

    'sv': {
      'months': {
        'original': ['Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      },
      'days': ['Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör']
    },

    'th': {
      'months': {
        'original': ['มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'],
        'abbr': ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.']
      },
      'days': ['อา', 'จ', 'อ', 'พ', 'พฤ', 'ศ', 'ส']
    },

    'ro': {
      'months': {
        'original': ['Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie'],
        'abbr': ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sep', 'Oct', 'Noi', 'Dec']
      },
      'days': ['D', 'L', 'Ma', 'Mi', 'J', 'V', 'S']
    },

    'sl-si': {
      'months': {
        'original': ['Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Avg', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Ned', 'Pon', 'Tor', 'Sre', 'Čet', 'Pet', 'Sob']
    },

    'pl': {
      'months': {
        'original': ['Styczeń', 'Luty', 'Marzec', 'Kwiecień', 'Maj', 'Czerwiec', 'Lipiec', 'Sierpień', 'Wrzesień', 'Październik', 'Listopad', 'Grudzień'],
        'abbr': ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru']
      },
      'days': ['Nd', 'Pn', 'Wt', 'Śr', 'Czw', 'Pt', 'Sob']
    }

  }

}
<|endoftext|>


<commit_before>export default {
  translations: {

    'da': {
      'months': {
        'original': ['Januar', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø']
    },

    'en': {
      'months': {
        'original': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      },
      'days': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
    },

    'es': {
      'months': {
        'original': ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
        'abbr': ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic']
      },
      'days': ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sab']
    },

    'fi': {
      'months': {
        'original': ['tammikuu', 'helmikuu', 'maaliskuu', 'huhtikuu', 'toukokuu', 'kesäkuu', 'heinäkuu', 'elokuu', 'syyskuu', 'lokakuu', 'marraskuu', 'joulukuu'],
        'abbr': ['tammi', 'helmi', 'maalis', 'huhti', 'touko', 'kesä', 'heinä', 'elo', 'syys', 'loka', 'marras', 'joulu']
      },
      'days': ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la']
    },

    'fr': {
      'months': {
        'original': ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
        'abbr': ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jui', 'Juil', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc']
      },
      'days': ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam']
    },

    'hr': {
      'months': {
        'original': ['Siječanj', 'Veljača', 'Ožujak', 'Travanj', 'Svibanj', 'Lipanj', 'Srpanj', 'Kolovoz', 'Rujan', 'Listopad', 'Studeni', 'Prosinac'],
        'abbr': ['Sij', 'Velj', 'Ožu', 'Tra', 'Svi', 'Lip', 'Srp', 'Kol', 'Ruj', 'Lis', 'Stu', 'Pro']
      },
      'days': ['Ned', 'Pon', 'Uto', 'Sri', 'Čet', 'Pet', 'Sub']
    },

    'it': {
      'months': {
        'original': ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
        'abbr': ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic']
      },
      'days': ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab']
    },

    'nl': {
      'months': {
        'original': ['Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Maa', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za']
    },

    'de': {
      'months': {
        'original': ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
        'abbr': ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
      },
      'days': ['So.', 'Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.']
    },

    'pt-br': {
      'months': {
        'original': ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
        'abbr': ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
      },
      'days': ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab']
    },

    'vi': {
      'months': {
        'original': ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'],
        'abbr': ['T 01', 'T 02', 'T 03', 'T 04', 'T 05', 'T 06', 'T 07', 'T 08', 'T 09', 'T 10', 'T 11', 'T 12']
      },
      'days': ['CN', 'Thứ 2', 'Thứ 3', 'Thứ 4', 'Thứ 5', 'Thứ 6', 'Thứ 7']
    },

    'zh': {
      'months': {
        'original': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
        'abbr': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
      },
      'days': ['日', '一', '二', '三', '四', '五', '六']
    },

    'ja': {
      'months': {
        'original': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        'abbr': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
      },
      'days': ['日', '月', '火', '水', '木', '金', '土']
    },

    'he': {
      'months': {
        'original': ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'],
        'abbr': ['ינו', 'פבר', 'מרץ', 'אפר', 'מאי', 'יונ', 'יול', 'אוג', 'ספט', 'אוק', 'נוב', 'דצמ']
      },
      'days': ['א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ש']
    },

    'cs': {
      'months': {
        'original': ['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
        'abbr': ['led', 'úno', 'bře', 'dub', 'kvě', 'čer', 'čec', 'srp', 'zář', 'říj', 'lis', 'pro']
      },
      'days': ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so']
    },

    'ru': {
      'months': {
        'original': ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
        'abbr': ['Янв', 'Февр', 'Март', 'Апр', 'Май', 'Июнь', 'Июль', 'Авг', 'Сент', 'Окт', 'Нояб', 'Дек']
      },
      'days': ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
    },

    'sv': {
      'months': {
        'original': ['Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      },
      'days': ['Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör']
    },

    'th': {
      'months': {
        'original': ['มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'],
        'abbr': ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.']
      },
      'days': ['อา', 'จ', 'อ', 'พ', 'พฤ', 'ศ', 'ส']
    },

    'ro': {
      'months': {
        'original': ['Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie'],
        'abbr': ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sep', 'Oct', 'Noi', 'Dec']
      },
      'days': ['D', 'L', 'Ma', 'Mi', 'J', 'V', 'S']
    },

    'sl': {
      'months': {
        'original': ['Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Avg', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Ned', 'Pon', 'Tor', 'Sre', 'Čet', 'Pet', 'Sob']
    }

  }

}
<commit_msg>Update DateLanguages.js<commit_after>export default {
  translations: {

    'da': {
      'months': {
        'original': ['Januar', 'Februar', 'Marts', 'April', 'Maj', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø']
    },

    'en': {
      'months': {
        'original': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      },
      'days': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
    },

    'es': {
      'months': {
        'original': ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
        'abbr': ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic']
      },
      'days': ['Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sab']
    },

    'fi': {
      'months': {
        'original': ['tammikuu', 'helmikuu', 'maaliskuu', 'huhtikuu', 'toukokuu', 'kesäkuu', 'heinäkuu', 'elokuu', 'syyskuu', 'lokakuu', 'marraskuu', 'joulukuu'],
        'abbr': ['tammi', 'helmi', 'maalis', 'huhti', 'touko', 'kesä', 'heinä', 'elo', 'syys', 'loka', 'marras', 'joulu']
      },
      'days': ['su', 'ma', 'ti', 'ke', 'to', 'pe', 'la']
    },

    'fr': {
      'months': {
        'original': ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
        'abbr': ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jui', 'Juil', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc']
      },
      'days': ['Dim', 'Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam']
    },

    'hr': {
      'months': {
        'original': ['Siječanj', 'Veljača', 'Ožujak', 'Travanj', 'Svibanj', 'Lipanj', 'Srpanj', 'Kolovoz', 'Rujan', 'Listopad', 'Studeni', 'Prosinac'],
        'abbr': ['Sij', 'Velj', 'Ožu', 'Tra', 'Svi', 'Lip', 'Srp', 'Kol', 'Ruj', 'Lis', 'Stu', 'Pro']
      },
      'days': ['Ned', 'Pon', 'Uto', 'Sri', 'Čet', 'Pet', 'Sub']
    },

    'it': {
      'months': {
        'original': ['Gennaio', 'Febbraio', 'Marzo', 'Aprile', 'Maggio', 'Giugno', 'Luglio', 'Agosto', 'Settembre', 'Ottobre', 'Novembre', 'Dicembre'],
        'abbr': ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic']
      },
      'days': ['Dom', 'Lun', 'Mar', 'Mer', 'Gio', 'Ven', 'Sab']
    },

    'nl': {
      'months': {
        'original': ['Januari', 'Februari', 'Maart', 'April', 'Mei', 'Juni', 'Juli', 'Augustus', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Maa', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za']
    },

    'de': {
      'months': {
        'original': ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
        'abbr': ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez']
      },
      'days': ['So.', 'Mo.', 'Di.', 'Mi.', 'Do.', 'Fr.', 'Sa.']
    },

    'pt-br': {
      'months': {
        'original': ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
        'abbr': ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez']
      },
      'days': ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab']
    },

    'vi': {
      'months': {
        'original': ['Tháng 1', 'Tháng 2', 'Tháng 3', 'Tháng 4', 'Tháng 5', 'Tháng 6', 'Tháng 7', 'Tháng 8', 'Tháng 9', 'Tháng 10', 'Tháng 11', 'Tháng 12'],
        'abbr': ['T 01', 'T 02', 'T 03', 'T 04', 'T 05', 'T 06', 'T 07', 'T 08', 'T 09', 'T 10', 'T 11', 'T 12']
      },
      'days': ['CN', 'Thứ 2', 'Thứ 3', 'Thứ 4', 'Thứ 5', 'Thứ 6', 'Thứ 7']
    },

    'zh': {
      'months': {
        'original': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
        'abbr': ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
      },
      'days': ['日', '一', '二', '三', '四', '五', '六']
    },

    'ja': {
      'months': {
        'original': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        'abbr': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
      },
      'days': ['日', '月', '火', '水', '木', '金', '土']
    },

    'he': {
      'months': {
        'original': ['ינואר', 'פברואר', 'מרץ', 'אפריל', 'מאי', 'יוני', 'יולי', 'אוגוסט', 'ספטמבר', 'אוקטובר', 'נובמבר', 'דצמבר'],
        'abbr': ['ינו', 'פבר', 'מרץ', 'אפר', 'מאי', 'יונ', 'יול', 'אוג', 'ספט', 'אוק', 'נוב', 'דצמ']
      },
      'days': ['א', 'ב', 'ג', 'ד', 'ה', 'ו', 'ש']
    },

    'cs': {
      'months': {
        'original': ['leden', 'únor', 'březen', 'duben', 'květen', 'červen', 'červenec', 'srpen', 'září', 'říjen', 'listopad', 'prosinec'],
        'abbr': ['led', 'úno', 'bře', 'dub', 'kvě', 'čer', 'čec', 'srp', 'zář', 'říj', 'lis', 'pro']
      },
      'days': ['ne', 'po', 'út', 'st', 'čt', 'pá', 'so']
    },

    'ru': {
      'months': {
        'original': ['Январь', 'Февраль', 'Март', 'Апрель', 'Май', 'Июнь', 'Июль', 'Август', 'Сентябрь', 'Октябрь', 'Ноябрь', 'Декабрь'],
        'abbr': ['Янв', 'Февр', 'Март', 'Апр', 'Май', 'Июнь', 'Июль', 'Авг', 'Сент', 'Окт', 'Нояб', 'Дек']
      },
      'days': ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб']
    },

    'sv': {
      'months': {
        'original': ['Januari', 'Februari', 'Mars', 'April', 'Maj', 'Juni', 'Juli', 'Augusti', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
      },
      'days': ['Sön', 'Mån', 'Tis', 'Ons', 'Tor', 'Fre', 'Lör']
    },

    'th': {
      'months': {
        'original': ['มกราคม', 'กุมภาพันธ์', 'มีนาคม', 'เมษายน', 'พฤษภาคม', 'มิถุนายน', 'กรกฎาคม', 'สิงหาคม', 'กันยายน', 'ตุลาคม', 'พฤศจิกายน', 'ธันวาคม'],
        'abbr': ['ม.ค.', 'ก.พ.', 'มี.ค.', 'เม.ย.', 'พ.ค.', 'มิ.ย.', 'ก.ค.', 'ส.ค.', 'ก.ย.', 'ต.ค.', 'พ.ย.', 'ธ.ค.']
      },
      'days': ['อา', 'จ', 'อ', 'พ', 'พฤ', 'ศ', 'ส']
    },

    'ro': {
      'months': {
        'original': ['Ianuarie', 'Februarie', 'Martie', 'Aprilie', 'Mai', 'Iunie', 'Iulie', 'August', 'Septembrie', 'Octombrie', 'Noiembrie', 'Decembrie'],
        'abbr': ['Ian', 'Feb', 'Mar', 'Apr', 'Mai', 'Iun', 'Iul', 'Aug', 'Sep', 'Oct', 'Noi', 'Dec']
      },
      'days': ['D', 'L', 'Ma', 'Mi', 'J', 'V', 'S']
    },

    'sl-si': {
      'months': {
        'original': ['Januar', 'Februar', 'Marec', 'April', 'Maj', 'Junij', 'Julij', 'Avgust', 'September', 'Oktober', 'November', 'December'],
        'abbr': ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Avg', 'Sep', 'Okt', 'Nov', 'Dec']
      },
      'days': ['Ned', 'Pon', 'Tor', 'Sre', 'Čet', 'Pet', 'Sob']
    }

  }

}
<|endoftext|>


<commit_before>/*
 * BSD 3-Clause License
 *
 * Copyright (c) 2017, MapCreator
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 *  Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * Converts snake_case strings to camelCase
 * @param {String} str - a snake_case string
 * @returns {String} - Converted camelCase string
 * @private
 */
export function snakeToCamelCase(str) {
  return str.replace(/(?:(_[a-z\d]))/g, x => x[1].toUpperCase());
}

/**
 * Converts camelCase strings to snake_case
 * @param {String} str - a camelCase string
 * @returns {String} - Converted snake_case string
 * @private
 */
export function camelToSnakeCase(str) {
  return str.replace(/([A-Z])/g, x => '_' + x.toLowerCase());
}

/**
 * Converts PascalCase strings to camelCase
 * @param {String} str - a PascalCase string
 * @returns {String} - Converted camelCase string
 * @private
 */
export function pascalToCamelCase(str) {
  return str.replace(/^([A-Z])/g, x => x.toLowerCase());
}

/**
 * Converts camelCase strings to PascalCase
 * @param {String} str - a camelCase string
 * @returns {String} - Converted PascalCase string
 * @private
 */
export function camelToPascalCase(str) {
  return str.replace(/^([a-z])/g, x => x.toUpperCase());
}<commit_msg>eslint --fix src<commit_after>/*
 * BSD 3-Clause License
 *
 * Copyright (c) 2017, MapCreator
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 *
 *  Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 *  Neither the name of the copyright holder nor the names of its
 *   contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * Converts snake_case strings to camelCase
 * @param {String} str - a snake_case string
 * @returns {String} - Converted camelCase string
 * @private
 */
export function snakeToCamelCase(str) {
  return str.replace(/(?:(_[a-z\d]))/g, x => x[1].toUpperCase());
}

/**
 * Converts camelCase strings to snake_case
 * @param {String} str - a camelCase string
 * @returns {String} - Converted snake_case string
 * @private
 */
export function camelToSnakeCase(str) {
  return str.replace(/([A-Z])/g, x => '_' + x.toLowerCase());
}

/**
 * Converts PascalCase strings to camelCase
 * @param {String} str - a PascalCase string
 * @returns {String} - Converted camelCase string
 * @private
 */
export function pascalToCamelCase(str) {
  return str.replace(/^([A-Z])/g, x => x.toLowerCase());
}

/**
 * Converts camelCase strings to PascalCase
 * @param {String} str - a camelCase string
 * @returns {String} - Converted PascalCase string
 * @private
 */
export function camelToPascalCase(str) {
  return str.replace(/^([a-z])/g, x => x.toUpperCase());
}
<|endoftext|>


<commit_before>// -*- js -*-

// Shared between all QML components
//.pragma library

var __wb = [
    [WhiteBalance.Auto, qsTr("Automatic"),
     "icon-m-camera-whitebalance-auto-selected"],
    [WhiteBalance.Sunset, qsTr("Sunny"),
     "icon-m-camera-whitebalance-sunny-selected"],
    [WhiteBalance.Cloudy, qsTr("Cloudy"),
     "icon-m-camera-whitebalance-cloudy-selected"],
    [WhiteBalance.Flourescent, qsTr("Flourescent"),
     "icon-m-camera-whitebalance-fluorescent-selected"],
    [WhiteBalance.Tungsten, qsTr("Tungsten"),
     "icon-m-camera-whitebalance-tungsten-selected"],
];

var __cf = [
    [ColorTone.Normal, qsTr("Off"),
     "icon-m-camera-no-filter-selected"],
    [ColorTone.GrayScale, qsTr("Black & white"),
     "icon-m-camera-filter-black-white-selected"],
    [ColorTone.Sepia, qsTr("Sepia"),
     "icon-m-camera-filter-sepia-selected"],
    [ColorTone.Vivid, qsTr("Vivid"),
     "icon-m-camera-filter-vivid-selected"],
    [ColorTone.Negative, qsTr("Negative"),
     "icon-m-camera-filter-negative-selected"],
    [ColorTone.Solarize, qsTr("Solarize"),
     "icon-m-camera-filter-solarize-selected"]
];

function filterData(val, data, item) {
    var x = 0;
    var i = data.length;
    for (x = 0; x < i; x++) {
        if (data[x][0] == val) {
            return data[x][item];
        }
    }
}

function wbSelectedIcon(wb) {
    return filterData(wb, __wb, 2);
}

function wbName(wb) {
    return filterData(wb, __wb, 1);
}

function cfSelectedIcon(cf) {
    return filterData(cf, __cf, 2);
}

function cfName(cf) {
    return filterData(cf, __cf, 1);
}
<commit_msg>Added normal icons<commit_after>// -*- js -*-

// Shared between all QML components
//.pragma library

var __wb = [
    [WhiteBalance.Auto, qsTr("Automatic"),
     "icon-m-camera-whitebalance-auto-selected", "icon-m-camera-whitebalance-auto"],
    [WhiteBalance.Sunset, qsTr("Sunny"),
     "icon-m-camera-whitebalance-sunny-selected", "icon-m-camera-whitebalance-sunny"],
    [WhiteBalance.Cloudy, qsTr("Cloudy"),
     "icon-m-camera-whitebalance-cloudy-selected", "icon-m-camera-whitebalance-cloudy"],
    [WhiteBalance.Flourescent, qsTr("Flourescent"),
     "icon-m-camera-whitebalance-fluorescent-selected", "icon-m-camera-whitebalance-fluorescent"],
    [WhiteBalance.Tungsten, qsTr("Tungsten"),
     "icon-m-camera-whitebalance-tungsten-selected", "icon-m-camera-whitebalance-tungsten"],
];

var __cf = [
    [ColorTone.Normal, qsTr("Off"),
     "icon-m-camera-no-filter-selected", "icon-m-camera-no-filter"],
    [ColorTone.GrayScale, qsTr("Black & white"),
     "icon-m-camera-filter-black-white-selected", "icon-m-camera-filter-black-white"],
    [ColorTone.Sepia, qsTr("Sepia"),
     "icon-m-camera-filter-sepia-selected", "icon-m-camera-filter-sepia"],
    [ColorTone.Vivid, qsTr("Vivid"),
     "icon-m-camera-filter-vivid-selected", "icon-m-camera-filter-vivid"],
    [ColorTone.Negative, qsTr("Negative"),
     "icon-m-camera-filter-negative-selected", "icon-m-camera-filter-negative"],
    [ColorTone.Solarize, qsTr("Solarize"),
     "icon-m-camera-filter-solarize-selected", "icon-m-camera-filter-solarize"]
];

function filterData(val, data, item) {
    var x = 0;
    var i = data.length;
    for (x = 0; x < i; x++) {
        if (data[x][0] == val) {
            return data[x][item];
        }
    }
}

function wbSelectedIcon(wb) {
    return filterData(wb, __wb, 2);
}

function wbIcon(wb) {
    return filterData(wb, __wb, 3);
}

function wbName(wb) {
    return filterData(wb, __wb, 1);
}

function cfSelectedIcon(cf) {
    return filterData(cf, __cf, 2);
}

function cfIcon(cf) {
    return filterData(cf, __cf, 3);
}

function cfName(cf) {
    return filterData(cf, __cf, 1);
}
<|endoftext|>