From 853f4506a24a34cad59f459fb1eac2c28a0943b2 Mon Sep 17 00:00:00 2001 From: Georgy Frolov Date: Tue, 10 May 2022 19:16:05 +0300 Subject: [PATCH 1/3] Added ORDER BY to query language --- README.rst | 8 ++ djangoql/admin.py | 1 + djangoql/ast.py | 17 ++++ djangoql/lexer.py | 20 +++++ djangoql/parser.py | 54 +++++++++++- djangoql/parsetab.py | 100 +++++++++++++---------- djangoql/queryset.py | 17 +++- djangoql/schema.py | 22 +++-- test_project/core/admin.py | 1 - test_project/core/tests/test_lexer.py | 2 +- test_project/core/tests/test_parser.py | 82 ++++++++++++++----- test_project/core/tests/test_queryset.py | 18 ++++ test_project/test_project/settings.py | 23 ++++++ 13 files changed, 291 insertions(+), 74 deletions(-) diff --git a/README.rst b/README.rst index 9d5164e..78ae76b 100644 --- a/README.rst +++ b/README.rst @@ -113,6 +113,9 @@ also an option that controls if that checkbox is enabled by default - If you don't want two search modes, simply remove ``search_fields`` from your ModelAdmin class. +Note that ``DjangoSQLSearchMixin`` overwrites the ``ordering`` field +of your view. + Language reference ------------------ @@ -145,6 +148,11 @@ parenthesis. DjangoQL is case-sensitive. Example: ``date_published ~ "2021-11"`` - find books published in Nov, 2021; - test a value vs. list: ``in``, ``not in``. Example: ``pk in (2, 3)``. +- results can be sorted with a SQL-style ``order by`` clause at the end of + the query. Sorting direction is either ``asc`` or ``desc`` (default ``asc``). + Example: + ``name endswith "peace" order by name desc, author.last_name`` +- an ``order by`` clause alone is also a valid query. DjangoQL Schema diff --git a/djangoql/admin.py b/djangoql/admin.py index 41a73e5..4a25563 100644 --- a/djangoql/admin.py +++ b/djangoql/admin.py @@ -46,6 +46,7 @@ def get_filters_params(self, *args, **kwargs): class DjangoQLSearchMixin(object): search_fields = ('_djangoql',) # just a stub to have search input displayed + ordering = () djangoql_completion = True djangoql_completion_enabled_by_default = True djangoql_schema = DjangoQLSchema diff --git a/djangoql/ast.py b/djangoql/ast.py index 1e07af2..3f5a94a 100644 --- a/djangoql/ast.py +++ b/djangoql/ast.py @@ -76,3 +76,20 @@ class Logical(Operator): class Comparison(Operator): pass + + +class OrderingKey(Node): + def __init__(self, name, direction): + self.name = name + self.direction = direction + + +class Ordering(Node): + def __init__(self, keys): + self.fields = keys + + +class Query(Node): + def __init__(self, expression, ordering): + self.expression = expression + self.ordering = ordering diff --git a/djangoql/lexer.py b/djangoql/lexer.py index 580dab9..195c089 100644 --- a/djangoql/lexer.py +++ b/djangoql/lexer.py @@ -86,6 +86,10 @@ def find_column(self, t): 'NOT_CONTAINS', 'STARTSWITH', 'ENDSWITH', + 'ORDER', + 'BY', + 'ASC', + 'DESC', ] t_COMMA = ',' @@ -159,6 +163,22 @@ def t_FALSE(self, t): def t_NONE(self, t): return t + @TOKEN('order' + not_followed_by_name) + def t_ORDER(self, t): + return t + + @TOKEN('by' + not_followed_by_name) + def t_BY(self, t): + return t + + @TOKEN('asc' + not_followed_by_name) + def t_ASC(self, t): + return t + + @TOKEN('desc' + not_followed_by_name) + def t_DESC(self, t): + return t + def t_error(self, t): raise DjangoQLLexerError( message='Illegal character %s' % repr(t.value[0]), diff --git a/djangoql/parser.py b/djangoql/parser.py index 416f67a..d7ae9e3 100644 --- a/djangoql/parser.py +++ b/djangoql/parser.py @@ -5,7 +5,8 @@ import ply.yacc as yacc -from .ast import Comparison, Const, Expression, List, Logical, Name +from .ast import Comparison, Const, Expression, List, Logical, Name, Ordering, \ + OrderingKey, Query from .compat import binary_type, text_type from .exceptions import DjangoQLParserError from .lexer import DjangoQLLexer @@ -44,7 +45,25 @@ def parse(self, input=None, lexer=None, **kwargs): # noqa: A002 lexer = lexer or self.default_lexer return self.yacc.parse(input=input, lexer=lexer, **kwargs) - start = 'expression' + start = 'query' + + def p_query(self, p): + """ + query : expression + """ + p[0] = Query(expression=p[1], ordering=None) + + def p_query_only_ordering(self, p): + """ + query : ordering + """ + p[0] = Query(expression=None, ordering=p[1]) + + def p_ordered_query(self, p): + """ + query : expression ordering + """ + p[0] = Query(expression=p[1], ordering=p[2]) def p_expression_parens(self, p): """ @@ -136,6 +155,37 @@ def p_comparison_in_list(self, p): else: p[0] = Comparison(operator='%s %s' % (p[1], p[2])) + def p_undirected_ordering_key(self, p): + """ + ordering_key : name + """ + p[0] = OrderingKey(name=p[1], direction=None) + + def p_directed_ordering_key(self, p): + """ + ordering_key : name ASC + | name DESC + """ + p[0] = OrderingKey(name=p[1], direction=p[2]) + + def p_ordering_key_list_single(self, p): + """ + ordering_key_list : ordering_key + """ + p[0] = [p[1]] + + def p_ordering_key_list(self, p): + """ + ordering_key_list : ordering_key_list COMMA ordering_key + """ + p[0] = p[1] + [p[3]] + + def p_ordering(self, p): + """ + ordering : ORDER BY ordering_key_list + """ + p[0] = Ordering(keys=p[3]) + def p_const_value(self, p): """ const_value : number diff --git a/djangoql/parsetab.py b/djangoql/parsetab.py index 630ac84..e4bfdec 100644 --- a/djangoql/parsetab.py +++ b/djangoql/parsetab.py @@ -6,9 +6,9 @@ _lr_method = 'LALR' -_lr_signature = 'expressionAND COMMA CONTAINS EQUALS FALSE FLOAT_VALUE GREATER GREATER_EQUAL IN INT_VALUE LESS LESS_EQUAL NAME NONE NOT NOT_CONTAINS NOT_EQUALS OR PAREN_L PAREN_R STRING_VALUE TRUE\n expression : PAREN_L expression PAREN_R\n \n expression : expression logical expression\n \n expression : name comparison_number number\n | name comparison_string string\n | name comparison_equality boolean_value\n | name comparison_equality none\n | name comparison_in_list const_list_value\n \n name : NAME\n \n logical : AND\n | OR\n \n comparison_number : comparison_equality\n | comparison_greater_less\n \n comparison_string : comparison_equality\n | comparison_greater_less\n | comparison_contains\n \n comparison_equality : EQUALS\n | NOT_EQUALS\n \n comparison_greater_less : GREATER\n | GREATER_EQUAL\n | LESS\n | LESS_EQUAL\n \n comparison_contains : CONTAINS\n | NOT_CONTAINS\n \n comparison_in_list : IN\n | NOT IN\n \n const_value : number\n | string\n | none\n | boolean_value\n \n number : INT_VALUE\n \n number : FLOAT_VALUE\n \n string : STRING_VALUE\n \n none : NONE\n \n boolean_value : true\n | false\n \n true : TRUE\n \n false : FALSE\n \n const_list_value : PAREN_L const_value_list PAREN_R\n \n const_value_list : const_value_list COMMA const_value\n \n const_value_list : const_value\n ' +_lr_signature = 'queryAND ASC BY COMMA CONTAINS DESC ENDSWITH EQUALS FALSE FLOAT_VALUE GREATER GREATER_EQUAL IN INT_VALUE LESS LESS_EQUAL NAME NONE NOT NOT_CONTAINS NOT_EQUALS OR ORDER PAREN_L PAREN_R STARTSWITH STRING_VALUE TRUE\n query : expression\n \n query : expression ordering\n \n expression : PAREN_L expression PAREN_R\n \n expression : expression logical expression\n \n expression : name comparison_number number\n | name comparison_string string\n | name comparison_equality boolean_value\n | name comparison_equality none\n | name comparison_in_list const_list_value\n \n name : NAME\n \n logical : AND\n | OR\n \n comparison_number : comparison_equality\n | comparison_greater_less\n \n comparison_string : comparison_equality\n | comparison_greater_less\n | comparison_string_specific\n \n comparison_equality : EQUALS\n | NOT_EQUALS\n \n comparison_greater_less : GREATER\n | GREATER_EQUAL\n | LESS\n | LESS_EQUAL\n \n comparison_string_specific : CONTAINS\n | NOT_CONTAINS\n | STARTSWITH\n | NOT STARTSWITH\n | ENDSWITH\n | NOT ENDSWITH\n \n comparison_in_list : IN\n | NOT IN\n \n ordering_key : name\n \n ordering_key : name ASC\n | name DESC\n \n ordering_key_list : ordering_key\n \n ordering_key_list : ordering_key_list COMMA ordering_key\n \n ordering : ORDER BY ordering_key_list\n \n const_value : number\n | string\n | none\n | boolean_value\n \n number : INT_VALUE\n \n number : FLOAT_VALUE\n \n string : STRING_VALUE\n \n none : NONE\n \n boolean_value : true\n | false\n \n true : TRUE\n \n false : FALSE\n \n const_list_value : PAREN_L const_value_list PAREN_R\n \n const_value_list : const_value_list COMMA const_value\n \n const_value_list : const_value\n ' -_lr_action_items = {'PAREN_L':([0,2,5,6,7,12,17,41,],[2,2,2,-9,-10,40,-24,-25,]),'NAME':([0,2,5,6,7,],[4,4,4,-9,-10,]),'$end':([1,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,48,],[0,-2,-1,-3,-30,-31,-4,-32,-5,-6,-34,-35,-33,-36,-37,-7,-38,]),'AND':([1,8,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,48,],[6,6,6,-1,-3,-30,-31,-4,-32,-5,-6,-34,-35,-33,-36,-37,-7,-38,]),'OR':([1,8,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,48,],[7,7,7,-1,-3,-30,-31,-4,-32,-5,-6,-34,-35,-33,-36,-37,-7,-38,]),'EQUALS':([3,4,],[15,-8,]),'NOT_EQUALS':([3,4,],[16,-8,]),'IN':([3,4,18,],[17,-8,41,]),'NOT':([3,4,],[18,-8,]),'GREATER':([3,4,],[19,-8,]),'GREATER_EQUAL':([3,4,],[20,-8,]),'LESS':([3,4,],[21,-8,]),'LESS_EQUAL':([3,4,],[22,-8,]),'CONTAINS':([3,4,],[23,-8,]),'NOT_CONTAINS':([3,4,],[24,-8,]),'PAREN_R':([8,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,42,43,44,45,46,47,48,50,],[26,-2,-1,-3,-30,-31,-4,-32,-5,-6,-34,-35,-33,-36,-37,-7,48,-40,-26,-27,-28,-29,-38,-39,]),'INT_VALUE':([9,11,13,15,16,19,20,21,22,40,49,],[28,-11,-12,-16,-17,-18,-19,-20,-21,28,28,]),'FLOAT_VALUE':([9,11,13,15,16,19,20,21,22,40,49,],[29,-11,-12,-16,-17,-18,-19,-20,-21,29,29,]),'STRING_VALUE':([10,11,13,14,15,16,19,20,21,22,23,24,40,49,],[31,-13,-14,-15,-16,-17,-18,-19,-20,-21,-22,-23,31,31,]),'NONE':([11,15,16,40,49,],[36,-16,-17,36,36,]),'TRUE':([11,15,16,40,49,],[37,-16,-17,37,37,]),'FALSE':([11,15,16,40,49,],[38,-16,-17,38,38,]),'COMMA':([28,29,31,34,35,36,37,38,42,43,44,45,46,47,50,],[-30,-31,-32,-34,-35,-33,-36,-37,49,-40,-26,-27,-28,-29,-39,]),} +_lr_action_items = {'PAREN_L':([0,3,7,9,10,15,20,47,],[3,3,3,-11,-12,46,-30,-31,]),'NAME':([0,3,7,9,10,31,59,],[5,5,5,-11,-12,5,5,]),'$end':([1,2,5,6,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,50,51,52,60,61,62,64,],[0,-1,-10,-2,-4,-3,-5,-42,-43,-6,-44,-7,-8,-46,-47,-45,-48,-49,-9,-37,-35,-32,-33,-34,-50,-36,]),'ORDER':([2,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,62,],[8,-4,-3,-5,-42,-43,-6,-44,-7,-8,-46,-47,-45,-48,-49,-9,-50,]),'AND':([2,11,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,62,],[9,9,9,-3,-5,-42,-43,-6,-44,-7,-8,-46,-47,-45,-48,-49,-9,-50,]),'OR':([2,11,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,62,],[10,10,10,-3,-5,-42,-43,-6,-44,-7,-8,-46,-47,-45,-48,-49,-9,-50,]),'EQUALS':([4,5,],[18,-10,]),'NOT_EQUALS':([4,5,],[19,-10,]),'IN':([4,5,21,],[20,-10,47,]),'NOT':([4,5,],[21,-10,]),'GREATER':([4,5,],[22,-10,]),'GREATER_EQUAL':([4,5,],[23,-10,]),'LESS':([4,5,],[24,-10,]),'LESS_EQUAL':([4,5,],[25,-10,]),'CONTAINS':([4,5,],[26,-10,]),'NOT_CONTAINS':([4,5,],[27,-10,]),'STARTSWITH':([4,5,21,],[28,-10,48,]),'ENDSWITH':([4,5,21,],[29,-10,49,]),'ASC':([5,52,],[-10,60,]),'DESC':([5,52,],[-10,61,]),'COMMA':([5,34,35,37,40,41,42,43,44,50,51,52,53,54,55,56,57,58,60,61,64,65,],[-10,-42,-43,-44,-46,-47,-45,-48,-49,59,-35,-32,63,-52,-38,-39,-40,-41,-33,-34,-36,-51,]),'BY':([8,],[31,]),'PAREN_R':([11,30,32,33,34,35,36,37,38,39,40,41,42,43,44,45,53,54,55,56,57,58,62,65,],[32,-4,-3,-5,-42,-43,-6,-44,-7,-8,-46,-47,-45,-48,-49,-9,62,-52,-38,-39,-40,-41,-50,-51,]),'INT_VALUE':([12,14,16,18,19,22,23,24,25,46,63,],[34,-13,-14,-18,-19,-20,-21,-22,-23,34,34,]),'FLOAT_VALUE':([12,14,16,18,19,22,23,24,25,46,63,],[35,-13,-14,-18,-19,-20,-21,-22,-23,35,35,]),'STRING_VALUE':([13,14,16,17,18,19,22,23,24,25,26,27,28,29,46,48,49,63,],[37,-15,-16,-17,-18,-19,-20,-21,-22,-23,-24,-25,-26,-28,37,-27,-29,37,]),'NONE':([14,18,19,46,63,],[42,-18,-19,42,42,]),'TRUE':([14,18,19,46,63,],[43,-18,-19,43,43,]),'FALSE':([14,18,19,46,63,],[44,-18,-19,44,44,]),} _lr_action = {} for _k, _v in _lr_action_items.items(): @@ -17,7 +17,7 @@ _lr_action[_x][_k] = _y del _lr_action_items -_lr_goto_items = {'expression':([0,2,5,],[1,8,25,]),'name':([0,2,5,],[3,3,3,]),'logical':([1,8,25,],[5,5,5,]),'comparison_number':([3,],[9,]),'comparison_string':([3,],[10,]),'comparison_equality':([3,],[11,]),'comparison_in_list':([3,],[12,]),'comparison_greater_less':([3,],[13,]),'comparison_contains':([3,],[14,]),'number':([9,40,49,],[27,44,44,]),'string':([10,40,49,],[30,45,45,]),'boolean_value':([11,40,49,],[32,47,47,]),'none':([11,40,49,],[33,46,46,]),'true':([11,40,49,],[34,34,34,]),'false':([11,40,49,],[35,35,35,]),'const_list_value':([12,],[39,]),'const_value_list':([40,],[42,]),'const_value':([40,49,],[43,50,]),} +_lr_goto_items = {'query':([0,],[1,]),'expression':([0,3,7,],[2,11,30,]),'name':([0,3,7,31,59,],[4,4,4,52,52,]),'ordering':([2,],[6,]),'logical':([2,11,30,],[7,7,7,]),'comparison_number':([4,],[12,]),'comparison_string':([4,],[13,]),'comparison_equality':([4,],[14,]),'comparison_in_list':([4,],[15,]),'comparison_greater_less':([4,],[16,]),'comparison_string_specific':([4,],[17,]),'number':([12,46,63,],[33,55,55,]),'string':([13,46,63,],[36,56,56,]),'boolean_value':([14,46,63,],[38,58,58,]),'none':([14,46,63,],[39,57,57,]),'true':([14,46,63,],[40,40,40,]),'false':([14,46,63,],[41,41,41,]),'const_list_value':([15,],[45,]),'ordering_key_list':([31,],[50,]),'ordering_key':([31,59,],[51,64,]),'const_value_list':([46,],[53,]),'const_value':([46,63,],[54,65,]),} _lr_goto = {} for _k, _v in _lr_goto_items.items(): @@ -26,45 +26,57 @@ _lr_goto[_x][_k] = _y del _lr_goto_items _lr_productions = [ - ("S' -> expression","S'",1,None,None,None), - ('expression -> PAREN_L expression PAREN_R','expression',3,'p_expression_parens','parser.py',49), - ('expression -> expression logical expression','expression',3,'p_expression_logical','parser.py',55), - ('expression -> name comparison_number number','expression',3,'p_expression_comparison','parser.py',61), - ('expression -> name comparison_string string','expression',3,'p_expression_comparison','parser.py',62), - ('expression -> name comparison_equality boolean_value','expression',3,'p_expression_comparison','parser.py',63), - ('expression -> name comparison_equality none','expression',3,'p_expression_comparison','parser.py',64), - ('expression -> name comparison_in_list const_list_value','expression',3,'p_expression_comparison','parser.py',65), - ('name -> NAME','name',1,'p_name','parser.py',71), - ('logical -> AND','logical',1,'p_logical','parser.py',77), - ('logical -> OR','logical',1,'p_logical','parser.py',78), - ('comparison_number -> comparison_equality','comparison_number',1,'p_comparison_number','parser.py',84), - ('comparison_number -> comparison_greater_less','comparison_number',1,'p_comparison_number','parser.py',85), - ('comparison_string -> comparison_equality','comparison_string',1,'p_comparison_string','parser.py',91), - ('comparison_string -> comparison_greater_less','comparison_string',1,'p_comparison_string','parser.py',92), - ('comparison_string -> comparison_contains','comparison_string',1,'p_comparison_string','parser.py',93), - ('comparison_equality -> EQUALS','comparison_equality',1,'p_comparison_equality','parser.py',99), - ('comparison_equality -> NOT_EQUALS','comparison_equality',1,'p_comparison_equality','parser.py',100), - ('comparison_greater_less -> GREATER','comparison_greater_less',1,'p_comparison_greater_less','parser.py',106), - ('comparison_greater_less -> GREATER_EQUAL','comparison_greater_less',1,'p_comparison_greater_less','parser.py',107), - ('comparison_greater_less -> LESS','comparison_greater_less',1,'p_comparison_greater_less','parser.py',108), - ('comparison_greater_less -> LESS_EQUAL','comparison_greater_less',1,'p_comparison_greater_less','parser.py',109), - ('comparison_contains -> CONTAINS','comparison_contains',1,'p_comparison_contains','parser.py',115), - ('comparison_contains -> NOT_CONTAINS','comparison_contains',1,'p_comparison_contains','parser.py',116), - ('comparison_in_list -> IN','comparison_in_list',1,'p_comparison_in_list','parser.py',122), - ('comparison_in_list -> NOT IN','comparison_in_list',2,'p_comparison_in_list','parser.py',123), - ('const_value -> number','const_value',1,'p_const_value','parser.py',132), - ('const_value -> string','const_value',1,'p_const_value','parser.py',133), - ('const_value -> none','const_value',1,'p_const_value','parser.py',134), - ('const_value -> boolean_value','const_value',1,'p_const_value','parser.py',135), - ('number -> INT_VALUE','number',1,'p_number_int','parser.py',141), - ('number -> FLOAT_VALUE','number',1,'p_number_float','parser.py',147), - ('string -> STRING_VALUE','string',1,'p_string','parser.py',153), - ('none -> NONE','none',1,'p_none','parser.py',159), - ('boolean_value -> true','boolean_value',1,'p_boolean_value','parser.py',165), - ('boolean_value -> false','boolean_value',1,'p_boolean_value','parser.py',166), - ('true -> TRUE','true',1,'p_true','parser.py',172), - ('false -> FALSE','false',1,'p_false','parser.py',178), - ('const_list_value -> PAREN_L const_value_list PAREN_R','const_list_value',3,'p_const_list_value','parser.py',184), - ('const_value_list -> const_value_list COMMA const_value','const_value_list',3,'p_const_value_list','parser.py',190), - ('const_value_list -> const_value','const_value_list',1,'p_const_value_list_single','parser.py',196), + ("S' -> query","S'",1,None,None,None), + ('query -> expression','query',1,'p_query','parser.py',54), + ('query -> expression ordering','query',2,'p_ordered_query','parser.py',60), + ('expression -> PAREN_L expression PAREN_R','expression',3,'p_expression_parens','parser.py',66), + ('expression -> expression logical expression','expression',3,'p_expression_logical','parser.py',72), + ('expression -> name comparison_number number','expression',3,'p_expression_comparison','parser.py',78), + ('expression -> name comparison_string string','expression',3,'p_expression_comparison','parser.py',79), + ('expression -> name comparison_equality boolean_value','expression',3,'p_expression_comparison','parser.py',80), + ('expression -> name comparison_equality none','expression',3,'p_expression_comparison','parser.py',81), + ('expression -> name comparison_in_list const_list_value','expression',3,'p_expression_comparison','parser.py',82), + ('name -> NAME','name',1,'p_name','parser.py',88), + ('logical -> AND','logical',1,'p_logical','parser.py',94), + ('logical -> OR','logical',1,'p_logical','parser.py',95), + ('comparison_number -> comparison_equality','comparison_number',1,'p_comparison_number','parser.py',101), + ('comparison_number -> comparison_greater_less','comparison_number',1,'p_comparison_number','parser.py',102), + ('comparison_string -> comparison_equality','comparison_string',1,'p_comparison_string','parser.py',108), + ('comparison_string -> comparison_greater_less','comparison_string',1,'p_comparison_string','parser.py',109), + ('comparison_string -> comparison_string_specific','comparison_string',1,'p_comparison_string','parser.py',110), + ('comparison_equality -> EQUALS','comparison_equality',1,'p_comparison_equality','parser.py',116), + ('comparison_equality -> NOT_EQUALS','comparison_equality',1,'p_comparison_equality','parser.py',117), + ('comparison_greater_less -> GREATER','comparison_greater_less',1,'p_comparison_greater_less','parser.py',123), + ('comparison_greater_less -> GREATER_EQUAL','comparison_greater_less',1,'p_comparison_greater_less','parser.py',124), + ('comparison_greater_less -> LESS','comparison_greater_less',1,'p_comparison_greater_less','parser.py',125), + ('comparison_greater_less -> LESS_EQUAL','comparison_greater_less',1,'p_comparison_greater_less','parser.py',126), + ('comparison_string_specific -> CONTAINS','comparison_string_specific',1,'p_comparison_string_specific','parser.py',132), + ('comparison_string_specific -> NOT_CONTAINS','comparison_string_specific',1,'p_comparison_string_specific','parser.py',133), + ('comparison_string_specific -> STARTSWITH','comparison_string_specific',1,'p_comparison_string_specific','parser.py',134), + ('comparison_string_specific -> NOT STARTSWITH','comparison_string_specific',2,'p_comparison_string_specific','parser.py',135), + ('comparison_string_specific -> ENDSWITH','comparison_string_specific',1,'p_comparison_string_specific','parser.py',136), + ('comparison_string_specific -> NOT ENDSWITH','comparison_string_specific',2,'p_comparison_string_specific','parser.py',137), + ('comparison_in_list -> IN','comparison_in_list',1,'p_comparison_in_list','parser.py',146), + ('comparison_in_list -> NOT IN','comparison_in_list',2,'p_comparison_in_list','parser.py',147), + ('ordering_key -> name','ordering_key',1,'p_undirected_ordering_key','parser.py',156), + ('ordering_key -> name ASC','ordering_key',2,'p_directed_ordering_key','parser.py',162), + ('ordering_key -> name DESC','ordering_key',2,'p_directed_ordering_key','parser.py',163), + ('ordering_key_list -> ordering_key','ordering_key_list',1,'p_ordering_key_list_single','parser.py',169), + ('ordering_key_list -> ordering_key_list COMMA ordering_key','ordering_key_list',3,'p_ordering_key_list','parser.py',175), + ('ordering -> ORDER BY ordering_key_list','ordering',3,'p_ordering','parser.py',181), + ('const_value -> number','const_value',1,'p_const_value','parser.py',187), + ('const_value -> string','const_value',1,'p_const_value','parser.py',188), + ('const_value -> none','const_value',1,'p_const_value','parser.py',189), + ('const_value -> boolean_value','const_value',1,'p_const_value','parser.py',190), + ('number -> INT_VALUE','number',1,'p_number_int','parser.py',196), + ('number -> FLOAT_VALUE','number',1,'p_number_float','parser.py',202), + ('string -> STRING_VALUE','string',1,'p_string','parser.py',208), + ('none -> NONE','none',1,'p_none','parser.py',214), + ('boolean_value -> true','boolean_value',1,'p_boolean_value','parser.py',220), + ('boolean_value -> false','boolean_value',1,'p_boolean_value','parser.py',221), + ('true -> TRUE','true',1,'p_true','parser.py',227), + ('false -> FALSE','false',1,'p_false','parser.py',233), + ('const_list_value -> PAREN_L const_value_list PAREN_R','const_list_value',3,'p_const_list_value','parser.py',239), + ('const_value_list -> const_value_list COMMA const_value','const_value_list',3,'p_const_value_list','parser.py',245), + ('const_value_list -> const_value','const_value_list',1,'p_const_value_list_single','parser.py',251), ] diff --git a/djangoql/queryset.py b/djangoql/queryset.py index 1ee7d31..77c6ea8 100644 --- a/djangoql/queryset.py +++ b/djangoql/queryset.py @@ -29,6 +29,17 @@ def build_filter(expr, schema_instance): ) +def build_order_by(expr): + ordering = expr.ordering + keys = [] + for field in ordering.fields if ordering else []: + key = '__'.join(field.name.parts) + if field.direction == 'desc': + key = f'-{key}' + keys.append(key) + return keys + + def apply_search(queryset, search, schema=None): """ Applies search written in DjangoQL mini-language to given queryset @@ -37,7 +48,11 @@ def apply_search(queryset, search, schema=None): schema = schema or DjangoQLSchema schema_instance = schema(queryset.model) schema_instance.validate(ast) - return queryset.filter(build_filter(ast, schema_instance)) + if ast.expression: + queryset = queryset.filter( + build_filter(ast.expression, schema_instance) + ) + return queryset.order_by(*build_order_by(ast)) class DjangoQLQuerySet(QuerySet): diff --git a/djangoql/schema.py b/djangoql/schema.py index 6af9982..0ac70fb 100644 --- a/djangoql/schema.py +++ b/djangoql/schema.py @@ -11,7 +11,8 @@ from django.db.models.fields.related import ForeignObjectRel from django.utils.timezone import get_current_timezone -from .ast import Comparison, Const, List, Logical, Name, Node +from .ast import Comparison, Const, Expression, List, Logical, Name, Ordering, \ + Query from .compat import text_type from .exceptions import DjangoQLSchemaError @@ -200,7 +201,6 @@ def get_options(self, search): lookup['%s__icontains' % self.name] = search return self.model.objects\ .filter(**lookup)\ - .order_by(self.name)\ .values_list(self.name, flat=True)\ .distinct() @@ -468,10 +468,18 @@ def validate(self, node): """ Validate DjangoQL AST tree vs. current schema """ - assert isinstance(node, Node) + assert isinstance(node, Query) + if node.expression: + self.validate_expression(node.expression) + if node.ordering: + self.validate_ordering(node.ordering) + + def validate_expression(self, node): + assert isinstance(node, Expression) + if isinstance(node.operator, Logical): - self.validate(node.left) - self.validate(node.right) + self.validate_expression(node.left) + self.validate_expression(node.right) return assert isinstance(node.left, Name) assert isinstance(node.operator, Comparison) @@ -490,3 +498,7 @@ def validate(self, node): values = value if isinstance(node.right, List) else [value] for v in values: field.validate(v) + + def validate_ordering(self, ordering: Ordering): + for field in ordering.fields: + self.resolve_name(field.name) diff --git a/test_project/core/admin.py b/test_project/core/admin.py index f46dc26..1b9fb4d 100644 --- a/test_project/core/admin.py +++ b/test_project/core/admin.py @@ -27,7 +27,6 @@ def get_options(self, search): return Book.objects\ .filter(author__username__icontains=search)\ .values_list('author__username', flat=True)\ - .order_by('author__username')\ .distinct() diff --git a/test_project/core/tests/test_lexer.py b/test_project/core/tests/test_lexer.py index 30e1fc3..2b632d5 100644 --- a/test_project/core/tests/test_lexer.py +++ b/test_project/core/tests/test_lexer.py @@ -54,7 +54,7 @@ def test_entity_props(self): def test_reserved_words(self): reserved = ('True', 'False', 'None', 'or', 'and', 'in', 'not', - 'startswith', 'endswith') + 'startswith', 'endswith', 'order', 'by', 'asc', 'desc') for word in reserved: self.assert_output(self.lexer.input(word), [(word.upper(), word)]) # A word made of reserved words should be treated as a name diff --git a/test_project/core/tests/test_parser.py b/test_project/core/tests/test_parser.py index 3cf604c..d24fbbb 100644 --- a/test_project/core/tests/test_parser.py +++ b/test_project/core/tests/test_parser.py @@ -2,7 +2,8 @@ import unittest.util from unittest import TestCase -from djangoql.ast import Comparison, Const, Expression, List, Logical, Name +from djangoql.ast import Comparison, Const, Expression, List, Logical, Name, \ + Ordering, OrderingKey, Query from djangoql.exceptions import DjangoQLParserError from djangoql.parser import DjangoQLParser @@ -17,76 +18,80 @@ class DjangoQLParseTest(TestCase): def test_comparisons(self): self.assertEqual( Expression(Name('age'), Comparison('>='), Const(18)), - self.parser.parse('age >= 18'), + self.parser.parse('age >= 18').expression, ) self.assertEqual( Expression(Name('gender'), Comparison('='), Const('female')), - self.parser.parse('gender = "female"'), + self.parser.parse('gender = "female"').expression, ) self.assertEqual( Expression(Name('name'), Comparison('!='), Const('Gennady')), - self.parser.parse('name != "Gennady"'), + self.parser.parse('name != "Gennady"').expression, ) self.assertEqual( Expression(Name('married'), Comparison('in'), List([Const(True), Const(False)])), - self.parser.parse('married in (True, False)'), + self.parser.parse('married in (True, False)').expression, ) self.assertEqual( Expression(Name('smile'), Comparison('!='), Const(None)), - self.parser.parse('(smile != None)'), + self.parser.parse('(smile != None)').expression, ) self.assertEqual( Expression(Name(['job', 'best', 'title']), Comparison('>'), Const('none')), - self.parser.parse('job.best.title > "none"'), + self.parser.parse('job.best.title > "none"').expression, ) def test_string_comparisons(self): self.assertEqual( Expression(Name('name'), Comparison('~'), Const('gav')), - self.parser.parse('name ~ "gav"'), + self.parser.parse('name ~ "gav"').expression, ) self.assertEqual( Expression(Name('name'), Comparison('!~'), Const('gav')), - self.parser.parse('name !~ "gav"'), + self.parser.parse('name !~ "gav"').expression, ) self.assertEqual( Expression(Name('name'), Comparison('startswith'), Const('gav')), - self.parser.parse('name startswith "gav"'), + self.parser.parse('name startswith "gav"').expression, ) self.assertEqual( Expression(Name('name'), Comparison('not startswith'), Const('rr')), - self.parser.parse('name not startswith "rr"'), + self.parser.parse('name not startswith "rr"').expression, ) self.assertEqual( Expression(Name('name'), Comparison('endswith'), Const('gav')), - self.parser.parse('name endswith "gav"'), + self.parser.parse('name endswith "gav"').expression, ) self.assertEqual( Expression(Name('name'), Comparison('not endswith'), Const('gav')), - self.parser.parse('name not endswith "gav"'), + self.parser.parse('name not endswith "gav"').expression, ) def test_escaped_chars(self): self.assertEqual( Expression(Name('name'), Comparison('~'), Const(u'Contains a "quoted" str, 年年有余')), - self.parser.parse(u'name ~ "Contains a \\"quoted\\" str, 年年有余"'), + self.parser.parse( + u'name ~ "Contains a \\"quoted\\" str, 年年有余"' + ).expression, ) self.assertEqual( Expression(Name('options'), Comparison('='), Const(u'П и Щ')), - self.parser.parse(u'options = "\\u041f \\u0438 \\u0429"'), + self.parser.parse( + u'options = "\\u041f \\u0438 \\u0429"' + ).expression, ) def test_numbers(self): self.assertEqual( Expression(Name('pk'), Comparison('>'), Const(5)), - self.parser.parse('pk > 5'), + self.parser.parse('pk > 5').expression, ) self.assertEqual( Expression(Name('rating'), Comparison('<='), Const(523)), - self.parser.parse('rating <= 5.23e2'), + self.parser.parse('rating <= 5.23e2').expression, ) def test_logical(self): @@ -96,7 +101,7 @@ def test_logical(self): Logical('and'), Expression(Name('age'), Comparison('<='), Const(45)), ), - self.parser.parse('age >= 18 and age <= 45'), + self.parser.parse('age >= 18 and age <= 45').expression, ) self.assertEqual( Expression( @@ -113,7 +118,7 @@ def test_logical(self): ), ), self.parser.parse('(city = "Ivanovo" and age <= 35) or ' - '(city = "Paris" and age <= 45)'), + '(city = "Paris" and age <= 45)').expression, ) def test_invalid_comparison(self): @@ -134,5 +139,42 @@ def test_entity_props(self): self.assertEqual( Expression(Name(['user', 'group', 'id']), Comparison('='), Const(5)), - self.parser.parse('user.group.id = 5'), + self.parser.parse('user.group.id = 5').expression, + ) + + def test_ordering(self): + self.assertEqual( + Query( + Expression(Name(['user', 'group']), + Comparison('='), Const("admin")), + ordering=Ordering( + keys=[OrderingKey(name=Name(['user', 'name']), + direction=None)] + ), + ), + self.parser.parse('user.group = "admin" order by user.name'), + ) + + self.assertEqual( + Query( + expression=None, + ordering=Ordering( + keys=[OrderingKey(name=Name(['user', 'name']), + direction=None)] + ), + ), + self.parser.parse('order by user.name'), + ) + + self.assertEqual( + Query( + Expression(Name(['title']), Comparison('~'), Const("short")), + ordering=Ordering( + keys=[ + OrderingKey(name=Name(['published']), direction='desc'), + OrderingKey(name=Name(['title']), direction=None), + ] + ), + ), + self.parser.parse('title ~ "short" order by published desc, title'), ) diff --git a/test_project/core/tests/test_queryset.py b/test_project/core/tests/test_queryset.py index 5921e4a..920a665 100644 --- a/test_project/core/tests/test_queryset.py +++ b/test_project/core/tests/test_queryset.py @@ -111,3 +111,21 @@ def test_empty_datetime(self): qs = apply_search(User.objects.all(), 'last_login = None') where_clause = str(qs.query).split('WHERE')[1].strip() self.assertEqual('"auth_user"."last_login" IS NULL', where_clause) + + def test_simple_ordering(self): + qs = apply_search(User.objects.all(), + 'last_login = None order by username desc') + order_by_clause = str(qs.query).split('ORDER BY')[1].strip() + self.assertEqual('"auth_user"."username" DESC', order_by_clause) + + qs = apply_search(User.objects.all(), + 'last_login = None order by username') + order_by_clause = str(qs.query).split('ORDER BY')[1].strip() + self.assertEqual('"auth_user"."username" ASC', order_by_clause) + + def test_ordering_by_multiple_keys(self): + qs = apply_search(User.objects.all(), + 'order by last_name desc, book.name') + order_by_clause = str(qs.query).split('ORDER BY')[1].strip() + self.assertEqual('"auth_user"."last_name" DESC, ' + '"core_book"."name" ASC', order_by_clause) diff --git a/test_project/test_project/settings.py b/test_project/test_project/settings.py index 2a8057b..cbaf929 100644 --- a/test_project/test_project/settings.py +++ b/test_project/test_project/settings.py @@ -134,3 +134,26 @@ # https://docs.djangoproject.com/en/1.10/howto/static-files/ STATIC_URL = '/static/' + + +LOGGING = { + 'version': 1, + 'filters': { + 'require_debug_true': { + '()': 'django.utils.log.RequireDebugTrue', + } + }, + 'handlers': { + 'console': { + 'level': 'DEBUG', + 'filters': ['require_debug_true'], + 'class': 'logging.StreamHandler', + } + }, + 'loggers': { + 'django.db.backends': { + 'level': 'DEBUG', + 'handlers': ['console'], + } + } +} From fe8aba11a9ad1cd851ba9d207a9e6d94b090cc92 Mon Sep 17 00:00:00 2001 From: Georgy Frolov Date: Wed, 11 May 2022 08:04:24 +0300 Subject: [PATCH 2/3] Use default ordering when ORDER BY is not applied --- README.rst | 2 -- djangoql/admin.py | 7 ++++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 78ae76b..1bc2d71 100644 --- a/README.rst +++ b/README.rst @@ -113,8 +113,6 @@ also an option that controls if that checkbox is enabled by default - If you don't want two search modes, simply remove ``search_fields`` from your ModelAdmin class. -Note that ``DjangoSQLSearchMixin`` overwrites the ``ordering`` field -of your view. Language reference ------------------ diff --git a/djangoql/admin.py b/djangoql/admin.py index 4a25563..0266453 100644 --- a/djangoql/admin.py +++ b/djangoql/admin.py @@ -43,10 +43,15 @@ def get_filters_params(self, *args, **kwargs): del params[DJANGOQL_SEARCH_MARKER] return params + def get_ordering(self, request, queryset): + if queryset.ordered: + return queryset.query.order_by + else: + return super().get_ordering(request, queryset) + class DjangoQLSearchMixin(object): search_fields = ('_djangoql',) # just a stub to have search input displayed - ordering = () djangoql_completion = True djangoql_completion_enabled_by_default = True djangoql_schema = DjangoQLSchema From 570cb2ace980843a9883812d0884eb56bf3f16d5 Mon Sep 17 00:00:00 2001 From: Georgy Frolov Date: Thu, 12 May 2022 18:25:34 +0300 Subject: [PATCH 3/3] lint --- djangoql/queryset.py | 2 +- .../static/djangoql/css/completion.css.map | 2 +- djangoql/static/djangoql/js/completion.js | 2 +- djangoql/static/djangoql/js/completion.js.map | 2 +- test_project/core/tests/test_parser.py | 14 +++++------ test_project/test_project/settings.py | 23 ------------------- 6 files changed, 11 insertions(+), 34 deletions(-) diff --git a/djangoql/queryset.py b/djangoql/queryset.py index 77c6ea8..7b6c9f2 100644 --- a/djangoql/queryset.py +++ b/djangoql/queryset.py @@ -50,7 +50,7 @@ def apply_search(queryset, search, schema=None): schema_instance.validate(ast) if ast.expression: queryset = queryset.filter( - build_filter(ast.expression, schema_instance) + build_filter(ast.expression, schema_instance), ) return queryset.order_by(*build_order_by(ast)) diff --git a/djangoql/static/djangoql/css/completion.css.map b/djangoql/static/djangoql/css/completion.css.map index 194c015..97bb47a 100644 --- a/djangoql/static/djangoql/css/completion.css.map +++ b/djangoql/static/djangoql/css/completion.css.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///./node_modules/djangoql-completion/dist/completion.css"],"names":[],"mappings":"AAAA;EACE,kBAAkB;EAClB,aAAa;EACb,sBAAsB;EACtB,kBAAkB;EAClB,iBAAiB;EACjB,iCAAiC;EACjC,gBAAgB;EAChB,eAAe;AACjB;;AAEA;EACE,yBAAyB;EACzB,YAAY;AACd;;AAEA;EACE,cAAc;EACd,SAAS;EACT,iBAAiB;EACjB,cAAc;AAChB;;AAEA;EACE,gBAAgB;EAChB,iBAAiB;EACjB,eAAe;AACjB;;AAEA;EACE,yBAAyB;EACzB,YAAY;AACd;;AAEA;EACE,gBAAgB;EAChB,WAAW;EACX,YAAY;EACZ,kBAAkB;AACpB;;AAEA;EACE,0BAA0B;EAC1B,SAAS;EACT,0BAA0B;EAC1B,kBAAkB;AACpB;;AAEA;;CAEC;AACD;EACE,cAAc;EACd,kBAAkB;AACpB;;AAEA;EACE,qDAAqD;EACrD,oDAAoD;EACpD,wDAAwD;EACxD,gDAAgD;EAChD,sBAAsB;EACtB,+CAA+C;EAC/C,kBAAkB;EAClB,YAAY;EACZ,cAAc;EACd,YAAY;EACZ,SAAS;EACT,YAAY;EACZ,kBAAkB;EAClB,QAAQ;EACR,WAAW;AACb;;AAEA;EACE;IACE,uBAAuB;EACzB;EACA;IACE,yBAAyB;EAC3B;AACF","file":"css/completion.css","sourcesContent":[".djangoql-completion {\n position: absolute;\n display: none;\n border: solid 1px #ccc;\n border-radius: 4px;\n background: white;\n background: var(--body-bg, white);\n min-width: 183px;\n font-size: 13px;\n}\n\n.djangoql-completion .active {\n background-color: #79aec8;\n color: white;\n}\n\n.djangoql-completion ul {\n padding: 2px 0;\n margin: 0;\n max-height: 295px;\n overflow: auto;\n}\n\n.djangoql-completion li {\n list-style: none;\n padding: 4px 10px;\n cursor: pointer;\n}\n\n.djangoql-completion li:hover {\n background-color: #c4e9fa;\n color: black;\n}\n\n.djangoql-completion li i {\n font-size: 0.9em;\n color: #ccc;\n float: right;\n font-style: normal;\n}\n\n.djangoql-completion .syntax-help {\n padding: 4px 10px 6px 10px;\n margin: 0;\n border-top: solid 1px #ccc;\n font-size: inherit;\n}\n\n/*\nPure CSS loading icon. Credit: https://loading.io/css/\n*/\n.djangoql-loading {\n display: block;\n position: relative;\n}\n\n.djangoql-loading:after {\n -moz-animation: djangoql-loading 1.2s linear infinite;\n -ms-animation: djangoql-loading 1.2s linear infinite;\n -webkit-animation: djangoql-loading 1.2s linear infinite;\n animation: djangoql-loading 1.2s linear infinite;\n border: 2px solid #aaa;\n border-color: #aaa transparent #aaa transparent;\n border-radius: 50%;\n content: \" \";\n display: block;\n height: 12px;\n left: 50%;\n margin: -8px;\n position: absolute;\n top: 50%;\n width: 12px;\n}\n\n@keyframes djangoql-loading {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"css/completion.css","mappings":"AAAA;EACE,kBAAkB;EAClB,aAAa;EACb,sBAAsB;EACtB,kBAAkB;EAClB,iBAAiB;EACjB,iCAAiC;EACjC,gBAAgB;EAChB,eAAe;AACjB;;AAEA;EACE,yBAAyB;EACzB,YAAY;AACd;;AAEA;EACE,cAAc;EACd,SAAS;EACT,iBAAiB;EACjB,cAAc;AAChB;;AAEA;EACE,gBAAgB;EAChB,iBAAiB;EACjB,eAAe;AACjB;;AAEA;EACE,yBAAyB;EACzB,YAAY;AACd;;AAEA;EACE,gBAAgB;EAChB,WAAW;EACX,YAAY;EACZ,kBAAkB;AACpB;;AAEA;EACE,0BAA0B;EAC1B,SAAS;EACT,0BAA0B;EAC1B,kBAAkB;AACpB;;AAEA;;CAEC;AACD;EACE,cAAc;EACd,kBAAkB;AACpB;;AAEA;EACE,qDAAqD;EACrD,oDAAoD;EACpD,wDAAwD;EACxD,gDAAgD;EAChD,sBAAsB;EACtB,+CAA+C;EAC/C,kBAAkB;EAClB,YAAY;EACZ,cAAc;EACd,YAAY;EACZ,SAAS;EACT,YAAY;EACZ,kBAAkB;EAClB,QAAQ;EACR,WAAW;AACb;;AAEA;EACE;IACE,uBAAuB;EACzB;EACA;IACE,yBAAyB;EAC3B;AACF","sources":["webpack:///../djangoql-completion/dist/completion.css"],"sourcesContent":[".djangoql-completion {\n position: absolute;\n display: none;\n border: solid 1px #ccc;\n border-radius: 4px;\n background: white;\n background: var(--body-bg, white);\n min-width: 183px;\n font-size: 13px;\n}\n\n.djangoql-completion .active {\n background-color: #79aec8;\n color: white;\n}\n\n.djangoql-completion ul {\n padding: 2px 0;\n margin: 0;\n max-height: 295px;\n overflow: auto;\n}\n\n.djangoql-completion li {\n list-style: none;\n padding: 4px 10px;\n cursor: pointer;\n}\n\n.djangoql-completion li:hover {\n background-color: #c4e9fa;\n color: black;\n}\n\n.djangoql-completion li i {\n font-size: 0.9em;\n color: #ccc;\n float: right;\n font-style: normal;\n}\n\n.djangoql-completion .syntax-help {\n padding: 4px 10px 6px 10px;\n margin: 0;\n border-top: solid 1px #ccc;\n font-size: inherit;\n}\n\n/*\nPure CSS loading icon. Credit: https://loading.io/css/\n*/\n.djangoql-loading {\n display: block;\n position: relative;\n}\n\n.djangoql-loading:after {\n -moz-animation: djangoql-loading 1.2s linear infinite;\n -ms-animation: djangoql-loading 1.2s linear infinite;\n -webkit-animation: djangoql-loading 1.2s linear infinite;\n animation: djangoql-loading 1.2s linear infinite;\n border: 2px solid #aaa;\n border-color: #aaa transparent #aaa transparent;\n border-radius: 50%;\n content: \" \";\n display: block;\n height: 12px;\n left: 50%;\n margin: -8px;\n position: absolute;\n top: 50%;\n width: 12px;\n}\n\n@keyframes djangoql-loading {\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n}\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/djangoql/static/djangoql/js/completion.js b/djangoql/static/djangoql/js/completion.js index 8a5c122..6405b33 100644 --- a/djangoql/static/djangoql/js/completion.js +++ b/djangoql/static/djangoql/js/completion.js @@ -1,2 +1,2 @@ -!function(){var t={57:function(t,e,n){function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function o(t){"function"!=typeof t&&(t=o.defunct);var e=[],n=[],i=0;function s(){for(var t=[],e=0,i=this.state,o=this.index,s=this.input,r=0,l=n.length;r=0||i%2&&1===u&&!c[0]){var h=a.pattern;h.lastIndex=o;var p=h.exec(s);if(p&&p.index===o){var d=t.push({result:p,action:a.action,length:p[0].length});for(a.global&&(e=d);--d>e;){var f=d-1;if(t[d].length>t[f].length){var m=t[d];t[d]=t[f],t[f]=m}}}}}return t}this.state=0,this.index=0,this.input="",this.addRule=function(t,e,i){var o=t.global;if(!o){var s="g";t.multiline&&(s+="m"),t.ignoreCase&&(s+="i"),t=new RegExp(t.source,s)}return"[object Array]"!==Object.prototype.toString.call(i)&&(i=[0]),n.push({pattern:t,global:o,action:e,start:i}),this},this.setInput=function(t){return i=0,this.state=0,this.index=0,e.length=0,this.input=t,this},this.lex=function(){if(e.length)return e.shift();for(this.reject=!0;this.index<=this.input.length;){for(var n=s.call(this).splice(i),o=this.index;n.length&&this.reject;){var r=n.shift(),l=r.result,a=r.length;this.index+=a,this.reject=!1,i++;var c=r.action.apply(this,l);if(this.reject)this.index=l.index;else if(void 0!==c)switch(Object.prototype.toString.call(c)){case"[object Array]":e=c.slice(1),c=c[0];default:return a&&(i=0),c}}var u=this.input;if(o=e||n<0||g&&t-f>=u}function w(){var t=o();if(x(t))return S(t);p=setTimeout(w,function(t){var n=e-(t-d);return g?l(n,u-(t-f)):n}(t))}function S(t){return p=void 0,y&&a?v(t):(a=c=void 0,h)}function E(){var t=o(),n=x(t);if(a=arguments,c=this,d=t,n){if(void 0===p)return b(d);if(g)return clearTimeout(p),p=setTimeout(w,e),v(d)}return void 0===p&&(p=setTimeout(w,e)),h}return e=s(e)||0,i(n)&&(m=!!n.leading,u=(g="maxWait"in n)?r(s(n.maxWait)||0,e):u,y="trailing"in n?!!n.trailing:y),E.cancel=function(){void 0!==p&&clearTimeout(p),f=0,a=d=c=p=void 0},E.flush=function(){return void 0===p?h:S(o())},E}},716:function(t){function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}t.exports=function(t){var n=e(t);return null!=t&&("object"==n||"function"==n)}},667:function(t){function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}t.exports=function(t){return null!=t&&"object"==e(t)}},570:function(t,e,n){function i(t){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var o=n(807),s=n(667);t.exports=function(t){return"symbol"==i(t)||s(t)&&"[object Symbol]"==o(t)}},244:function(t,e,n){var i=n(366);t.exports=function(){return i.Date.now()}},167:function(t,e,n){var i=n(645),o=n(716);t.exports=function(t,e,n){var s=!0,r=!0;if("function"!=typeof t)throw new TypeError("Expected a function");return o(n)&&(s="leading"in n?!!n.leading:s,r="trailing"in n?!!n.trailing:r),i(t,e,{leading:s,maxWait:e,trailing:r})}},666:function(t,e,n){var i=n(182),o=n(716),s=n(570),r=/^[-+]0x[0-9a-f]+$/i,l=/^0b[01]+$/i,a=/^0o[0-7]+$/i,c=parseInt;t.exports=function(t){if("number"==typeof t)return t;if(s(t))return NaN;if(o(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=o(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=i(t);var n=l.test(t);return n||a.test(t)?c(t.slice(2),n?2:8):r.test(t)?NaN:+t}}},e={};function n(i){var o=e[i];if(void 0!==o)return o.exports;var s=e[i]={id:i,loaded:!1,exports:{}};return t[i](s,s.exports,n),s.loaded=!0,s.exports}n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,{a:e}),e},n.d=function(t,e){for(var i in e)n.o(e,i)&&!n.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.nmd=function(t){return t.paths=[],t.children||(t.children=[]),t},function(){"use strict";var t=n(57),e=n.n(t),i=n(645),o=n.n(i),s=n(716),r=n.n(s),l=n(167),a=n.n(l);function c(t){return(c="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function u(t){this.size=0,this.limit=t,this.oldest=this.newest=void 0,this._keymap={}}u.prototype._markEntryAsUsed=function(t){t!==this.newest&&(t.newer&&(t===this.oldest&&(this.oldest=t.newer),t.newer.older=t.older),t.older&&(t.older.newer=t.newer),t.newer=void 0,t.older=this.newest,this.newest&&(this.newest.newer=t),this.newest=t)},u.prototype.put=function(t,e){var n=this._keymap[t];return n?(n.value=e,void this._markEntryAsUsed(n)):(this._keymap[t]=n={key:t,value:e,older:void 0,newer:void 0},this.newest?(this.newest.newer=n,n.older=this.newest):this.oldest=n,this.newest=n,this.size++,this.size>this.limit?this.shift():void 0)},u.prototype.shift=function(){var t=this.oldest;return t&&(this.oldest.newer?(this.oldest=this.oldest.newer,this.oldest.older=void 0):(this.oldest=void 0,this.newest=void 0),t.newer=t.older=void 0,delete this._keymap[t.key],this.size--),t},u.prototype.get=function(t,e){var n=this._keymap[t];if(void 0!==n)return this._markEntryAsUsed(n),e?n:n.value},u.prototype.find=function(t){return this._keymap[t]},u.prototype.set=function(t,e){var n,i=this.get(t,!0);return i?(n=i.value,i.value=e):(n=this.put(t,e))&&(n=n.value),n},u.prototype.remove=function(t){var e=this._keymap[t];if(e)return delete this._keymap[e.key],e.newer&&e.older?(e.older.newer=e.newer,e.newer.older=e.older):e.newer?(e.newer.older=void 0,this.oldest=e.newer):e.older?(e.older.newer=void 0,this.newest=e.older):this.oldest=this.newest=void 0,this.size--,e.value},u.prototype.removeAll=function(){this.oldest=this.newest=void 0,this.size=0,this._keymap={}},"function"==typeof Object.keys?u.prototype.keys=function(){return Object.keys(this._keymap)}:u.prototype.keys=function(){var t=[];for(var e in this._keymap)t.push(e);return t},u.prototype.forEach=function(t,e,n){var i;if(!0===e?(n=!0,e=void 0):"object"!==c(e)&&(e=this),n)for(i=this.newest;i;)t.call(e,i.key,i.value,this),i=i.older;else for(i=this.oldest;i;)t.call(e,i.key,i.value,this),i=i.newer},u.prototype.toJSON=function(){for(var t=new Array(this.size),e=0,n=this.oldest;n;)t[e++]={key:n.key,value:n.value},n=n.newer;return t},u.prototype.toString=function(){for(var t="",e=this.oldest;e;)t+=String(e.key)+":"+e.value,(e=e.newer)&&(t+=" < ");return t};var h=u;function p(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function d(t){for(var e=1;et.length)&&(e=t.length);for(var n=0,i=new Array(e);n".concat(i,"")),{text:t,snippetBefore:e||"",snippetAfter:n||"",suggestionText:o}}O.addRule(C,(function(){})),O.addRule(/\./,(function(t){return R("DOT",t)})),O.addRule(/,/,(function(t){return R("COMMA",t)})),O.addRule(new RegExp("or".concat(E)),(function(t){return R("OR",t)})),O.addRule(new RegExp("and".concat(E)),(function(t){return R("AND",t)})),O.addRule(new RegExp("not".concat(E)),(function(t){return R("NOT",t)})),O.addRule(new RegExp("in".concat(E)),(function(t){return R("IN",t)})),O.addRule(new RegExp("startswith".concat(E)),(function(t){return R("STARTSWITH",t)})),O.addRule(new RegExp("endswith".concat(E)),(function(t){return R("ENDSWITH",t)})),O.addRule(new RegExp("True".concat(E)),(function(t){return R("TRUE",t)})),O.addRule(new RegExp("False".concat(E)),(function(t){return R("FALSE",t)})),O.addRule(new RegExp("None".concat(E)),(function(t){return R("NONE",t)})),O.addRule(/[_A-Za-z][_0-9A-Za-z]*(\.[_A-Za-z][_0-9A-Za-z]*)*/,(function(t){return R("NAME",t)})),O.addRule(S,(function(t){return R("STRING_VALUE",t.slice(1,t.length-1))})),O.addRule(b,(function(t){return R("INT_VALUE",t)})),O.addRule(x,(function(t){return R("FLOAT_VALUE",t)})),O.addRule(/\(/,(function(t){return R("PAREN_L",t)})),O.addRule(/\)/,(function(t){return R("PAREN_R",t)})),O.addRule(/=/,(function(t){return R("EQUALS",t)})),O.addRule(/!=/,(function(t){return R("NOT_EQUALS",t)})),O.addRule(/>/,(function(t){return R("GREATER",t)})),O.addRule(/>=/,(function(t){return R("GREATER_EQUAL",t)})),O.addRule(/ element, "+"but ".concat(this.textarea.tagName," was found")):this.logError("Element not found by selector: ".concat(t.selector))):this.logError("Please pass an object with initialization parameters")};j.init=function(t){return new j(t)},j.DOMReady=function(t){"loading"!==document.readyState?t():document.addEventListener("DOMContentLoaded",t)},j.prototype={createCompletionElement:function(){var t,e=this.options;this.completion||(this.completion=document.createElement("div"),this.completion.className="djangoql-completion",document.querySelector("body").appendChild(this.completion),this.completionUL=document.createElement("ul"),this.completionUL.onscroll=a()(this.onCompletionScroll.bind(this),50),this.completion.appendChild(this.completionUL),"string"==typeof e.syntaxHelp&&((t=document.createElement("p")).className="syntax-help",t.innerHTML='Syntax Help',t.addEventListener("mousedown",(function(t){t.preventDefault()})),this.completion.appendChild(t)),this.completionEnabled=!e.hasOwnProperty("completionEnabled")||e.completionEnabled)},destroyCompletionElement:function(){this.completion&&(this.completion.parentNode.removeChild(this.completion),this.completion=null,this.completionEnabled=!1)},enableCompletion:function(){this.completionEnabled=!0},disableCompletion:function(){this.completionEnabled=!1,this.hideCompletion()},getJson:function(t,e){this.loading=!0;var n=function(){this.loading=!1,this.request=null,this.logError("failed to fetch from ".concat(t))}.bind(this);this.request&&this.request.abort(),this.request=new XMLHttpRequest,this.request.open("GET",t,!0),this.request.onload=function(){this.loading=!1,200===this.request.status?"function"==typeof e.success&&e.success(JSON.parse(this.request.responseText)):n(),this.request=null}.bind(this),this.request.ontimeout=n,this.request.onerror=n,this.request.onprogress=function(){},window.setTimeout(this.request.send.bind(this.request))},loadIntrospections:function(t){var e=function(t){this.currentModel=t.current_model,this.models=t.models,this.suggestionsAPIUrl=t.suggestions_api_url}.bind(this);"string"==typeof t?this.getJson(t,{success:e}):r()(t)?e(t):this.logError("introspections parameter is expected to be either URL or "+"object with definitions, but ".concat(t," was found"))},logError:function(t){console.error("DjangoQL: ".concat(t))},onCompletionMouseClick:function(t){this.selectCompletion(parseInt(t.currentTarget.getAttribute("data-index"),10))},onCompletionMouseDown:function(t){t.preventDefault()},onKeydown:function(t){switch(t.keyCode){case 38:this.suggestions.length&&(null===this.selected?this.selected=this.suggestions.length-1:0===this.selected?this.selected=null:this.selected-=1,this.renderCompletion(),t.preventDefault());break;case 40:this.suggestions.length&&(null===this.selected?this.selected=0:this.selected1&&(p=d.join(""),!h&&!u.text)){var f=(c=2,function(t){if(Array.isArray(t))return t}(a=d)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){var i,o,s=[],r=!0,l=!1;try{for(n=n.call(t);!(r=(i=n.next()).done)&&(s.push(i.value),!e||s.length!==e);r=!0);}catch(t){l=!0,o=t}finally{try{r||null==n.return||n.return()}finally{if(l)throw o}}return s}}(a,c)||function(t,e){if(t){if("string"==typeof t)return m(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?m(t,e):void 0}}(a,c)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());h=f[0],p=f[1]}r.endsWith(h)&&(h=""),l.startsWith(p)&&(p="");var g=h+u.text+p,y=r.length+g.length;d.length>1&&(y-=d[1].length),this.textarea.value=r+g+l,this.textarea.focus(),this.textarea.setSelectionRange(y,y),this.selected=null,this.textareaResize&&this.textareaResize(),this.generateSuggestions(this.textarea),this.renderCompletion()},hideCompletion:function(){this.selected=null,this.completion&&(this.completion.style.display="none")},highlight:function(t,e){return e&&t?this.highlightCaseSensitive?t.split(e).join("".concat(e,"")):t.replace(new RegExp("(".concat(e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),")"),"ig"),"$1"):t},renderCompletion:function(t){var e,n,i,o,s,r;if(this.completionEnabled){if(!t||"none"!==this.completion.style.display)if(this.suggestions.length||this.loading){var l=this.suggestions.length,a=[].slice.call(this.completionUL.querySelectorAll("li[data-index]"));for(s=a.length,n=0;ni.bottom?this.completionUL.scrollTop=this.completionUL.scrollTop+2+(o.bottom-i.bottom):o.topl;)a[--s].removeEventListener("click",this.onCompletionMouseClick),a[s].removeEventListener("mousedown",this.onCompletionMouseDown),this.completionUL.removeChild(a[s]);r=this.completionUL.querySelector("li.djangoql-loading"),this.loading?r||((r=document.createElement("li")).className="djangoql-loading",r.innerHTML=" ",this.completionUL.appendChild(r)):r&&this.completionUL.removeChild(r);var c=this.textarea.getBoundingClientRect(),u=window.pageYOffset+c.top+c.height;this.completion.style.top="".concat(u,"px"),this.completion.style.left="".concat(c.left,"px"),this.completion.style.display="block"}else this.hideCompletion()}else this.hideCompletion()},resolveName:function(t){var e,n,i,o=t.split("."),s=this.currentModel,r=null,l=[];if(s)for(l.push(s),n=0,i=o.length;n=e&&(d=p[h.length-1],h.pop()),h.length&&(c=h[h.length-1],h.length>1&&(u=h[h.length-2]));var f=(n=t.slice(c?c.end:0,e)).match(C);f&&(n=n.slice(f[0].length)),"("===n&&(n="");var m=["AND","OR"];return(")"!==n||f)&&(!c||m.indexOf(c.name)>=0&&f||"."===n&&c&&!f||"PAREN_L"===c.name&&(!u||m.indexOf(u.name)>=0)?(s="field",r=this.currentModel,"."===n&&(n=t.slice(c.start,e)),(i=n.split(".")).length>1&&(n=i.pop(),(o=this.resolveName(i.join("."))).model&&!o.field?(r=o.model,a=o.modelStack):(s=null,r=null))):c&&f&&u&&"NAME"===u.name&&["EQUALS","NOT_EQUALS","CONTAINS","NOT_CONTAINS","GREATER_EQUAL","GREATER","LESS_EQUAL","LESS"].indexOf(c.name)>=0?(o=this.resolveName(u.value)).model&&(s="value",r=o.model,l=o.field,a=o.modelStack,'"'!==n[0]||"str"!==this.models[r][l].type&&!this.models[r][l].options||(n=n.slice(1))):c&&f&&"NAME"===c.name?(o=this.resolveName(c.value)).model&&(s="comparison",r=o.model,l=o.field,a=o.modelStack):c&&f&&["PAREN_R","INT_VALUE","FLOAT_VALUE","STRING_VALUE"].indexOf(c.name)>=0&&(s="logical")),{prefix:n,scope:s,model:r,field:l,currentFullToken:d,modelStack:a}},getCurrentFieldOptions:function(){var t=this.textarea,e=this.getContext(t.value,t.selectionStart),n=this.models[e.model],i=e.field&&n[e.field],o={cacheKey:null,context:e,field:i,model:n,options:null};if("value"!==e.scope||!i||!i.options)return null;if(Array.isArray(i.options))o.options=i.options;else if(!0===i.options){if(!this.suggestionsAPIUrl)return null;o.cacheKey="".concat(e.model,".").concat(e.field,"|").concat(e.prefix)}return o},loadFieldOptions:function(t){var e=this.getCurrentFieldOptions()||{},n=e.context;if(e.cacheKey){var i={field:"".concat(n.model,".").concat(n.field),search:n.prefix},o=this.suggestionsCache.get(e.cacheKey)||{};if(t&&o.has_next)i.page=o.page?o.page+1:1;else if(o.page)return;o.loading=!0,this.suggestionsCache.set(e.cacheKey,o);var s,r,l,a,c,u,h,p,f,m,g=(s=this.suggestionsAPIUrl,r=i,p=(h=s.split("?"))[0],f=h.slice(1).join("?"),m=f.split("&"),Object.keys(r).forEach((function(t){for(a=encodeURI(t),c=encodeURI(r[a]),u=m.length;u--;)if((l=m[u].split("="))[0]===a){l[1]=c,m[u]=l.join("=");break}u<0&&m.push("".concat(a,"=").concat(c))})),(f=m.join("&"))?[p,f].join("?"):p);this.getJson(g,{success:function(t){var n=this.suggestionsCache.get(e.cacheKey)||{};if(t.page-1===(n.page||0)){var i=d(d({},t),{},{items:(n.items||[]).concat(t.items)});this.suggestionsCache.set(e.cacheKey,i),this.loading=!1,this.populateFieldOptions(),this.renderCompletion()}}.bind(this)}),this.populateFieldOptions(),this.renderCompletion()}},populateFieldOptions:function(t){var e=this.getCurrentFieldOptions();if(null!==e){var n,i=e.options,o=e.context&&e.context.prefix;if(i)i=this.valuesCaseSensitive?i.filter((function(t){return t.indexOf(o)>=0})):i.filter((function(t){return t.toLowerCase().indexOf(o.toLowerCase())>=0}));else{if(this.suggestions=[],!e.cacheKey)return;if(i=(n=this.suggestionsCache.get(e.cacheKey)||{}).items||[],!n.loading&&(!n.page||t&&n.has_next)&&this.debouncedLoadFieldOptions(t),!i.length)return}this.highlightCaseSensitive=this.valuesCaseSensitive,this.suggestions=i.map((function(t){return A(t,'"','"')}))}},onCompletionScroll:function(){var t=this.completionUL.getBoundingClientRect().height,e=this.completionUL.scrollTop+t;e>t&&e>this.completionUL.scrollHeight-t&&this.populateFieldOptions(!0)},generateSuggestions:function(){var t,e,n,i=this.textarea;if(!this.completionEnabled)return this.prefix="",void(this.suggestions=[]);if(this.currentModel){if(i.selectionStart!==i.selectionEnd)return this.prefix="",void(this.suggestions=[]);n=function(t){return t.text.indexOf(this.prefix)>=0}.bind(this),this.highlightCaseSensitive=!0;var o=this.getContext(i.value,i.selectionStart),s=o.modelStack;this.prefix=o.prefix;var r=this.models[o.model],l=o.field&&r[o.field];switch(o.scope){case"field":this.suggestions=Object.keys(r).filter((function(t){var e=r[t].relation;return"relation"!==r[t].type||!s.includes(e)||s.slice(-1)[0]===e})).map((function(t){return A(t,"","relation"===r[t].type?".":" ")}));break;case"comparison":t=["=",["!=","is not equal to"]],e=" ",l&&"bool"!==l.type&&(["date","datetime"].indexOf(l.type)>=0?(t.push(["~","contains"],["!~","does not contain"]),e=' "|"'):"str"===l.type?(t.push(["~","contains"],["!~","does not contain"],"startswith","not startswith","endswith","not endswith"),e=' "|"'):l.options&&(e=' "|"'),"str"!==l.type&&t.push(">",">=","<","<=")),this.suggestions=t.map((function(t){return"string"==typeof t?A(t,"",e):A(t[0],"",e,t[1])})),l&&"bool"!==l.type&&(e=["str","date","datetime"].indexOf(l.type)>=0||l.options?' ("|")':" (|)",this.suggestions.push(A("in","",e)),this.suggestions.push(A("not in","",e))),n=function(t){return 0===t.text.lastIndexOf(this.prefix,0)}.bind(this);break;case"value":l?l.options?(this.prefix=o.prefix,this.populateFieldOptions()):"bool"===l.type?(this.suggestions=[A("True",""," "),A("False",""," ")],l.nullable&&this.suggestions.push(A("None",""," "))):"unknown"===l.type&&(this.prefix="",this.suggestions=[]):this.suggestions=[A("None",""," ")];break;case"logical":this.suggestions=[A("and",""," "),A("or",""," ")];break;default:this.prefix="",this.suggestions=[]}this.suggestions=this.suggestions.filter(n),1===this.suggestions.length?this.selected=0:this.selected=null}}};var L=j;window.DjangoQL=L}()}(); +!function(){var t={528:function(t,e,n){function i(t){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i(t)}function o(t){"function"!=typeof t&&(t=o.defunct);var e=[],n=[],i=0;function s(){for(var t=[],e=0,i=this.state,o=this.index,s=this.input,r=0,l=n.length;r=0||i%2&&1===c&&!u[0]){var h=a.pattern;h.lastIndex=o;var p=h.exec(s);if(p&&p.index===o){var d=t.push({result:p,action:a.action,length:p[0].length});for(a.global&&(e=d);--d>e;){var f=d-1;if(t[d].length>t[f].length){var m=t[d];t[d]=t[f],t[f]=m}}}}}return t}this.state=0,this.index=0,this.input="",this.addRule=function(t,e,i){var o=t.global;if(!o){var s="g";t.multiline&&(s+="m"),t.ignoreCase&&(s+="i"),t=new RegExp(t.source,s)}return"[object Array]"!==Object.prototype.toString.call(i)&&(i=[0]),n.push({pattern:t,global:o,action:e,start:i}),this},this.setInput=function(t){return i=0,this.state=0,this.index=0,e.length=0,this.input=t,this},this.lex=function(){if(e.length)return e.shift();for(this.reject=!0;this.index<=this.input.length;){for(var n=s.call(this).splice(i),o=this.index;n.length&&this.reject;){var r=n.shift(),l=r.result,a=r.length;this.index+=a,this.reject=!1,i++;var u=r.action.apply(this,l);if(this.reject)this.index=l.index;else if(void 0!==u)return"[object Array]"===Object.prototype.toString.call(u)&&(e=u.slice(1),u=u[0]),a&&(i=0),u}var c=this.input;if(o=e||n<0||g&&t-f>=c}function w(){var t=o();if(x(t))return S(t);p=setTimeout(w,function(t){var n=e-(t-d);return g?l(n,c-(t-f)):n}(t))}function S(t){return p=void 0,y&&a?v(t):(a=u=void 0,h)}function E(){var t=o(),n=x(t);if(a=arguments,u=this,d=t,n){if(void 0===p)return b(d);if(g)return clearTimeout(p),p=setTimeout(w,e),v(d)}return void 0===p&&(p=setTimeout(w,e)),h}return e=s(e)||0,i(n)&&(m=!!n.leading,c=(g="maxWait"in n)?r(s(n.maxWait)||0,e):c,y="trailing"in n?!!n.trailing:y),E.cancel=function(){void 0!==p&&clearTimeout(p),f=0,a=d=u=p=void 0},E.flush=function(){return void 0===p?h:S(o())},E}},563:function(t){function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},e(t)}t.exports=function(t){var n=e(t);return null!=t&&("object"==n||"function"==n)}},23:function(t){function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},e(t)}t.exports=function(t){return null!=t&&"object"==e(t)}},602:function(t,e,n){function i(t){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i(t)}var o=n(596),s=n(23);t.exports=function(t){return"symbol"==i(t)||s(t)&&"[object Symbol]"==o(t)}},445:function(t,e,n){var i=n(597);t.exports=function(){return i.Date.now()}},204:function(t,e,n){var i=n(719),o=n(563);t.exports=function(t,e,n){var s=!0,r=!0;if("function"!=typeof t)throw new TypeError("Expected a function");return o(n)&&(s="leading"in n?!!n.leading:s,r="trailing"in n?!!n.trailing:r),i(t,e,{leading:s,maxWait:e,trailing:r})}},912:function(t,e,n){var i=n(611),o=n(563),s=n(602),r=/^[-+]0x[0-9a-f]+$/i,l=/^0b[01]+$/i,a=/^0o[0-7]+$/i,u=parseInt;t.exports=function(t){if("number"==typeof t)return t;if(s(t))return NaN;if(o(t)){var e="function"==typeof t.valueOf?t.valueOf():t;t=o(e)?e+"":e}if("string"!=typeof t)return 0===t?t:+t;t=i(t);var n=l.test(t);return n||a.test(t)?u(t.slice(2),n?2:8):r.test(t)?NaN:+t}}},e={};function n(i){var o=e[i];if(void 0!==o)return o.exports;var s=e[i]={id:i,loaded:!1,exports:{}};return t[i](s,s.exports,n),s.loaded=!0,s.exports}n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,{a:e}),e},n.d=function(t,e){for(var i in e)n.o(e,i)&&!n.o(t,i)&&Object.defineProperty(t,i,{enumerable:!0,get:e[i]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.nmd=function(t){return t.paths=[],t.children||(t.children=[]),t},function(){"use strict";var t=n(528),e=n.n(t),i=n(719),o=n.n(i),s=n(563),r=n.n(s),l=n(204),a=n.n(l);function u(t){return u="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},u(t)}function c(t){this.size=0,this.limit=t,this.oldest=this.newest=void 0,this._keymap={}}c.prototype._markEntryAsUsed=function(t){t!==this.newest&&(t.newer&&(t===this.oldest&&(this.oldest=t.newer),t.newer.older=t.older),t.older&&(t.older.newer=t.newer),t.newer=void 0,t.older=this.newest,this.newest&&(this.newest.newer=t),this.newest=t)},c.prototype.put=function(t,e){var n=this._keymap[t];return n?(n.value=e,void this._markEntryAsUsed(n)):(this._keymap[t]=n={key:t,value:e,older:void 0,newer:void 0},this.newest?(this.newest.newer=n,n.older=this.newest):this.oldest=n,this.newest=n,this.size++,this.size>this.limit?this.shift():void 0)},c.prototype.shift=function(){var t=this.oldest;return t&&(this.oldest.newer?(this.oldest=this.oldest.newer,this.oldest.older=void 0):(this.oldest=void 0,this.newest=void 0),t.newer=t.older=void 0,delete this._keymap[t.key],this.size--),t},c.prototype.get=function(t,e){var n=this._keymap[t];if(void 0!==n)return this._markEntryAsUsed(n),e?n:n.value},c.prototype.find=function(t){return this._keymap[t]},c.prototype.set=function(t,e){var n,i=this.get(t,!0);return i?(n=i.value,i.value=e):(n=this.put(t,e))&&(n=n.value),n},c.prototype.remove=function(t){var e=this._keymap[t];if(e)return delete this._keymap[e.key],e.newer&&e.older?(e.older.newer=e.newer,e.newer.older=e.older):e.newer?(e.newer.older=void 0,this.oldest=e.newer):e.older?(e.older.newer=void 0,this.newest=e.older):this.oldest=this.newest=void 0,this.size--,e.value},c.prototype.removeAll=function(){this.oldest=this.newest=void 0,this.size=0,this._keymap={}},"function"==typeof Object.keys?c.prototype.keys=function(){return Object.keys(this._keymap)}:c.prototype.keys=function(){var t=[];for(var e in this._keymap)t.push(e);return t},c.prototype.forEach=function(t,e,n){var i;if(!0===e?(n=!0,e=void 0):"object"!==u(e)&&(e=this),n)for(i=this.newest;i;)t.call(e,i.key,i.value,this),i=i.older;else for(i=this.oldest;i;)t.call(e,i.key,i.value,this),i=i.newer},c.prototype.toJSON=function(){for(var t=new Array(this.size),e=0,n=this.oldest;n;)t[e++]={key:n.key,value:n.value},n=n.newer;return t},c.prototype.toString=function(){for(var t="",e=this.oldest;e;)t+=String(e.key)+":"+e.value,(e=e.newer)&&(t+=" < ");return t};var h=c;function p(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);e&&(i=i.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,i)}return n}function d(t){for(var e=1;et.length)&&(e=t.length);for(var n=0,i=new Array(e);n".concat(i,"")),{text:t,snippetBefore:e||"",snippetAfter:n||"",suggestionText:o}}R.addRule(/order by\b/,(function(t){return O("ORDER BY",t)})),R.addRule(C,(function(){})),R.addRule(/\./,(function(t){return O("DOT",t)})),R.addRule(/,/,(function(t){return O("COMMA",t)})),R.addRule(new RegExp("or".concat(E)),(function(t){return O("OR",t)})),R.addRule(new RegExp("and".concat(E)),(function(t){return O("AND",t)})),R.addRule(new RegExp("not".concat(E)),(function(t){return O("NOT",t)})),R.addRule(new RegExp("in".concat(E)),(function(t){return O("IN",t)})),R.addRule(new RegExp("startswith".concat(E)),(function(t){return O("STARTSWITH",t)})),R.addRule(new RegExp("endswith".concat(E)),(function(t){return O("ENDSWITH",t)})),R.addRule(new RegExp("True".concat(E)),(function(t){return O("TRUE",t)})),R.addRule(new RegExp("False".concat(E)),(function(t){return O("FALSE",t)})),R.addRule(new RegExp("None".concat(E)),(function(t){return O("NONE",t)})),R.addRule(new RegExp("asc".concat(E)),(function(t){return O("ASC",t)})),R.addRule(new RegExp("desc".concat(E)),(function(t){return O("DESC",t)})),R.addRule(/[_A-Za-z][_0-9A-Za-z]*(\.[_A-Za-z][_0-9A-Za-z]*)*/,(function(t){return O("NAME",t)})),R.addRule(S,(function(t){return O("STRING_VALUE",t.slice(1,t.length-1))})),R.addRule(b,(function(t){return O("INT_VALUE",t)})),R.addRule(x,(function(t){return O("FLOAT_VALUE",t)})),R.addRule(/\(/,(function(t){return O("PAREN_L",t)})),R.addRule(/\)/,(function(t){return O("PAREN_R",t)})),R.addRule(/=/,(function(t){return O("EQUALS",t)})),R.addRule(/!=/,(function(t){return O("NOT_EQUALS",t)})),R.addRule(/>/,(function(t){return O("GREATER",t)})),R.addRule(/>=/,(function(t){return O("GREATER_EQUAL",t)})),R.addRule(/ element, "+"but ".concat(this.textarea.tagName," was found")):this.logError("Element not found by selector: ".concat(t.selector))):this.logError("Please pass an object with initialization parameters")};L.init=function(t){return new L(t)},L.DOMReady=function(t){"loading"!==document.readyState?t():document.addEventListener("DOMContentLoaded",t)},L.prototype={createCompletionElement:function(){var t,e=this.options;this.completion||(this.completion=document.createElement("div"),this.completion.className="djangoql-completion",document.querySelector("body").appendChild(this.completion),this.completionUL=document.createElement("ul"),this.completionUL.onscroll=a()(this.onCompletionScroll.bind(this),50),this.completion.appendChild(this.completionUL),"string"==typeof e.syntaxHelp&&((t=document.createElement("p")).className="syntax-help",t.innerHTML='Syntax Help',t.addEventListener("mousedown",(function(t){t.preventDefault()})),this.completion.appendChild(t)),this.completionEnabled=!e.hasOwnProperty("completionEnabled")||e.completionEnabled)},destroyCompletionElement:function(){this.completion&&(this.completion.parentNode.removeChild(this.completion),this.completion=null,this.completionEnabled=!1)},enableCompletion:function(){this.completionEnabled=!0},disableCompletion:function(){this.completionEnabled=!1,this.hideCompletion()},getJson:function(t,e){this.loading=!0;var n=function(){this.loading=!1,this.request=null,this.logError("failed to fetch from ".concat(t))}.bind(this);this.request&&this.request.abort(),this.request=new XMLHttpRequest,this.request.open("GET",t,!0),this.request.onload=function(){this.loading=!1,200===this.request.status?"function"==typeof e.success&&e.success(JSON.parse(this.request.responseText)):n(),this.request=null}.bind(this),this.request.ontimeout=n,this.request.onerror=n,this.request.onprogress=function(){},window.setTimeout(this.request.send.bind(this.request))},loadIntrospections:function(t){var e=function(t){this.currentModel=t.current_model,this.models=t.models,this.suggestionsAPIUrl=t.suggestions_api_url}.bind(this);"string"==typeof t?this.getJson(t,{success:e}):r()(t)?e(t):this.logError("introspections parameter is expected to be either URL or "+"object with definitions, but ".concat(t," was found"))},logError:function(t){console.error("DjangoQL: ".concat(t))},onCompletionMouseClick:function(t){this.selectCompletion(parseInt(t.currentTarget.getAttribute("data-index"),10))},onCompletionMouseDown:function(t){t.preventDefault()},onKeydown:function(t){switch(t.keyCode){case 38:this.suggestions.length&&(null===this.selected?this.selected=this.suggestions.length-1:0===this.selected?this.selected=null:this.selected-=1,this.renderCompletion(),t.preventDefault());break;case 40:this.suggestions.length&&(null===this.selected?this.selected=0:this.selected1&&(p=d.join(""),!h&&!c.text)){var f=(u=2,function(t){if(Array.isArray(t))return t}(a=d)||function(t,e){var n=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=n){var i,o,s=[],r=!0,l=!1;try{for(n=n.call(t);!(r=(i=n.next()).done)&&(s.push(i.value),!e||s.length!==e);r=!0);}catch(t){l=!0,o=t}finally{try{r||null==n.return||n.return()}finally{if(l)throw o}}return s}}(a,u)||function(t,e){if(t){if("string"==typeof t)return m(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?m(t,e):void 0}}(a,u)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}());h=f[0],p=f[1]}r.endsWith(h)&&(h=""),l.startsWith(p)&&(p="");var g=h+c.text+p,y=r.length+g.length;d.length>1&&(y-=d[1].length),this.textarea.value=r+g+l,this.textarea.focus(),this.textarea.setSelectionRange(y,y),this.selected=null,this.textareaResize&&this.textareaResize(),this.generateSuggestions(this.textarea),this.renderCompletion()},hideCompletion:function(){this.selected=null,this.completion&&(this.completion.style.display="none")},highlight:function(t,e){return e&&t?this.highlightCaseSensitive?t.split(e).join("".concat(e,"")):t.replace(new RegExp("(".concat(e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),")"),"ig"),"$1"):t},renderCompletion:function(t){var e,n,i,o,s,r;if(this.completionEnabled){if(!t||"none"!==this.completion.style.display)if(this.suggestions.length||this.loading){var l=this.suggestions.length,a=[].slice.call(this.completionUL.querySelectorAll("li[data-index]"));for(s=a.length,n=0;ni.bottom?this.completionUL.scrollTop=this.completionUL.scrollTop+2+(o.bottom-i.bottom):o.topl;)a[--s].removeEventListener("click",this.onCompletionMouseClick),a[s].removeEventListener("mousedown",this.onCompletionMouseDown),this.completionUL.removeChild(a[s]);r=this.completionUL.querySelector("li.djangoql-loading"),this.loading?r||((r=document.createElement("li")).className="djangoql-loading",r.innerHTML=" ",this.completionUL.appendChild(r)):r&&this.completionUL.removeChild(r);var u=this.textarea.getBoundingClientRect(),c=window.pageYOffset+u.top+u.height;this.completion.style.top="".concat(c,"px"),this.completion.style.left="".concat(u.left,"px"),this.completion.style.display="block"}else this.hideCompletion()}else this.hideCompletion()},resolveName:function(t){var e,n,i,o=t.split("."),s=this.currentModel,r=null,l=[];if(s)for(l.push(s),n=0,i=o.length;n=e&&(m=f[d.length-1],d.pop()),d.length&&(h=d[d.length-1],d.length>1&&(p=d[d.length-2]));var g=(n=t.slice(h?h.end:0,e)).match(C);g&&(n=n.slice(g[0].length)),"("===n&&(n="");var y=["AND","OR"];return(")"!==n||g)&&("expression"===c&&(!h||y.indexOf(h.name)>=0&&g||"."===n&&h&&!g||"PAREN_L"===h.name&&(!p||y.indexOf(p.name)>=0))||"ordering"===c&&h&&("ORDER BY"===h.name||"COMMA"===h.name)?(s="field",r=this.currentModel,"."===n&&(n=t.slice(h.start,e)),(i=n.split(".")).length>1&&(n=i.pop(),(o=this.resolveName(i.join("."))).model&&!o.field?(r=o.model,a=o.modelStack):(s=null,r=null))):"expression"===c&&h&&g&&p&&"NAME"===p.name&&["EQUALS","NOT_EQUALS","CONTAINS","NOT_CONTAINS","GREATER_EQUAL","GREATER","LESS_EQUAL","LESS"].indexOf(h.name)>=0?(o=this.resolveName(p.value)).model&&(s="value",r=o.model,l=o.field,a=o.modelStack,'"'!==n[0]||"str"!==this.models[r][l].type&&!this.models[r][l].options||(n=n.slice(1))):"expression"===c&&h&&g&&"NAME"===h.name?(o=this.resolveName(h.value)).model&&(s="comparison",r=o.model,l=o.field,a=o.modelStack):"expression"===c&&h&&g&&["PAREN_R","INT_VALUE","FLOAT_VALUE","STRING_VALUE"].indexOf(h.name)>=0?s="logical":"ordering"===c&&h&&"NAME"===h.name&&(s="sortdir")),{prefix:n,scope:s,model:r,field:l,currentFullToken:m,modelStack:a,queryPart:c,nestingLevel:u}},getCurrentFieldOptions:function(){var t=this.textarea,e=this.getContext(t.value,t.selectionStart),n=this.models[e.model],i=e.field&&n[e.field],o={cacheKey:null,context:e,field:i,model:n,options:null};if("value"!==e.scope||!i||!i.options)return null;if(Array.isArray(i.options))o.options=i.options;else if(!0===i.options){if(!this.suggestionsAPIUrl)return null;o.cacheKey="".concat(e.model,".").concat(e.field,"|").concat(e.prefix)}return o},loadFieldOptions:function(t){var e=this.getCurrentFieldOptions()||{},n=e.context;if(e.cacheKey){var i={field:"".concat(n.model,".").concat(n.field),search:n.prefix},o=this.suggestionsCache.get(e.cacheKey)||{};if(t&&o.has_next)i.page=o.page?o.page+1:1;else if(o.page)return;o.loading=!0,this.suggestionsCache.set(e.cacheKey,o);var s,r,l,a,u,c,h,p,f,m,g=(s=this.suggestionsAPIUrl,r=i,p=(h=s.split("?"))[0],f=h.slice(1).join("?"),m=f.split("&"),Object.keys(r).forEach((function(t){for(a=encodeURI(t),u=encodeURI(r[a]),c=m.length;c--;)if((l=m[c].split("="))[0]===a){l[1]=u,m[c]=l.join("=");break}c<0&&m.push("".concat(a,"=").concat(u))})),(f=m.join("&"))?[p,f].join("?"):p);this.getJson(g,{success:function(t){var n=this.suggestionsCache.get(e.cacheKey)||{};if(t.page-1===(n.page||0)){var i=d(d({},t),{},{items:(n.items||[]).concat(t.items)});this.suggestionsCache.set(e.cacheKey,i),this.loading=!1,this.populateFieldOptions(),this.renderCompletion()}}.bind(this)}),this.populateFieldOptions(),this.renderCompletion()}},populateFieldOptions:function(t){var e=this.getCurrentFieldOptions();if(null!==e){var n,i=e.options,o=e.context&&e.context.prefix;if(i)i=this.valuesCaseSensitive?i.filter((function(t){return t.indexOf(o)>=0})):i.filter((function(t){return t.toLowerCase().indexOf(o.toLowerCase())>=0}));else{if(this.suggestions=[],!e.cacheKey)return;if(i=(n=this.suggestionsCache.get(e.cacheKey)||{}).items||[],!n.loading&&(!n.page||t&&n.has_next)&&this.debouncedLoadFieldOptions(t),!i.length)return}this.highlightCaseSensitive=this.valuesCaseSensitive,this.suggestions=i.map((function(t){return A(t,'"','"')}))}},onCompletionScroll:function(){var t=this.completionUL.getBoundingClientRect().height,e=this.completionUL.scrollTop+t;e>t&&e>this.completionUL.scrollHeight-t&&this.populateFieldOptions(!0)},generateSuggestions:function(){var t,e,n,i=this.textarea;if(!this.completionEnabled)return this.prefix="",void(this.suggestions=[]);if(this.currentModel){if(i.selectionStart!==i.selectionEnd)return this.prefix="",void(this.suggestions=[]);n=function(t){return t.text.indexOf(this.prefix)>=0}.bind(this),this.highlightCaseSensitive=!0;var o=this.getContext(i.value,i.selectionStart);console.log(o);var s=o.modelStack;this.prefix=o.prefix;var r=this.models[o.model],l=o.field&&r[o.field];switch(o.scope){case"field":this.suggestions=Object.keys(r).filter((function(t){var e=r[t].relation;return"relation"!==r[t].type||!s.includes(e)||s.slice(-1)[0]===e})).map((function(t){return A(t,"","relation"===r[t].type?".":" ")})),"expression"===o.queryPart&&0===o.nestingLevel&&this.suggestions.push(A("order by",""," "));break;case"comparison":t=["=",["!=","is not equal to"]],e=" ",l&&"bool"!==l.type&&(["date","datetime"].indexOf(l.type)>=0?(t.push(["~","contains"],["!~","does not contain"]),e=' "|"'):"str"===l.type?(t.push(["~","contains"],["!~","does not contain"],"startswith","not startswith","endswith","not endswith"),e=' "|"'):l.options&&(e=' "|"'),"str"!==l.type&&t.push(">",">=","<","<=")),this.suggestions=t.map((function(t){return"string"==typeof t?A(t,"",e):A(t[0],"",e,t[1])})),l&&"bool"!==l.type&&(e=["str","date","datetime"].indexOf(l.type)>=0||l.options?' ("|")':" (|)",this.suggestions.push(A("in","",e)),this.suggestions.push(A("not in","",e))),n=function(t){return 0===t.text.lastIndexOf(this.prefix,0)}.bind(this);break;case"value":l?l.options?(this.prefix=o.prefix,this.populateFieldOptions()):"bool"===l.type?(this.suggestions=[A("True",""," "),A("False",""," ")],l.nullable&&this.suggestions.push(A("None",""," "))):"unknown"===l.type&&(this.prefix="",this.suggestions=[]):this.suggestions=[A("None",""," ")];break;case"logical":this.suggestions=[A("and",""," "),A("or",""," ")],0===o.nestingLevel&&this.suggestions.push(A("order by",""," "));break;case"sortdir":this.suggestions=[A("asc",""," "),A("desc",""," ")];break;default:this.prefix="",this.suggestions=[]}this.suggestions=this.suggestions.filter(n),1===this.suggestions.length?this.selected=0:this.selected=null}}};var j=L;window.DjangoQL=j}()}(); //# sourceMappingURL=completion.js.map \ No newline at end of file diff --git a/djangoql/static/djangoql/js/completion.js.map b/djangoql/static/djangoql/js/completion.js.map index 7dde9d8..1a2b77a 100644 --- a/djangoql/static/djangoql/js/completion.js.map +++ b/djangoql/static/djangoql/js/completion.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///./node_modules/lex/lexer.js","webpack:///./node_modules/lodash/_Symbol.js","webpack:///./node_modules/lodash/_baseGetTag.js","webpack:///./node_modules/lodash/_baseTrim.js","webpack:///./node_modules/lodash/_freeGlobal.js","webpack:///./node_modules/lodash/_getRawTag.js","webpack:///./node_modules/lodash/_objectToString.js","webpack:///./node_modules/lodash/_root.js","webpack:///./node_modules/lodash/_trimmedEndIndex.js","webpack:///./node_modules/lodash/debounce.js","webpack:///./node_modules/lodash/isObject.js","webpack:///./node_modules/lodash/isObjectLike.js","webpack:///./node_modules/lodash/isSymbol.js","webpack:///./node_modules/lodash/now.js","webpack:///./node_modules/lodash/throttle.js","webpack:///./node_modules/lodash/toNumber.js","webpack:///webpack/bootstrap","webpack:///webpack/runtime/compat get default export","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/global","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///webpack/runtime/node module decorator","webpack:///./node_modules/djangoql-completion/src/lru-cache.js","webpack:///./node_modules/djangoql-completion/src/index.js","webpack:///./node_modules/djangoql-completion/src/utils.js","webpack:///./completion-widget/index.js"],"names":["Lexer","defunct","tokens","rules","remove","scan","matches","index","state","this","lastIndex","input","i","length","rule","start","states","indexOf","pattern","result","exec","j","push","action","global","k","temple","addRule","flags","multiline","ignoreCase","RegExp","source","Object","prototype","toString","call","setInput","lex","shift","reject","splice","match","token","apply","slice","charAt","module","exports","chr","Error","Symbol","require","getRawTag","objectToString","symToStringTag","toStringTag","undefined","value","trimmedEndIndex","reTrimStart","string","replace","freeGlobal","objectProto","hasOwnProperty","nativeObjectToString","isOwn","tag","unmasked","e","freeSelf","self","root","Function","reWhitespace","test","isObject","now","toNumber","nativeMax","Math","max","nativeMin","min","func","wait","options","lastArgs","lastThis","maxWait","timerId","lastCallTime","lastInvokeTime","leading","maxing","trailing","TypeError","invokeFunc","time","args","thisArg","leadingEdge","setTimeout","timerExpired","shouldInvoke","timeSinceLastCall","trailingEdge","timeWaiting","remainingWait","debounced","isInvoking","arguments","clearTimeout","cancel","flush","type","baseGetTag","isObjectLike","Date","debounce","baseTrim","isSymbol","reIsBadHex","reIsBinary","reIsOctal","freeParseInt","parseInt","other","valueOf","isBinary","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","id","loaded","__webpack_modules__","n","getter","__esModule","d","a","definition","key","o","defineProperty","enumerable","get","g","globalThis","window","obj","prop","nmd","paths","children","LRUCache","limit","size","oldest","newest","_keymap","_markEntryAsUsed","entry","newer","older","put","returnEntry","find","set","oldvalue","removeAll","keys","forEach","fun","context","desc","toJSON","s","Array","String","reIntValue","reFractionPart","reExponentPart","intRegex","floatRegex","reStringChar","stringRegex","reNotFollowedByName","whitespaceRegex","lexer","name","suggestion","text","snippetBefore","snippetAfter","explanation","suggestionText","l","lexAll","end","DjangoQL","cacheSize","currentModel","models","suggestionsAPIUrl","prefix","suggestions","selected","valuesCaseSensitive","highlightCaseSensitive","textarea","completion","completionUL","completionEnabled","loadIntrospections","introspections","selector","document","querySelector","tagName","logError","suggestionsCache","debouncedLoadFieldOptions","loadFieldOptions","bind","loading","enableCompletion","disableCompletion","onCompletionMouseClick","onCompletionMouseDown","popupCompletion","debouncedRenderCompletion","renderCompletion","setAttribute","addEventListener","onKeydown","hideCompletion","autoResize","textareaResize","style","resize","overflow","createCompletionElement","init","DOMReady","callback","readyState","syntaxHelp","createElement","className","appendChild","onscroll","throttle","onCompletionScroll","innerHTML","preventDefault","destroyCompletionElement","parentNode","removeChild","getJson","url","settings","onLoadError","request","abort","XMLHttpRequest","open","onload","status","success","JSON","parse","responseText","ontimeout","onerror","onprogress","send","initIntrospections","data","current_model","suggestions_api_url","message","console","error","selectCompletion","currentTarget","getAttribute","keyCode","onSubmit","form","submit","getComputedStyle","heightOffset","parseFloat","paddingTop","paddingBottom","height","scrollHeight","generateSuggestions","getContext","selectionStart","currentFullToken","textValue","startPos","tokenEndPos","textBefore","textAfter","trim","snippetAfterParts","split","join","endsWith","startsWith","textToPaste","cursorPosAfter","focus","setSelectionRange","display","highlight","dontForceDisplay","currentLi","completionRect","currentLiRect","liLen","loadingElement","suggestionsLen","li","querySelectorAll","getBoundingClientRect","bottom","scrollTop","top","removeEventListener","inputRect","pageYOffset","left","resolveName","f","nameParts","model","field","modelStack","relation","cursorPos","resolvedName","scope","lastToken","nextToLastToken","allTokens","pop","whitespace","logicalTokens","getCurrentFieldOptions","ctx","fieldOptions","cacheKey","isArray","loadMore","requestParams","search","cached","has_next","page","params","pair","parts","path","queryString","pairs","requestUrl","encodeURI","cache","cachedData","items","concat","populateFieldOptions","filter","item","toLowerCase","map","rectHeight","scrollBottom","searchFilter","selectionEnd","includes","lastIndexOf","nullable"],"mappings":"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","file":"js/completion.js","sourcesContent":["if (typeof module === \"object\" && typeof module.exports === \"object\") module.exports = Lexer;\n\nLexer.defunct = function (chr) {\n throw new Error(\"Unexpected character at index \" + (this.index - 1) + \": \" + chr);\n};\n\nfunction Lexer(defunct) {\n if (typeof defunct !== \"function\") defunct = Lexer.defunct;\n\n var tokens = [];\n var rules = [];\n var remove = 0;\n this.state = 0;\n this.index = 0;\n this.input = \"\";\n\n this.addRule = function (pattern, action, start) {\n var global = pattern.global;\n\n if (!global) {\n var flags = \"g\";\n if (pattern.multiline) flags += \"m\";\n if (pattern.ignoreCase) flags += \"i\";\n pattern = new RegExp(pattern.source, flags);\n }\n\n if (Object.prototype.toString.call(start) !== \"[object Array]\") start = [0];\n\n rules.push({\n pattern: pattern,\n global: global,\n action: action,\n start: start\n });\n\n return this;\n };\n\n this.setInput = function (input) {\n remove = 0;\n this.state = 0;\n this.index = 0;\n tokens.length = 0;\n this.input = input;\n return this;\n };\n\n this.lex = function () {\n if (tokens.length) return tokens.shift();\n\n this.reject = true;\n\n while (this.index <= this.input.length) {\n var matches = scan.call(this).splice(remove);\n var index = this.index;\n\n while (matches.length) {\n if (this.reject) {\n var match = matches.shift();\n var result = match.result;\n var length = match.length;\n this.index += length;\n this.reject = false;\n remove++;\n\n var token = match.action.apply(this, result);\n if (this.reject) this.index = result.index;\n else if (typeof token !== \"undefined\") {\n switch (Object.prototype.toString.call(token)) {\n case \"[object Array]\":\n tokens = token.slice(1);\n token = token[0];\n default:\n if (length) remove = 0;\n return token;\n }\n }\n } else break;\n }\n\n var input = this.input;\n\n if (index < input.length) {\n if (this.reject) {\n remove = 0;\n var token = defunct.call(this, input.charAt(this.index++));\n if (typeof token !== \"undefined\") {\n if (Object.prototype.toString.call(token) === \"[object Array]\") {\n tokens = token.slice(1);\n return token[0];\n } else return token;\n }\n } else {\n if (this.index !== index) remove = 0;\n this.reject = true;\n }\n } else if (matches.length)\n this.reject = true;\n else break;\n }\n };\n\n function scan() {\n var matches = [];\n var index = 0;\n\n var state = this.state;\n var lastIndex = this.index;\n var input = this.input;\n\n for (var i = 0, length = rules.length; i < length; i++) {\n var rule = rules[i];\n var start = rule.start;\n var states = start.length;\n\n if ((!states || start.indexOf(state) >= 0) ||\n (state % 2 && states === 1 && !start[0])) {\n var pattern = rule.pattern;\n pattern.lastIndex = lastIndex;\n var result = pattern.exec(input);\n\n if (result && result.index === lastIndex) {\n var j = matches.push({\n result: result,\n action: rule.action,\n length: result[0].length\n });\n\n if (rule.global) index = j;\n\n while (--j > index) {\n var k = j - 1;\n\n if (matches[j].length > matches[k].length) {\n var temple = matches[j];\n matches[j] = matches[k];\n matches[k] = temple;\n }\n }\n }\n }\n }\n\n return matches;\n }\n}\n","var root = require('./_root');\n\n/** Built-in value references. */\nvar Symbol = root.Symbol;\n\nmodule.exports = Symbol;\n","var Symbol = require('./_Symbol'),\n getRawTag = require('./_getRawTag'),\n objectToString = require('./_objectToString');\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? getRawTag(value)\n : objectToString(value);\n}\n\nmodule.exports = baseGetTag;\n","var trimmedEndIndex = require('./_trimmedEndIndex');\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nmodule.exports = baseTrim;\n","/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\nmodule.exports = freeGlobal;\n","var Symbol = require('./_Symbol');\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar symToStringTag = Symbol ? Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty.call(value, symToStringTag),\n tag = value[symToStringTag];\n\n try {\n value[symToStringTag] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag] = tag;\n } else {\n delete value[symToStringTag];\n }\n }\n return result;\n}\n\nmodule.exports = getRawTag;\n","/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nmodule.exports = objectToString;\n","var freeGlobal = require('./_freeGlobal');\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\nmodule.exports = root;\n","/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nmodule.exports = trimmedEndIndex;\n","var isObject = require('./isObject'),\n now = require('./now'),\n toNumber = require('./toNumber');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n timeWaiting = wait - timeSinceLastCall;\n\n return maxing\n ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\nmodule.exports = debounce;\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nmodule.exports = isObject;\n","/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nmodule.exports = isObjectLike;\n","var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && baseGetTag(value) == symbolTag);\n}\n\nmodule.exports = isSymbol;\n","var root = require('./_root');\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\nmodule.exports = now;\n","var debounce = require('./debounce'),\n isObject = require('./isObject');\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds. The throttled function comes with a `cancel`\n * method to cancel delayed `func` invocations and a `flush` method to\n * immediately invoke them. Provide `options` to indicate whether `func`\n * should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.throttle` and `_.debounce`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n * Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\nfunction throttle(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (isObject(options)) {\n leading = 'leading' in options ? !!options.leading : leading;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n return debounce(func, wait, {\n 'leading': leading,\n 'maxWait': wait,\n 'trailing': trailing\n });\n}\n\nmodule.exports = throttle;\n","var baseTrim = require('./_baseTrim'),\n isObject = require('./isObject'),\n isSymbol = require('./isSymbol');\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = toNumber;\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","/**\n * https://github.com/rsms/js-lru/blob/v2/lru.js\n *\n * A doubly linked list-based Least Recently Used (LRU) cache. Will keep most\n * recently used items while discarding least recently used items when its limit\n * is reached.\n *\n * Licensed under MIT. Copyright (c) 2010 Rasmus Andersson \n * See README.md for details.\n *\n * Illustration of the design:\n *\n * entry entry entry entry\n * ______ ______ ______ ______\n * | head |.newer => | |.newer => | |.newer => | tail |\n * | A | | B | | C | | D |\n * |______| <= older.|______| <= older.|______| <= older.|______|\n *\n * removed <-- <-- <-- <-- <-- <-- <-- <-- <-- <-- <-- added\n */\nfunction LRUCache (limit) {\n // Current size of the cache. (Read-only).\n this.size = 0;\n // Maximum number of items this cache can hold.\n this.limit = limit;\n this.oldest = this.newest = undefined;\n this._keymap = {};\n}\n\n\nLRUCache.prototype._markEntryAsUsed = function(entry) {\n if (entry === this.newest) {\n // Already the most recenlty used entry, so no need to update the list\n return;\n }\n // HEAD--------------TAIL\n // <.older .newer>\n // <--- add direction --\n // A B C E\n if (entry.newer) {\n if (entry === this.oldest) {\n this.oldest = entry.newer;\n }\n entry.newer.older = entry.older; // C <-- E.\n }\n if (entry.older) {\n entry.older.newer = entry.newer; // C. --> E\n }\n entry.newer = undefined; // D --x\n entry.older = this.newest; // D. --> E\n if (this.newest) {\n this.newest.newer = entry; // E. <-- D\n }\n this.newest = entry;\n};\n\n/**\n * Put into the cache associated with . Returns the entry which was\n * removed to make room for the new entry. Otherwise undefined is returned\n * (i.e. if there was enough room already).\n */\nLRUCache.prototype.put = function(key, value) {\n var entry = this._keymap[key];\n\n if (entry) {\n // update existing\n entry.value = value;\n this._markEntryAsUsed(entry);\n return;\n }\n\n // new entry\n this._keymap[key] = entry = {key:key, value:value, older:undefined, newer:undefined};\n\n if (this.newest) {\n // link previous tail to the new tail (entry)\n this.newest.newer = entry;\n entry.older = this.newest;\n } else {\n // we're first in -- yay\n this.oldest = entry;\n }\n\n // add new entry to the end of the linked list -- it's now the freshest entry.\n this.newest = entry;\n this.size++;\n if (this.size > this.limit) {\n // we hit the limit -- remove the head\n return this.shift();\n }\n};\n\n/**\n * Purge the least recently used (oldest) entry from the cache. Returns the\n * removed entry or undefined if the cache was empty.\n *\n * If you need to perform any form of finalization of purged items, this is a\n * good place to do it. Simply override/replace this function:\n *\n * var c = new LRUCache(123);\n * c.shift = function() {\n * var entry = LRUCache.prototype.shift.call(this);\n * doSomethingWith(entry);\n * return entry;\n * }\n */\nLRUCache.prototype.shift = function() {\n // todo: handle special case when limit == 1\n var entry = this.oldest;\n if (entry) {\n if (this.oldest.newer) {\n // advance the list\n this.oldest = this.oldest.newer;\n this.oldest.older = undefined;\n } else {\n // the cache is exhausted\n this.oldest = undefined;\n this.newest = undefined;\n }\n // Remove last strong reference to and remove links from the purged\n // entry being returned:\n entry.newer = entry.older = undefined;\n // delete is slow, but we need to do this to avoid uncontrollable growth:\n delete this._keymap[entry.key];\n this.size--;\n }\n return entry;\n};\n\n/**\n * Get and register recent use of . Returns the value associated with \n * or undefined if not in cache.\n */\nLRUCache.prototype.get = function(key, returnEntry) {\n // First, find our cache entry\n var entry = this._keymap[key];\n if (entry === undefined) return; // Not cached. Sorry.\n // As was found in the cache, register it as being requested recently\n this._markEntryAsUsed(entry);\n return returnEntry ? entry : entry.value;\n};\n\n// ----------------------------------------------------------------------------\n// Following code is optional and can be removed without breaking the core\n// functionality.\n\n/**\n * Check if is in the cache without registering recent use. Feasible if\n * you do not want to chage the state of the cache, but only \"peek\" at it.\n * Returns the entry associated with if found, or undefined if not found.\n */\nLRUCache.prototype.find = function(key) {\n return this._keymap[key];\n};\n\n/**\n * Update the value of entry with . Returns the old value, or undefined if\n * entry was not in the cache.\n */\nLRUCache.prototype.set = function(key, value) {\n var oldvalue, entry = this.get(key, true);\n if (entry) {\n oldvalue = entry.value;\n entry.value = value;\n } else {\n oldvalue = this.put(key, value);\n if (oldvalue) oldvalue = oldvalue.value;\n }\n return oldvalue;\n};\n\n/**\n * Remove entry from cache and return its value. Returns undefined if not\n * found.\n */\nLRUCache.prototype.remove = function(key) {\n var entry = this._keymap[key];\n if (!entry) return;\n delete this._keymap[entry.key]; // need to do delete unfortunately\n if (entry.newer && entry.older) {\n // relink the older entry with the newer entry\n entry.older.newer = entry.newer;\n entry.newer.older = entry.older;\n } else if (entry.newer) {\n // remove the link to us\n entry.newer.older = undefined;\n // link the newer entry to head\n this.oldest = entry.newer;\n } else if (entry.older) {\n // remove the link to us\n entry.older.newer = undefined;\n // link the newer entry to head\n this.newest = entry.older;\n } else {// if(entry.older === undefined && entry.newer === undefined) {\n this.oldest = this.newest = undefined;\n }\n\n this.size--;\n return entry.value;\n};\n\n/** Removes all entries */\nLRUCache.prototype.removeAll = function() {\n // This should be safe, as we never expose strong refrences to the outside\n this.oldest = this.newest = undefined;\n this.size = 0;\n this._keymap = {};\n};\n\n/**\n * Return an array containing all keys of entries stored in the cache object, in\n * arbitrary order.\n */\nif (typeof Object.keys === 'function') {\n LRUCache.prototype.keys = function() {\n return Object.keys(this._keymap);\n };\n} else {\n LRUCache.prototype.keys = function() {\n var keys = [];\n for (var k in this._keymap) {\n keys.push(k);\n }\n return keys;\n };\n}\n\n/**\n * Call `fun` for each entry. Starting with the newest entry if `desc` is a true\n * value, otherwise starts with the oldest (head) enrty and moves towards the\n * tail.\n *\n * `fun` is called with 3 arguments in the context `context`:\n * `fun.call(context, Object key, Object value, LRUCache self)`\n */\nLRUCache.prototype.forEach = function(fun, context, desc) {\n var entry;\n if (context === true) {\n desc = true;\n context = undefined;\n } else if (typeof context !== 'object') {\n context = this;\n }\n if (desc) {\n entry = this.newest;\n while (entry) {\n fun.call(context, entry.key, entry.value, this);\n entry = entry.older;\n }\n } else {\n entry = this.oldest;\n while (entry) {\n fun.call(context, entry.key, entry.value, this);\n entry = entry.newer;\n }\n }\n};\n\n/** Returns a JSON (array) representation */\nLRUCache.prototype.toJSON = function() {\n var s = new Array(this.size), i = 0, entry = this.oldest;\n while (entry) {\n s[i++] = { key: entry.key, value: entry.value };\n entry = entry.newer;\n }\n return s;\n};\n\n/** Returns a String representation */\nLRUCache.prototype.toString = function() {\n var s = '', entry = this.oldest;\n while (entry) {\n s += String(entry.key)+':'+entry.value;\n entry = entry.newer;\n if (entry) {\n s += ' < ';\n }\n }\n return s;\n};\n\n// Export ourselves\nexport default LRUCache;\n","import Lexer from 'lex';\nimport debounce from 'lodash/debounce';\nimport isObject from 'lodash/isObject';\nimport throttle from 'lodash/throttle';\n\nimport LRUCache from './lru-cache';\nimport { DOMReady, escapeRegExp, setUrlParams } from './utils';\n\nconst reIntValue = '(-?0|-?[1-9][0-9]*)';\nconst reFractionPart = '\\\\.[0-9]+';\nconst reExponentPart = '[eE][+-]?[0-9]+';\nconst intRegex = new RegExp(reIntValue);\nconst floatRegex = new RegExp(\n `${reIntValue}${reFractionPart}${reExponentPart}`\n + `|${reIntValue}${reFractionPart}|${reIntValue}${reExponentPart}`,\n);\nconst reLineTerminators = '\\\\n\\\\r\\\\u2028\\\\u2029';\nconst reEscapedChar = '\\\\\\\\[\\\\\\\\\"/bfnrt]';\nconst reEscapedUnicode = '\\\\\\\\u[0-9A-Fa-f]{4}';\nconst reStringChar = `[^\\\\\\\\\"\\\\\\\\\\\\\\\\${reLineTerminators}]`;\nconst stringRegex = new RegExp(\n '\\\\\"('\n + `${reEscapedChar}|${reEscapedUnicode}|${reStringChar}`\n + ')*\\\\\"',\n);\nconst nameRegex = /[_A-Za-z][_0-9A-Za-z]*(\\.[_A-Za-z][_0-9A-Za-z]*)*/;\nconst reNotFollowedByName = '(?![_0-9A-Za-z])';\nconst whitespaceRegex = /[ \\t\\v\\f\\u00A0]+/;\n\nconst lexer = new Lexer(() => {\n // Silently swallow any lexer errors\n});\n\nfunction token(name, value) {\n return { name, value };\n}\n\nlexer.addRule(whitespaceRegex, () => { /* ignore whitespace */ });\nlexer.addRule(/\\./, (l) => token('DOT', l));\nlexer.addRule(/,/, (l) => token('COMMA', l));\nlexer.addRule(new RegExp(`or${reNotFollowedByName}`), (l) => token('OR', l));\nlexer.addRule(new RegExp(`and${reNotFollowedByName}`), (l) => token('AND', l));\nlexer.addRule(new RegExp(`not${reNotFollowedByName}`), (l) => token('NOT', l));\nlexer.addRule(new RegExp(`in${reNotFollowedByName}`), (l) => token('IN', l));\nlexer.addRule(\n new RegExp(`startswith${reNotFollowedByName}`),\n (l) => token('STARTSWITH', l),\n);\nlexer.addRule(\n new RegExp(`endswith${reNotFollowedByName}`),\n (l) => token('ENDSWITH', l),\n);\nlexer.addRule(\n new RegExp(`True${reNotFollowedByName}`),\n (l) => token('TRUE', l),\n);\nlexer.addRule(\n new RegExp(`False${reNotFollowedByName}`),\n (l) => token('FALSE', l),\n);\nlexer.addRule(\n new RegExp(`None${reNotFollowedByName}`),\n (l) => token('NONE', l),\n);\nlexer.addRule(nameRegex, (l) => token('NAME', l));\nlexer.addRule(\n stringRegex,\n // Trim leading and trailing quotes:\n (l) => token('STRING_VALUE', l.slice(1, l.length - 1)),\n);\nlexer.addRule(intRegex, (l) => token('INT_VALUE', l));\nlexer.addRule(floatRegex, (l) => token('FLOAT_VALUE', l));\nlexer.addRule(/\\(/, (l) => token('PAREN_L', l));\nlexer.addRule(/\\)/, (l) => token('PAREN_R', l));\nlexer.addRule(/=/, (l) => token('EQUALS', l));\nlexer.addRule(/!=/, (l) => token('NOT_EQUALS', l));\nlexer.addRule(/>/, (l) => token('GREATER', l));\nlexer.addRule(/>=/, (l) => token('GREATER_EQUAL', l));\nlexer.addRule(/ token('LESS', l));\nlexer.addRule(/<=/, (l) => token('LESS_EQUAL', l));\nlexer.addRule(/~/, (l) => token('CONTAINS', l));\nlexer.addRule(/!~/, (l) => token('NOT_CONTAINS', l));\nlexer.lexAll = function () {\n let match;\n const result = [];\n while (match = this.lex()) { // eslint-disable-line no-cond-assign\n match.start = this.index - match.value.length;\n match.end = this.index;\n result.push(match);\n }\n return result;\n};\n\nfunction suggestion(text, snippetBefore, snippetAfter, explanation) {\n // text is being displayed in completion box and pasted when you hit Enter.\n // snippetBefore is an optional extra text to be pasted before main text.\n // snippetAfter is an optional text to be pasted after. It may also include\n // \"|\" symbol to designate desired cursor position after paste.\n let suggestionText = text;\n if (typeof explanation !== 'undefined') {\n suggestionText += `${explanation}`;\n }\n\n return {\n text,\n snippetBefore: snippetBefore || '',\n snippetAfter: snippetAfter || '',\n suggestionText,\n };\n}\n\n// Main DjangoQL object\nconst DjangoQL = function (options) {\n let cacheSize = 100;\n\n this.options = options;\n this.currentModel = null;\n this.models = {};\n this.suggestionsAPIUrl = null;\n\n this.token = token;\n this.lexer = lexer;\n\n this.prefix = '';\n this.suggestions = [];\n this.selected = null;\n this.valuesCaseSensitive = false;\n this.highlightCaseSensitive = true;\n\n this.textarea = null;\n this.completion = null;\n this.completionUL = null;\n this.completionEnabled = false;\n\n // Initialization\n if (!isObject(options)) {\n this.logError('Please pass an object with initialization parameters');\n return;\n }\n this.loadIntrospections(options.introspections);\n if (typeof options.selector === 'string') {\n this.textarea = document.querySelector(options.selector);\n } else {\n this.textarea = options.selector;\n }\n if (!this.textarea) {\n this.logError(`Element not found by selector: ${options.selector}`);\n return;\n }\n if (this.textarea.tagName !== 'TEXTAREA') {\n this.logError(\n 'selector must be pointing to