追加一个字[中英文]到树中
@param $tree
@param $code
@param $word
@param bool $end
@param array $data
@param string $full_str
@return mixed
513663
private function &_appendWordToTree(&$tree, $code, $word, $end = false, $data = array(), $full_str = '', $is_py) {
        if (!isset($tree[$code])) {
            $tree[$code] = array(
                'end' => $end,
                'child' => array(),
                'value' => $word,
            );
        }
        if ($end) {
            $tree[$code]['end'] = true;
            $tree[$code]['is_py'] = $is_py;
            //拼音不需要full 拼音根据读音多样性对应多个词语 重复词语覆盖data
            if ($is_py) {
                $is_change = false;
                if(isset($tree[$code]["chinese_list"]) && count($tree[$code]["chinese_list"])>0) {
                    foreach ($tree[$code]["chinese_list"] as $key => &$node) {
                        if ($node['word'] == $full_str) {
                            $node['data'] = $data;
                            $is_change = true;
                            break;
                        }
                    }
                }
                if(!$is_change){
                    $tree[$code]['chinese_list'][] = ["word" => $full_str, "data" => $data];
                }
            } else {
                $tree[$code]['full'] = $full_str;
                $tree[$code]['data'] = $data;
            }
        }

        return $tree[$code]['child'];
    }
721701
public function getBlock(Tree $tree, int $block_id, string $ctype = '', array $cfg = []): string
    {
        $request       = app(ServerRequestInterface::class);
        $default_start = $this->getBlockSetting($block_id, 'start', '0');
        $filter        = $this->getBlockSetting($block_id, 'filter', 'all');
        $controls      = $this->getBlockSetting($block_id, 'controls', '1');
        $start         = (bool) $request->get('start', $default_start);

        $media_types = [
            $this->getBlockSetting($block_id, 'filter_audio', '0') ? 'audio' : null,
            $this->getBlockSetting($block_id, 'filter_book', '1') ? 'book' : null,
            $this->getBlockSetting($block_id, 'filter_card', '1') ? 'card' : null,
            $this->getBlockSetting($block_id, 'filter_certificate', '1') ? 'certificate' : null,
            $this->getBlockSetting($block_id, 'filter_coat', '1') ? 'coat' : null,
            $this->getBlockSetting($block_id, 'filter_document', '1') ? 'document' : null,
            $this->getBlockSetting($block_id, 'filter_electronic', '1') ? 'electronic' : null,
            $this->getBlockSetting($block_id, 'filter_fiche', '1') ? 'fiche' : null,
            $this->getBlockSetting($block_id, 'filter_film', '1') ? 'film' : null,
            $this->getBlockSetting($block_id, 'filter_magazine', '1') ? 'magazine' : null,
            $this->getBlockSetting($block_id, 'filter_manuscript', '1') ? 'manuscript' : null,
            $this->getBlockSetting($block_id, 'filter_map', '1') ? 'map' : null,
            $this->getBlockSetting($block_id, 'filter_newspaper', '1') ? 'newspaper' : null,
            $this->getBlockSetting($block_id, 'filter_other', '1') ? 'other' : null,
            $this->getBlockSetting($block_id, 'filter_painting', '1') ? 'painting' : null,
            $this->getBlockSetting($block_id, 'filter_photo', '1') ? 'photo' : null,
            $this->getBlockSetting($block_id, 'filter_tombstone', '1') ? 'tombstone' : null,
            $this->getBlockSetting($block_id, 'filter_video', '0') ? 'video' : null,
        ];

        $media_types = array_filter($media_types);

        // We can apply the filters using SQL
        // Do not use "ORDER BY RAND()" - it is very slow on large tables. Use PHP::array_rand() instead.
        $all_media = DB::table('media')
            ->join('media_file', static function (JoinClause $join): void {
                $join
                    ->on('media_file.m_file', '=', 'media.m_file')
                    ->on('media_file.m_id', '=', 'media.m_id');
            })
            ->where('media.m_file', '=', $tree->id())
            ->whereIn('media_file.multimedia_format', ['jpg', 'jpeg', 'png', 'gif', 'tiff', 'bmp'])
            ->whereIn('media_file.source_media_type', $media_types)
            ->pluck('media.m_id')
            ->all();

        // Keep looking through the media until a suitable one is found.
        $random_media = null;
        while (!empty($all_media)) {
            $n          = array_rand($all_media);
            $media      = Media::getInstance($all_media[$n], $tree);
            $media_file = $media->firstImageFile();
            if ($media->canShow() && $media_file instanceof MediaFile && !$media_file->isExternal()) {
                // Check if it is linked to a suitable individual
                foreach ($media->linkedIndividuals('OBJE') as $indi) {
                    if (
                        $filter === 'all' ||
                        $filter === 'indi' && strpos($indi->gedcom(), "\n1 OBJE @" . $media->xref() . '@') !== false ||
                        $filter === 'event' && strpos($indi->gedcom(), "\n2 OBJE @" . $media->xref() . '@') !== false
                    ) {
                        // Found one :-)
                        $random_media = $media;
                        break 2;
                    }
                }
            }
            unset($all_media[$n]);
        }

        if ($random_media) {
            $content = view('modules/random_media/slide-show', [
                'block_id'            => $block_id,
                'media'               => $random_media,
                'media_file'          => $random_media->firstImageFile(),
                'show_controls'       => $controls,
                'start_automatically' => $start,
                'tree'                => $tree,
            ]);
        } else {
            $content = I18N::translate('This family tree has no images to display.');
        }

        if ($ctype !== '') {
            if ($ctype === 'gedcom' && Auth::isManager($tree)) {
                $config_url = route('tree-page-block-edit', [
                    'block_id' => $block_id,
                    'ged'      => $tree->name(),
                ]);
            } elseif ($ctype === 'user' && Auth::check()) {
                $config_url = route('user-page-block-edit', [
                    'block_id' => $block_id,
                    'ged'      => $tree->name(),
                ]);
            } else {
                $config_url = '';
            }

            return view('modules/block-template', [
                'block'      => Str::kebab($this->name()),
                'id'         => $block_id,
                'config_url' => $config_url,
                'title'      => $this->title(),
                'content'    => $content,
            ]);
        }

        return $content;
    }
