<commit_before>import {
    event as d3_event,
    select as d3_select
} from 'd3-selection';

import { t, textDirection } from '../util/locale';

import { actionAddEntity } from '../actions/add_entity';
import { actionAddMember } from '../actions/add_member';
import { actionChangeMember } from '../actions/change_member';
import { actionDeleteMember } from '../actions/delete_member';

import { modeSelect } from '../modes/select';
import { osmEntity, osmRelation } from '../osm';
import { services } from '../services';
import { svgIcon } from '../svg/icon';
import { uiCombobox } from './combobox';
import { uiDisclosure } from './disclosure';
import { tooltip } from '../util/tooltip';
import { utilArrayGroupBy, utilDisplayName, utilNoAuto, utilHighlightEntities } from '../util';


export function uiRawMembershipEditor(context) {
    var taginfo = services.taginfo;
    var nearbyCombo = uiCombobox(context, 'parent-relation')
        .minItems(1)
        .fetcher(fetchNearbyRelations);
    var _inChange = false;
    var _entityID;
    var _showBlank;


    function selectRelation(d) {
        d3_event.preventDefault();

        // remove the hover-highlight styling
        utilHighlightEntities([d.relation.id], false, context);

        context.enter(modeSelect(context, [d.relation.id]));
    }


    function changeRole(d) {
        if (d === 0) return;    // called on newrow (shoudn't happen)
        if (_inChange) return;  // avoid accidental recursive call #5731

        var oldRole = d.member.role;
        var newRole = d3_select(this).property('value');

        if (oldRole !== newRole) {
            _inChange = true;
            context.perform(
                actionChangeMember(d.relation.id, Object.assign({}, d.member, { role: newRole }), d.index),
                t('operations.change_role.annotation')
            );
        }
        _inChange = false;
    }


    function addMembership(d, role) {
        this.blur();           // avoid keeping focus on the button
        _showBlank = false;

        var member = { id: _entityID, type: context.entity(_entityID).type, role: role };

        if (d.relation) {
            context.perform(
                actionAddMember(d.relation.id, member),
                t('operations.add_member.annotation')
            );

        } else {
            var relation = osmRelation();
            context.perform(
                actionAddEntity(relation),
                actionAddMember(relation.id, member),
                t('operations.add.annotation.relation')
            );

            context.enter(modeSelect(context, [relation.id]).newFeature(true));
        }
    }


    function deleteMembership(d) {
        this.blur();           // avoid keeping focus on the button
        if (d === 0) return;   // called on newrow (shoudn't happen)

        // remove the hover-highlight styling
        utilHighlightEntities([d.relation.id], false, context);

        context.perform(
            actionDeleteMember(d.relation.id, d.index),
            t('operations.delete_member.annotation')
        );
    }


    function fetchNearbyRelations(q, callback) {
        var newRelation = { relation: null, value: t('inspector.new_relation') };
        var result = [];
        var graph = context.graph();

        context.intersects(context.extent()).forEach(function(entity) {
            if (entity.type !== 'relation' || entity.id === _entityID) return;

            var matched = context.presets().match(entity, graph);
            var presetName = (matched && matched.name()) || t('inspector.relation');
            var entityName = utilDisplayName(entity) || '';

            var value = presetName + ' ' + entityName;
            if (q && (value + ' ' + entity.id).toLowerCase().indexOf(q.toLowerCase()) === -1) return;

            result.push({ relation: entity, value: value });
        });

        result.sort(function(a, b) {
            return osmRelation.creationOrder(a.relation, b.relation);
        });

        // Dedupe identical names by appending relation id - see #2891
        var dupeGroups = Object.values(utilArrayGroupBy(result, 'value'))
            .filter(function(v) { return v.length > 1; });

        dupeGroups.forEach(function(group) {
            group.forEach(function(obj) {
                obj.value += ' ' + obj.relation.id;
            });
        });

        result.forEach(function(obj) {
            obj.title = obj.value;
        });

        result.unshift(newRelation);
        callback(result);
    }


    function rawMembershipEditor(selection) {
        var entity = context.entity(_entityID);
        var parents = context.graph().parentRelations(entity);
        var memberships = [];

        parents.slice(0, 1000).forEach(function(relation) {
            relation.members.forEach(function(member, index) {<commit_msg>Accept IDs of loaded relations in the raw membership editor (close #3487)<commit_after>import {
    event as d3_event,
    select as d3_select
} from 'd3-selection';

import { t, textDirection } from '../util/locale';

import { actionAddEntity } from '../actions/add_entity';
import { actionAddMember } from '../actions/add_member';
import { actionChangeMember } from '../actions/change_member';
import { actionDeleteMember } from '../actions/delete_member';

import { modeSelect } from '../modes/select';
import { osmEntity, osmRelation } from '../osm';
import { services } from '../services';
import { svgIcon } from '../svg/icon';
import { uiCombobox } from './combobox';
import { uiDisclosure } from './disclosure';
import { tooltip } from '../util/tooltip';
import { utilArrayGroupBy, utilDisplayName, utilNoAuto, utilHighlightEntities } from '../util';


export function uiRawMembershipEditor(context) {
    var taginfo = services.taginfo;
    var nearbyCombo = uiCombobox(context, 'parent-relation')
        .minItems(1)
        .fetcher(fetchNearbyRelations);
    var _inChange = false;
    var _entityID;
    var _showBlank;


    function selectRelation(d) {
        d3_event.preventDefault();

        // remove the hover-highlight styling
        utilHighlightEntities([d.relation.id], false, context);

        context.enter(modeSelect(context, [d.relation.id]));
    }


    function changeRole(d) {
        if (d === 0) return;    // called on newrow (shoudn't happen)
        if (_inChange) return;  // avoid accidental recursive call #5731

        var oldRole = d.member.role;
        var newRole = d3_select(this).property('value');

        if (oldRole !== newRole) {
            _inChange = true;
            context.perform(
                actionChangeMember(d.relation.id, Object.assign({}, d.member, { role: newRole }), d.index),
                t('operations.change_role.annotation')
            );
        }
        _inChange = false;
    }


    function addMembership(d, role) {
        this.blur();           // avoid keeping focus on the button
        _showBlank = false;

        var member = { id: _entityID, type: context.entity(_entityID).type, role: role };

        if (d.relation) {
            context.perform(
                actionAddMember(d.relation.id, member),
                t('operations.add_member.annotation')
            );

        } else {
            var relation = osmRelation();
            context.perform(
                actionAddEntity(relation),
                actionAddMember(relation.id, member),
                t('operations.add.annotation.relation')
            );

            context.enter(modeSelect(context, [relation.id]).newFeature(true));
        }
    }


    function deleteMembership(d) {
        this.blur();           // avoid keeping focus on the button
        if (d === 0) return;   // called on newrow (shoudn't happen)

        // remove the hover-highlight styling
        utilHighlightEntities([d.relation.id], false, context);

        context.perform(
            actionDeleteMember(d.relation.id, d.index),
            t('operations.delete_member.annotation')
        );
    }


    function fetchNearbyRelations(q, callback) {
        var newRelation = { relation: null, value: t('inspector.new_relation') };

        var result = [];

        var graph = context.graph();

        function baseDisplayLabel(entity) {
            var matched = context.presets().match(entity, graph);
            var presetName = (matched && matched.name()) || t('inspector.relation');
            var entityName = utilDisplayName(entity) || '';

            return presetName + ' ' + entityName;
        }

        var explicitRelation = q && context.hasEntity(q.toLowerCase());
        if (explicitRelation && explicitRelation.type === 'relation' && explicitRelation.id !== _entityID) {
            // loaded relation is specified explicitly, only show that

            result.push({
                relation: explicitRelation,
                value: baseDisplayLabel(explicitRelation) + ' ' + explicitRelation.id
            });
        } else {

            context.intersects(context.extent()).forEach(function(entity) {
                if (entity.type !== 'relation' || entity.id === _entityID) return;

                var value = baseDisplayLabel(entity);
                if (q && (value + ' ' + entity.id).toLowerCase().indexOf(q.toLowerCase()) === -1) return;

                result.push({ relation: entity, value: value });
            });

            result.sort(function(a, b) {
                return osmRelation.creationOrder(a.relation, b.relation);
            });

            // Dedupe identical names by appending relation id - see #2891
            var dupeGroups = Object.values(utilArrayGroupBy(result, 'value'))
                .filter(function(v) { return v.length > 1; });

            dupeGroups.forEach(function(group) {
                group.forEach(function(obj) {
                    obj.value += ' ' + obj.relation.id;
                });
            });
        }

        result.forEach(function(obj) {
            obj.title = obj.value;
        });

        result.unshift(newRelation);
        callback(result);
    }


    function rawMembershipEditor(selection) {
        var entity = context.entity(_entityID);
        var parents = context.graph().parentRelations(entity);
        var memberships = [];

        parents.slice(0, 1000).forEach(function(relation) {
            relation.members.forEach(function(member, index) {
{'fraction_non_alphanumeric': 0.128136114582332, 'fraction_numerical': 0.004806305873305777, 'mean_word_length': 2.2250464972101676, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1347870', 'n_tokens_mistral': 2923, 'n_tokens_neox': 2761, 'n_words': 632}