forked from MapComplete/MapComplete
		
	
		
			
				
	
	
		
			121 lines
		
	
	
		
			No EOL
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			121 lines
		
	
	
		
			No EOL
		
	
	
		
			3.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
import {Tag} from "./Tag";
 | 
						|
import {TagsFilter} from "./TagsFilter";
 | 
						|
import {And} from "./And";
 | 
						|
import {Utils} from "../Utils";
 | 
						|
 | 
						|
export class TagUtils {
 | 
						|
    static ApplyTemplate(template: string, tags: any): string {
 | 
						|
        for (const k in tags) {
 | 
						|
            while (template.indexOf("{" + k + "}") >= 0) {
 | 
						|
                const escaped = tags[k].replace(/</g, '<').replace(/>/g, '>');
 | 
						|
                template = template.replace("{" + k + "}", escaped);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return template;
 | 
						|
    }
 | 
						|
 | 
						|
    static KVtoProperties(tags: Tag[]): any {
 | 
						|
        const properties = {};
 | 
						|
        for (const tag of tags) {
 | 
						|
            properties[tag.key] = tag.value
 | 
						|
        }
 | 
						|
        return properties;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Given two hashes of {key --> values[]}, makes sure that every neededTag is present in availableTags
 | 
						|
     */
 | 
						|
    static AllKeysAreContained(availableTags: any, neededTags: any) {
 | 
						|
        for (const neededKey in neededTags) {
 | 
						|
            const availableValues: string[] = availableTags[neededKey]
 | 
						|
            if (availableValues === undefined) {
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
            const neededValues: string[] = neededTags[neededKey];
 | 
						|
            for (const neededValue of neededValues) {
 | 
						|
                if (availableValues.indexOf(neededValue) < 0) {
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
    /***
 | 
						|
     * Creates a hash {key --> [values]}, with all the values present in the tagsfilter
 | 
						|
     *
 | 
						|
     * @param tagsFilters
 | 
						|
     * @constructor
 | 
						|
     */
 | 
						|
    static SplitKeys(tagsFilters: TagsFilter[]) {
 | 
						|
        const keyValues = {} // Map string -> string[]
 | 
						|
        tagsFilters = [...tagsFilters] // copy all
 | 
						|
        while (tagsFilters.length > 0) {
 | 
						|
            // Queue
 | 
						|
            const tagsFilter = tagsFilters.shift();
 | 
						|
 | 
						|
            if (tagsFilter === undefined) {
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
 | 
						|
            if (tagsFilter instanceof And) {
 | 
						|
                tagsFilters.push(...tagsFilter.and);
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
 | 
						|
            if (tagsFilter instanceof Tag) {
 | 
						|
                if (keyValues[tagsFilter.key] === undefined) {
 | 
						|
                    keyValues[tagsFilter.key] = [];
 | 
						|
                }
 | 
						|
                keyValues[tagsFilter.key].push(...tagsFilter.value.split(";"));
 | 
						|
                continue;
 | 
						|
            }
 | 
						|
 | 
						|
            console.error("Invalid type to flatten the multiAnswer", tagsFilter);
 | 
						|
            throw "Invalid type to FlattenMultiAnswer"
 | 
						|
        }
 | 
						|
        return keyValues;
 | 
						|
    }
 | 
						|
 | 
						|
    /**
 | 
						|
     * Given multiple tagsfilters which can be used as answer, will take the tags with the same keys together as set.
 | 
						|
     * E.g:
 | 
						|
     *
 | 
						|
     * FlattenMultiAnswer([and: [ "x=a", "y=0;1"], and: ["x=b", "y=2"], and: ["x=", "y=3"]])
 | 
						|
     * will result in
 | 
						|
     * ["x=a;b", "y=0;1;2;3"]
 | 
						|
     *
 | 
						|
     * @param tagsFilters
 | 
						|
     * @constructor
 | 
						|
     */
 | 
						|
    static FlattenMultiAnswer(tagsFilters: TagsFilter[]): And {
 | 
						|
        if (tagsFilters === undefined) {
 | 
						|
            return new And([]);
 | 
						|
        }
 | 
						|
 | 
						|
        let keyValues = TagUtils.SplitKeys(tagsFilters);
 | 
						|
        const and: TagsFilter[] = []
 | 
						|
        for (const key in keyValues) {
 | 
						|
            and.push(new Tag(key, Utils.Dedup(keyValues[key]).join(";")));
 | 
						|
        }
 | 
						|
        return new And(and);
 | 
						|
    }
 | 
						|
 | 
						|
    static MatchesMultiAnswer(tag: TagsFilter, tags: any): boolean {
 | 
						|
        const splitted = TagUtils.SplitKeys([tag]);
 | 
						|
        for (const splitKey in splitted) {
 | 
						|
            const neededValues = splitted[splitKey];
 | 
						|
            if (tags[splitKey] === undefined) {
 | 
						|
                return false;
 | 
						|
            }
 | 
						|
 | 
						|
            const actualValue = tags[splitKey].split(";");
 | 
						|
            for (const neededValue of neededValues) {
 | 
						|
                if (actualValue.indexOf(neededValue) < 0) {
 | 
						|
                    return false;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
} |