762716
@Override @DefinedBy(Api.COMPILER_TREE)
    public DCDocComment newDocCommentTree(List<? extends DocTree> fullBody, List<? extends DocTree> tags) {
        ListBuffer<DCTree> lb = new ListBuffer<>();
        lb.addAll(cast(fullBody));
        List<DCTree> fBody = lb.toList();

        // A dummy comment to keep the diagnostics logic happy.
        Comment c = new Comment() {
            @Override
            public String getText() {
                return null;
            }

            @Override
            public int getSourcePos(int index) {
                return Position.NOPOS;
            }

            @Override
            public CommentStyle getStyle() {
                return CommentStyle.JAVADOC;
            }

            @Override
            public boolean isDeprecated() {
                return false;
            }
        };
        Pair<List<DCTree>, List<DCTree>> pair = splitBody(fullBody);
        DCDocComment tree = new DCDocComment(c, fBody, pair.fst, pair.snd, cast(tags));
        return tree;
    }
326543
def create_tree_from_string(line):
    
    depth         = 0
    current_word  = ""
    root          = None
    current_node  = root

    for char in line:
        if char == '(':
            if current_node is not None and len(current_word) > 0:
                attribute_text_label(current_node, current_word)
                current_word = ""
            depth += 1
            if depth > 1:
                # replace current head node by this node:
                child = LabeledTree(depth=depth)
                current_node.add_child(child)
                current_node = child
                root.add_general_child(child)
            else:
                root = LabeledTree(depth=depth)
                root.add_general_child(root)
                current_node = root

        elif char == ')':
            # assign current word:
            if len(current_word) > 0:
                attribute_text_label(current_node, current_word)
                current_word = ""

            # go up a level:
            depth -= 1
            if current_node.parent != None:
                current_node.parent.udepth = max(current_node.udepth+1, current_node.parent.udepth)
            current_node = current_node.parent
        else:
            # add to current read word
            current_word += char
    if depth != 0:
        raise ParseError("Not an equal amount of closing and opening parentheses")

    return root
495977
public static function create(string $tree_name, string $tree_title): Tree
    {
        try {
            // Create a new tree
            DB::table('gedcom')->insert([
                'gedcom_name' => $tree_name,
            ]);

            $tree_id = (int) DB::connection()->getPdo()->lastInsertId();

            $tree = new self($tree_id, $tree_name, $tree_title);
        } catch (PDOException $ex) {
            // A tree with that name already exists?
            return self::findByName($tree_name);
        }

        $tree->setPreference('imported', '0');
        $tree->setPreference('title', $tree_title);

        // Set preferences from default tree
        (new Builder(DB::connection()))->from('gedcom_setting')->insertUsing(
            ['gedcom_id', 'setting_name', 'setting_value'],
            static function (Builder $query) use ($tree_id): void {
                $query
                    ->select([DB::raw($tree_id), 'setting_name', 'setting_value'])
                    ->from('gedcom_setting')
                    ->where('gedcom_id', '=', -1);
            }
        );

        (new Builder(DB::connection()))->from('default_resn')->insertUsing(
            ['gedcom_id', 'tag_type', 'resn'],
            static function (Builder $query) use ($tree_id): void {
                $query
                    ->select([DB::raw($tree_id), 'tag_type', 'resn'])
                    ->from('default_resn')
                    ->where('gedcom_id', '=', -1);
            }
        );

        // Gedcom and privacy settings
        $tree->setPreference('CONTACT_USER_ID', (string) Auth::id());
        $tree->setPreference('WEBMASTER_USER_ID', (string) Auth::id());
        $tree->setPreference('LANGUAGE', WT_LOCALE); // Default to the current admin’s language

        switch (WT_LOCALE) {
            case 'es':
                $tree->setPreference('SURNAME_TRADITION', 'spanish');
                break;
            case 'is':
                $tree->setPreference('SURNAME_TRADITION', 'icelandic');
                break;
            case 'lt':
                $tree->setPreference('SURNAME_TRADITION', 'lithuanian');
                break;
            case 'pl':
                $tree->setPreference('SURNAME_TRADITION', 'polish');
                break;
            case 'pt':
            case 'pt-BR':
                $tree->setPreference('SURNAME_TRADITION', 'portuguese');
                break;
            default:
                $tree->setPreference('SURNAME_TRADITION', 'paternal');
                break;
        }

        // Genealogy data
        // It is simpler to create a temporary/unimported GEDCOM than to populate all the tables...
        /* I18N: This should be a common/default/placeholder name of an individual. Put slashes around the surname. */
        $john_doe = I18N::translate('John /DOE/');
        $note     = I18N::translate('Edit this individual and replace their details with your own.');
        $gedcom   = "0 HEAD\n1 CHAR UTF-8\n0 @X1@ INDI\n1 NAME {$john_doe}\n1 SEX M\n1 BIRT\n2 DATE 01 JAN 1850\n2 NOTE {$note}\n0 TRLR\n";

        DB::table('gedcom_chunk')->insert([
            'gedcom_id'  => $tree_id,
            'chunk_data' => $gedcom,
        ]);

        // Update our cache
        self::$trees[$tree->id] = $tree;

        return $tree;
    }
818964
static public function endsWith($string, $needle, $message = null, $propertyPath = null, $encoding = 'utf8')
        {
            static::string($string);

            $stringPosition = mb_strlen($string, $encoding) - mb_strlen($needle, $encoding);

            if (mb_strripos($string, $needle, null, $encoding) !== $stringPosition) {
                $message = $message ?: sprintf(
                    'Value "%s" does not end with "%s".',
                    static::stringify($string),
                    static::stringify($needle)
                );

                $constraints = array('needle' => $needle, 'encoding' => $encoding);

                throw static::createException($string, $message, static::INVALID_STRING_END, $propertyPath, $constraints);
            }
        }
867445
function(str) {
  var abbrRegex = /^\-(\w+?)$/,
      fullRegex = /^\-\-(no\-)?(.+?)(?:=(.+))?$/,
      valRegex = /^[^\-].*/;

  var charMatch = abbrRegex.exec(str),
      chars = charMatch && charMatch[1].split("");

  var fullMatch = fullRegex.exec(str),
      full = fullMatch && fullMatch[2];

  var isValue = str !== undefined && (str === "" || valRegex.test(str));
  var value;
  if (isValue) {
    value = str;
  }
  else if (full) {
    value = fullMatch[1] ? false : fullMatch[3];
  }

  return {
    str: str,
    chars: chars,
    full: full,
    value: value,
    isValue: isValue
  }
}
1277191
void createBinaryTree()
    {
        int[] point = new int[VocabWord.MAX_CODE_LENGTH];
        char[] code = new char[VocabWord.MAX_CODE_LENGTH];
        int[] count = new int[vocabSize * 2 + 1];
        char[] binary = new char[vocabSize * 2 + 1];
        int[] parentNode = new int[vocabSize * 2 + 1];

        for (int i = 0; i < vocabSize; i++)
            count[i] = vocab[i].cn;
        for (int i = vocabSize; i < vocabSize * 2; i++)
            count[i] = Integer.MAX_VALUE;
        int pos1 = vocabSize - 1;
        int pos2 = vocabSize;
        // Following algorithm constructs the Huffman tree by adding one node at a time
        int min1i, min2i;
        for (int i = 0; i < vocabSize - 1; i++)
        {
            // First, find two smallest nodes 'min1, min2'
            if (pos1 >= 0)
            {
                if (count[pos1] < count[pos2])
                {
                    min1i = pos1;
                    pos1--;
                }
                else
                {
                    min1i = pos2;
                    pos2++;
                }
            }
            else
            {
                min1i = pos2;
                pos2++;
            }
            if (pos1 >= 0)
            {
                if (count[pos1] < count[pos2])
                {
                    min2i = pos1;
                    pos1--;
                }
                else
                {
                    min2i = pos2;
                    pos2++;
                }
            }
            else
            {
                min2i = pos2;
                pos2++;
            }
            count[vocabSize + i] = count[min1i] + count[min2i];
            parentNode[min1i] = vocabSize + i;
            parentNode[min2i] = vocabSize + i;
            binary[min2i] = 1;
        }
        // Now assign binary code to each vocabulary word
        for (int j = 0; j < vocabSize; j++)
        {
            int k = j;
            int i = 0;
            while (true)
            {
                code[i] = binary[k];
                point[i] = k;
                i++;
                k = parentNode[k];
                if (k == vocabSize * 2 - 2) break;
            }
            vocab[j].codelen = i;
            vocab[j].point[0] = vocabSize - 2;
            for (k = 0; k < i; k++)
            {
                vocab[j].code[i - k - 1] = code[k];
                vocab[j].point[i - k] = point[k] - vocabSize;
            }
        }
    }
909761
function processSubtree( $element, &$lastHandlerResult )
    {
        $ret = null;
        $tmp = null;

        // Call "Init handler"
        $this->callOutputHandler( 'initHandler', $element, $tmp );

        $debug = eZDebugSetting::isConditionTrue( 'kernel-datatype-ezxmltext', eZDebug::LEVEL_DEBUG );

        // Process children
        if ( $element->hasChildNodes() )
        {
            // Make another copy of children to save primary structure
            $childNodes = $element->childNodes;
            $childrenCount = $childNodes->length;

            // we can not loop directly over the childNodes property, because this will change while we are working on it's parent's children
            $children = array();
            foreach ( $childNodes as $childNode )
            {
                $children[] = $childNode;
            }

            $lastResult = null;
            $newElements = array();
            foreach ( $children as $child )
            {
                if ( $debug )
                {
                    eZDebug::writeDebug( 'processing children, current child: ' . $child->nodeName, eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext', __METHOD__ ) );
                }

                $childReturn = $this->processSubtree( $child, $lastResult );

                unset( $lastResult );
                if ( isset( $childReturn['result'] ) )
                {
                    if ( $debug )
                    {
                        eZDebug::writeDebug( 'return result is set for child ' . $child->nodeName, eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext', __METHOD__ ) );
                    }

                    $lastResult = $childReturn['result'];
                }

                if ( isset( $childReturn['new_elements'] ) )
                {
                    $newElements = array_merge( $newElements, $childReturn['new_elements'] );
                }

                if ( $this->QuitProcess )
                {
                    return $ret;
                }
            }

            if ( $debug )
            {
                eZDebug::writeDebug( $this->Document->saveXML(),
                                     eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                                  'XML before processNewElements for element ' . $element->nodeName ) );
            }

            // process elements created in children handlers
            $this->processNewElements( $newElements );

            if ( $debug )
            {
                eZDebug::writeDebug( $this->Document->saveXML(),
                                     eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                                  'XML after processNewElements for element ' . $element->nodeName ) );
            }
        }

        // Call "Structure handler"
        if ( $debug )
        {
            eZDebug::writeDebug( $this->Document->saveXML(),
                                 eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                              'XML before callOutputHandler structHandler for element ' . $element->nodeName ) );
        }

        $ret = $this->callOutputHandler( 'structHandler', $element, $lastHandlerResult );

        if ( $debug )
        {
            eZDebug::writeDebug( $this->Document->saveXML(),
                                 eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                              'XML after callOutputHandler structHandler for element ' . $element->nodeName ) );
            eZDebug::writeDebug( $ret,
                                 eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                              'return value of callOutputHandler structHandler for element ' . $element->nodeName ) );
        }

        // Process by schema (check if element is allowed to exist)
        if ( !$this->processBySchemaPresence( $element ) )
        {
            if ( $debug )
            {
                eZDebug::writeDebug( $this->Document->saveXML(),
                                     eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                                  'XML after failed processBySchemaPresence for element ' . $element->nodeName ) );
            }
            return $ret;
        }

        if ( $debug )
        {
            eZDebug::writeDebug( $this->Document->saveXML(),
                                 eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                              'XML after processBySchemaPresence for element ' . $element->nodeName ) );
        }

        // Process by schema (check place in the tree)
        if ( !$this->processBySchemaTree( $element ) )
        {
            if ( $debug )
            {
                eZDebug::writeDebug( $this->Document->saveXML(),
                                     eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                                  'XML after failed processBySchemaTree for element ' . $element->nodeName ) );
            }
            return $ret;
        }

        if ( $debug )
        {
            eZDebug::writeDebug( $this->Document->saveXML(),
                                 eZDebugSetting::changeLabel( 'kernel-datatype-ezxmltext',
                                                              'XML after processBySchemaTree for element ' . $element->nodeName ) );
        }


        $tmp = null;
        // Call "Publish handler"
        $this->callOutputHandler( 'publishHandler', $element, $tmp );

        // Process attributes according to the schema
        if ( $element->hasAttributes() )
        {
            if ( !$this->XMLSchema->hasAttributes( $element ) )
            {
                eZXMLInputParser::removeAllAttributes( $element );
            }
            else
            {
                $this->processAttributesBySchema( $element );
            }
        }
        return $ret;
    }
499774
public function _buildTree(&$rootDoc, &$class, $depth = NULL)
    {
        if ($depth === NULL) {
            $start = TRUE;
            $depth = 0;
        } else {
            $start = FALSE;
        }
        $output = '';
        $undefinedClass = FALSE;
        if ($class->superclass()) {
            $superclass =& $rootDoc->classNamed($class->superclass());
            if ($superclass) {
                $result = $this->_buildTree($rootDoc, $superclass, $depth);
                $output .= $result[0];
                $depth = ++$result[1];
            } else {
                $output .= $class->superclass().'<br>';
                $output .= str_repeat('   ', $depth).' └─';
                $depth++;
                $undefinedClass = TRUE;
            }
        }
        if ($depth > 0 && !$undefinedClass) {
            $output .= str_repeat('   ', $depth).' └─';
        }
        if ($start) {
            $output .= '<strong>'.$class->name().'</strong><br />';
        } else {
            $output .= '<a href="'.str_repeat('../', $this->_depth).$class->asPath().'">'.$class->name().'</a><br>';
        }

        return array($output, $depth);
    }
13780
static function buildFromString($str, $lowercase=true, $forceTagsClosed=true, $target_charset = self::DEFAULT_TARGET_CHARSET, $stripRN=true, $defaultBRText=self::DEFAULT_BR_TEXT, $defaultSpanText=self::DEFAULT_SPAN_TEXT)
    {
        $dom = new Tree(null, $lowercase, $forceTagsClosed, $target_charset, $stripRN, $defaultBRText, $defaultSpanText);
        if (empty($str) or strlen($str) > self::MAX_FILE_SIZE)
        {
            $dom->clear();
            return false;
        }
        $dom->load($str, $lowercase, $stripRN);
        return $dom;
    }
639647
function _displayTree($tree, $parent = NULL) {
        $outputList = TRUE;
        foreach ($tree as $name => $element) {
            if ($element->superclass() == $parent) {
                if ($outputList)
                    echo "<ul>\n";
                echo "<li><a href=\"", $this->_asURL($element), "\">", $element->qualifiedName(), "</a>";
                $this->_displayTree($tree, $name);
                echo "</li>\n";
                $outputList = FALSE;
            }
        }
        if (!$outputList)
            echo "</ul>\n";
    }
209010
static function snippet($text, $keywords, $limit, $max_length, $around = array('<b>', '</b>'))
	{
		$result = array();

		$keywords = self::normalize($keywords);
		list($pre, $post) = $around;
		$prev = array();
		$after = false;

		foreach(self::normalize_hash($text) as $word_orig => $word_norm)
		{
			$is_kw = false;
			if(in_array($word_norm, $keywords))
			{
				$prev[] = $pre.$word_orig.$post;
				$is_kw = true;
			}
			else
				$prev[] = $word_orig;

			if($is_kw)
			{
				if($after)
				{
					$result = array_merge($result, $prev);
					$prev = array();
				}
				else
				{
					$result = array_merge($result, count($prev) > $limit ? array('&#133') : array(), array_slice($prev, -$limit-1));
					$prev = array();
				}

				$after = true;
			}
			else
			{
				if($after && count($prev) >= $limit)
				{
					$after = false;
					$result = array_merge($result, $prev);
					$prev = array();
				}
			}
		}

		if($after)
			$result = array_merge($result, array('&#133'), $prev);

		return strip_text(join(' ', $result).'&#133;', $max_length);
	}
156524
protected function &searchTree(
        /*# string */ $key,
        /*# array */ &$tree,
        /*# bool */ $create = false
    ) {
        $found = &$tree;
        $parts = explode($this->field_splitter, $key);
        while (null !== ($part = array_shift($parts))) {
            if (!isset($found[$part])) {
                if ($create) {
                    $found[$part] = [];
                } else {
                    $bad = null;
                    return $bad;
                }
            }
            $found = &$found[$part];
        }
        return $found;
    }
828372
def _complete(self, text, line, begin, end):
        
        line = line[:end]  # Ignore characters following the cursor.
        fullargs = self.split_line(line)[1:]
        args = fullargs[:]
        options = self.deep_scan_parser(self.argparser)

        # Walk into options tree if subcommands are detected.
        last_subcommand = None
        while True:
            for key, completers in options.items():
                if key in args and hasattr(completers[0], 'items'):
                    args.remove(key)
                    last_subcommand = key
                    options = completers[0]
                    break
            else:
                break

        if text == last_subcommand:
            # We have to specially catch the case where the last argument is
            # the key used to find our subparser.  More specifically when the
            # cursor is not preceded by a space too, as this prevents the
            # completion routines from continuing.  The simplest way without
            # complicating the algo for coming up with our options list is to
            # simply shortcut the completer by returning a single item.
            # Subsequent tabs will work normally.
            return {text}

        # Look for incomplete actions.
        choices = set(x for x in options
                      if x is not None and x.startswith(text))
        arg_buf = []
        pos_args = []
        trailing_action = None
        # The slice below skips the last arg if it is 'active'.
        for x in reversed(args[:-1 if text else None]):
            if x in options:
                action = options[x][0]
                action.consume(arg_buf)
                pos_args.extend(arg_buf)
                del arg_buf[:]
                if action.full:
                    choices -= {action.key}
                if not trailing_action:
                    trailing_action = action
                    if not action.full:
                        if action.reached_min:
                            choices |= action(self, text, fullargs)
                            choices -= {action.key}
                        else:
                            choices = action(self, text, fullargs)
                            break
            else:
                arg_buf.insert(0, x)
        pos_args.extend(arg_buf)

        # Feed any remaining arguments in the buffer to positionals so long as
        # there isn't a trailing action that can still consume.
        if None in options and (not trailing_action or trailing_action.full):
            for x_action in options[None]:
                x_action.consume(pos_args)
                if not x_action.reached_min:
                    choices = x_action(self, text, fullargs)
                    break
                elif not x_action.full:
                    choices |= x_action(self, text, fullargs)
        return choices
1228434
private function faqsExist(Tree $tree, string $language): bool
    {
        return DB::table('block')
            ->join('block_setting', 'block_setting.block_id', '=', 'block.block_id')
            ->where('module_name', '=', $this->name())
            ->where('setting_name', '=', 'languages')
            ->where(static function (Builder $query) use ($tree): void {
                $query
                    ->whereNull('gedcom_id')
                    ->orWhere('gedcom_id', '=', $tree->id());
            })
            ->select(['setting_value AS languages'])
            ->get()
            ->filter(static function (stdClass $faq) use ($language): bool {
                return $faq->languages === '' || in_array($language, explode(',', $faq->languages), true);
            })
            ->isNotEmpty();
    }
860747
@Override
	public String getFullPredString()
	{
		if (valuetree.getPredicate() == null)
		{
			return "";
		}
		String result = valuetree.getPredicate().toString();
		return result;
	}