// File: /workspace/github_c_makefile_star2_O0/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: flattenSubquery
static int flattenSubquery(
  Parse *pParse,       /* Parsing context */
  Select *p,           /* The parent or outer SELECT statement */
  int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */
  int isAgg,           /* True if outer SELECT uses aggregate functions */
  int subqueryIsAgg    /* True if the subquery uses aggregate functions */
){
  const char *zSavedAuthContext = pParse->zAuthContext;
  Select *pParent;
  Select *pSub;       /* The inner query or "subquery" */
  Select *pSub1;      /* Pointer to the rightmost select in sub-query */
  SrcList *pSrc;      /* The FROM clause of the outer query */
  SrcList *pSubSrc;   /* The FROM clause of the subquery */
  ExprList *pList;    /* The result set of the outer query */
  int iParent;        /* VDBE cursor number of the pSub result set temp table */
  int i;              /* Loop counter */
  Expr *pWhere;                    /* The WHERE clause */
  struct SrcList_item *pSubitem;   /* The subquery */
  sqlite3 *db = pParse->db;

  /* Check to see if flattening is permitted.  Return 0 if not.
  */
  assert( p!=0 );
  assert( p->pPrior==0 );  /* Unable to flatten compound queries */
  if( OptimizationDisabled(db, SQLITE_QueryFlattener) ) return 0;
  pSrc = p->pSrc;
  assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
  pSubitem = &pSrc->a[iFrom];
  iParent = pSubitem->iCursor;
  pSub = pSubitem->pSelect;
  assert( pSub!=0 );
  if( isAgg && subqueryIsAgg ) return 0;                 /* Restriction (1)  */
  if( subqueryIsAgg && pSrc->nSrc>1 ) return 0;          /* Restriction (2)  */
  pSubSrc = pSub->pSrc;
  assert( pSubSrc );
  /* Prior to version 3.1.2, when LIMIT and OFFSET had to be simple constants,
  ** not arbitrary expresssions, we allowed some combining of LIMIT and OFFSET
  ** because they could be computed at compile-time.  But when LIMIT and OFFSET
  ** became arbitrary expressions, we were forced to add restrictions (13)
  ** and (14). */
  if( pSub->pLimit && p->pLimit ) return 0;              /* Restriction (13) */
  if( pSub->pOffset ) return 0;                          /* Restriction (14) */
  if( p->pRightmost && pSub->pLimit ){
    return 0;                                            /* Restriction (15) */
  }
  if( pSubSrc->nSrc==0 ) return 0;                       /* Restriction (7)  */
  if( pSub->selFlags & SF_Distinct ) return 0;           /* Restriction (5)  */
  if( pSub->pLimit && (pSrc->nSrc>1 || isAgg) ){
     return 0;         /* Restrictions (8)(9) */
  }
  if( (p->selFlags & SF_Distinct)!=0 && subqueryIsAgg ){
     return 0;         /* Restriction (6)  */
  }
  if( p->pOrderBy && pSub->pOrderBy ){
     return 0;                                           /* Restriction (11) */
  }
  if( isAgg && pSub->pOrderBy ) return 0;                /* Restriction (16) */
  if( pSub->pLimit && p->pWhere ) return 0;              /* Restriction (19) */
  if( pSub->pLimit && (p->selFlags & SF_Distinct)!=0 ){
     return 0;         /* Restriction (21) */
  }

  /* OBSOLETE COMMENT 1:
  ** Restriction 3:  If the subquery is a join, make sure the subquery is 
  ** not used as the right operand of an outer join.  Examples of why this
  ** is not allowed:
  **
  **         t1 LEFT OUTER JOIN (t2 JOIN t3)
  **
  ** If we flatten the above, we would get
  **
  **         (t1 LEFT OUTER JOIN t2) JOIN t3
  **
  ** which is not at all the same thing.
  **
  ** OBSOLETE COMMENT 2:
  ** Restriction 12:  If the subquery is the right operand of a left outer
  ** join, make sure the subquery has no WHERE clause.
  ** An examples of why this is not allowed:
  **
  **         t1 LEFT OUTER JOIN (SELECT * FROM t2 WHERE t2.x>0)
  **
  ** If we flatten the above, we would get
  **
  **         (t1 LEFT OUTER JOIN t2) WHERE t2.x>0
  **
  ** But the t2.x>0 test will always fail on a NULL row of t2, which
  ** effectively converts the OUTER JOIN into an INNER JOIN.
  **
  ** THIS OVERRIDES OBSOLETE COMMENTS 1 AND 2 ABOVE:
  ** Ticket #3300 shows that flattening the right term of a LEFT JOIN
  ** is fraught with danger.  Best to avoid the whole thing.  If the
  ** subquery is the right term of a LEFT JOIN, then do not flatten.
  */
  if( (pSubitem->jointype & JT_OUTER)!=0 ){
    return 0;
  }

  /* Restriction 17: If the sub-query is a compound SELECT, then it must
  ** use only the UNION ALL operator. And none of the simple select queries
  ** that make up the compound SELECT are allowed to be aggregate or distinct
  ** queries.
  */
  if( pSub->pPrior ){
    if( pSub->pOrderBy ){
      return 0;  /* Restriction 20 */
    }
    if( isAgg || (p->selFlags & SF_Distinct)!=0 || pSrc->nSrc!=1 ){
      return 0;
    }
    for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
      testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct );
      testcase( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))==SF_Aggregate );
      assert( pSub->pSrc!=0 );
      if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0
       || (pSub1->pPrior && pSub1->op!=TK_ALL) 
       || pSub1->pSrc->nSrc<1
       || pSub->pEList->nExpr!=pSub1->pEList->nExpr
      ){
        return 0;
      }
      testcase( pSub1->pSrc->nSrc>1 );
    }

    /* Restriction 18. */
    if( p->pOrderBy ){
      int ii;
      for(ii=0; ii<p->pOrderBy->nExpr; ii++){
        if( p->pOrderBy->a[ii].iOrderByCol==0 ) return 0;
      }
    }
  }

  /***** If we reach this point, flattening is permitted. *****/

  /* Authorize the subquery */
  pParse->zAuthContext = pSubitem->zName;
  TESTONLY(i =) sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
  testcase( i==SQLITE_DENY );
  pParse->zAuthContext = zSavedAuthContext;

  /* If the sub-query is a compound SELECT statement, then (by restrictions
  ** 17 and 18 above) it must be a UNION ALL and the parent query must 
  ** be of the form:
  **
  **     SELECT <expr-list> FROM (<sub-query>) <where-clause> 
  **
  ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block
  ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or 
  ** OFFSET clauses and joins them to the left-hand-side of the original
  ** using UNION ALL operators. In this case N is the number of simple
  ** select statements in the compound sub-query.
  **
  ** Example:
  **
  **     SELECT a+1 FROM (
  **        SELECT x FROM tab
  **        UNION ALL
  **        SELECT y FROM tab
  **        UNION ALL
  **        SELECT abs(z*2) FROM tab2
  **     ) WHERE a!=5 ORDER BY 1
  **
  ** Transformed into:
  **
  **     SELECT x+1 FROM tab WHERE x+1!=5
  **     UNION ALL
  **     SELECT y+1 FROM tab WHERE y+1!=5
  **     UNION ALL
  **     SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5
  **     ORDER BY 1
  **
  ** We call this the "compound-subquery flattening".
  */
  for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
    Select *pNew;
    ExprList *pOrderBy = p->pOrderBy;
    Expr *pLimit = p->pLimit;
    Expr *pOffset = p->pOffset;
    Select *pPrior = p->pPrior;
    p->pOrderBy = 0;
    p->pSrc = 0;
    p->pPrior = 0;
    p->pLimit = 0;
    p->pOffset = 0;
    pNew = sqlite3SelectDup(db, p, 0);
    p->pOffset = pOffset;
    p->pLimit = pLimit;
    p->pOrderBy = pOrderBy;
    p->pSrc = pSrc;
    p->op = TK_ALL;
    p->pRightmost = 0;
    if( pNew==0 ){
      pNew = pPrior;
    }else{
      pNew->pPrior = pPrior;
      pNew->pRightmost = 0;
    }
    p->pPrior = pNew;
    if( db->mallocFailed ) return 1;
  }

  /* Begin flattening the iFrom-th entry of the FROM clause 
  ** in the outer query.
  */
  pSub = pSub1 = pSubitem->pSelect;

  /* Delete the transient table structure associated with the
  ** subquery
  */
  sqlite3DbFree(db, pSubitem->zDatabase);
  sqlite3DbFree(db, pSubitem->zName);
  sqlite3DbFree(db, pSubitem->zAlias);
  pSubitem->zDatabase = 0;
  pSubitem->zName = 0;
  pSubitem->zAlias = 0;
  pSubitem->pSelect = 0;

  /* Defer deleting the Table object associated with the
  ** subquery until code generation is
  ** complete, since there may still exist Expr.pTab entries that
  ** refer to the subquery even after flattening.  Ticket #3346.
  **
  ** pSubitem->pTab is always non-NULL by test restrictions and tests above.
  */
  if( ALWAYS(pSubitem->pTab!=0) ){
    Table *pTabToDel = pSubitem->pTab;
    if( pTabToDel->nRef==1 ){
      Parse *pToplevel = sqlite3ParseToplevel(pParse);
      pTabToDel->pNextZombie = pToplevel->pZombieTab;
      pToplevel->pZombieTab = pTabToDel;
    }else{
      pTabToDel->nRef--;
    }
    pSubitem->pTab = 0;
  }

  /* The following loop runs once for each term in a compound-subquery
  ** flattening (as described above).  If we are doing a different kind
  ** of flattening - a flattening other than a compound-subquery flattening -
  ** then this loop only runs once.
  **
  ** This loop moves all of the FROM elements of the subquery into the
  ** the FROM clause of the outer query.  Before doing this, remember
  ** the cursor number for the original outer query FROM element in
  ** iParent.  The iParent cursor will never be used.  Subsequent code
  ** will scan expressions looking for iParent references and replace
  ** those references with expressions that resolve to the subquery FROM
  ** elements we are now copying in.
  */
  for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
    int nSubSrc;
    u8 jointype = 0;
    pSubSrc = pSub->pSrc;     /* FROM clause of subquery */
    nSubSrc = pSubSrc->nSrc;  /* Number of terms in subquery FROM clause */
    pSrc = pParent->pSrc;     /* FROM clause of the outer query */

    if( pSrc ){
      assert( pParent==p );  /* First time through the loop */
      jointype = pSubitem->jointype;
    }else{
      assert( pParent!=p );  /* 2nd and subsequent times through the loop */
      pSrc = pParent->pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
      if( pSrc==0 ){
        assert( db->mallocFailed );
        break;
      }
    }

    /* The subquery uses a single slot of the FROM clause of the outer
    ** query.  If the subquery has more than one element in its FROM clause,
    ** then expand the outer query to make space for it to hold all elements
    ** of the subquery.
    **
    ** Example:
    **
    **    SELECT * FROM tabA, (SELECT * FROM sub1, sub2), tabB;
    **
    ** The outer query has 3 slots in its FROM clause.  One slot of the
    ** outer query (the middle slot) is used by the subquery.  The next
    ** block of code will expand the out query to 4 slots.  The middle
    ** slot is expanded to two slots in order to make space for the
    ** two elements in the FROM clause of the subquery.
    */
    if( nSubSrc>1 ){
      pParent->pSrc = pSrc = sqlite3SrcListEnlarge(db, pSrc, nSubSrc-1,iFrom+1);
      if( db->mallocFailed ){
        break;
      }
    }

    /* Transfer the FROM clause terms from the subquery into the
    ** outer query.
    */
    for(i=0; i<nSubSrc; i++){
      sqlite3IdListDelete(db, pSrc->a[i+iFrom].pUsing);
      pSrc->a[i+iFrom] = pSubSrc->a[i];
      memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
    }
    pSrc->a[iFrom].jointype = jointype;
  
    /* Now begin substituting subquery result set expressions for 
    ** references to the iParent in the outer query.
    ** 
    ** Example:
    **
    **   SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b;
    **   \                     \_____________ subquery __________/          /
    **    \_____________________ outer query ______________________________/
    **
    ** We look at every expression in the outer query and every place we see
    ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
    */
    pList = pParent->pEList;
    for(i=0; i<pList->nExpr; i++){
      if( pList->a[i].zName==0 ){
        char *zName = sqlite3DbStrDup(db, pList->a[i].zSpan);
        sqlite3Dequote(zName);
        pList->a[i].zName = zName;
      }
    }
    substExprList(db, pParent->pEList, iParent, pSub->pEList);
    if( isAgg ){
      substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
    }
    if( pSub->pOrderBy ){
      assert( pParent->pOrderBy==0 );
      pParent->pOrderBy = pSub->pOrderBy;
      pSub->pOrderBy = 0;
    }else if( pParent->pOrderBy ){
      substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
    }
    if( pSub->pWhere ){
      pWhere = sqlite3ExprDup(db, pSub->pWhere, 0);
    }else{
      pWhere = 0;
    }
    if( subqueryIsAgg ){
      assert( pParent->pHaving==0 );
      pParent->pHaving = pParent->pWhere;
      pParent->pWhere = pWhere;
      pParent->pHaving = substExpr(db, pParent->pHaving, iParent, pSub->pEList);
      pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, 
                                  sqlite3ExprDup(db, pSub->pHaving, 0));
      assert( pParent->pGroupBy==0 );
      pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy, 0);
    }else{
      pParent->pWhere = substExpr(db, pParent->pWhere, iParent, pSub->pEList);
      pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
    }
  
    /* The flattened query is distinct if either the inner or the
    ** outer query is distinct. 
    */
    pParent->selFlags |= pSub->selFlags & SF_Distinct;
  
    /*
    ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
    **
    ** One is tempted to try to add a and b to combine the limits.  But this
    ** does not work if either limit is negative.
    */
    if( pSub->pLimit ){
      pParent->pLimit = pSub->pLimit;
      pSub->pLimit = 0;
    }
  }

  /* Finially, delete what is left of the subquery and return
  ** success.
  */
  sqlite3SelectDelete(db, pSub1);

  return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq 0x248(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movzwl 0x4c(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x6c153
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
addq $0x8, %rax
movslq -0x1c(%rbp), %rcx
imulq $0x68, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rax
movl 0x3c(%rax), %eax
movl %eax, -0x64(%rbp)
movq -0x78(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x40(%rbp)
cmpl $0x0, -0x20(%rbp)
je 0x6c1a4
cmpl $0x0, -0x24(%rbp)
je 0x6c1a4
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
cmpl $0x0, -0x24(%rbp)
je 0x6c1c2
movq -0x50(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jle 0x6c1c2
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x68(%rax)
je 0x6c1f0
movq -0x18(%rbp), %rax
cmpq $0x0, 0x68(%rax)
je 0x6c1f0
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x40(%rbp), %rax
cmpq $0x0, 0x70(%rax)
je 0x6c207
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x18(%rbp), %rax
cmpq $0x0, 0x60(%rax)
je 0x6c229
movq -0x40(%rbp), %rax
cmpq $0x0, 0x68(%rax)
je 0x6c229
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x58(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x0, %eax
jne 0x6c241
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x40(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x6c25d
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x40(%rbp), %rax
cmpq $0x0, 0x68(%rax)
je 0x6c286
movq -0x50(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jg 0x6c27a
cmpl $0x0, -0x20(%rbp)
je 0x6c286
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x18(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x6c2a8
cmpl $0x0, -0x24(%rbp)
je 0x6c2a8
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x18(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x6c2ca
movq -0x40(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x6c2ca
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
cmpl $0x0, -0x20(%rbp)
je 0x6c2e7
movq -0x40(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x6c2e7
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x40(%rbp), %rax
cmpq $0x0, 0x68(%rax)
je 0x6c309
movq -0x18(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x6c309
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x40(%rbp), %rax
cmpq $0x0, 0x68(%rax)
je 0x6c330
movq -0x18(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x6c330
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x78(%rbp), %rax
movzbl 0x38(%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x6c34c
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x40(%rbp), %rax
cmpq $0x0, 0x50(%rax)
je 0x6c484
movq -0x40(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x6c372
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
cmpl $0x0, -0x20(%rbp)
jne 0x6c394
movq -0x18(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x6c394
movq -0x50(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
je 0x6c3a0
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
movq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x6c417
movq -0x48(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x5, %eax
cmpl $0x0, %eax
jne 0x6c3fb
movq -0x48(%rbp), %rax
cmpq $0x0, 0x50(%rax)
je 0x6c3d7
movq -0x48(%rbp), %rax
movzbl 0x8(%rax), %eax
cmpl $0x71, %eax
jne 0x6c3fb
movq -0x48(%rbp), %rax
movq 0x28(%rax), %rax
movzbl (%rax), %eax
cmpl $0x1, %eax
jl 0x6c3fb
movq -0x40(%rbp), %rax
movq (%rax), %rax
movl (%rax), %eax
movq -0x48(%rbp), %rcx
movq (%rcx), %rcx
cmpl (%rcx), %eax
je 0x6c407
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
jmp 0x6c409
movq -0x48(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x6c3a8
movq -0x18(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x6c482
movl $0x0, -0x84(%rbp)
movl -0x84(%rbp), %eax
movq -0x18(%rbp), %rcx
movq 0x48(%rcx), %rcx
cmpl (%rcx), %eax
jge 0x6c480
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq 0x8(%rax), %rax
movslq -0x84(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movzwl 0x1a(%rax), %eax
cmpl $0x0, %eax
jne 0x6c46d
movl $0x0, -0x4(%rbp)
jmp 0x6cbb7
jmp 0x6c46f
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x6c42c
jmp 0x6c482
jmp 0x6c484
movq -0x78(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x248(%rax)
movq -0x10(%rbp), %rdi
movl $0x15, %esi
xorl %eax, %eax
movl %eax, %r8d
movq %r8, %rdx
movq %r8, %rcx
callq 0x5e720
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x248(%rax)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x6c624
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x98(%rbp)
movq -0x18(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, -0xa0(%rbp)
movq -0x18(%rbp), %rax
movq 0x70(%rax), %rax
movq %rax, -0xa8(%rbp)
movq -0x18(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0xb0(%rbp)
movq -0x18(%rbp), %rax
movq $0x0, 0x48(%rax)
movq -0x18(%rbp), %rax
movq $0x0, 0x28(%rax)
movq -0x18(%rbp), %rax
movq $0x0, 0x50(%rax)
movq -0x18(%rbp), %rax
movq $0x0, 0x68(%rax)
movq -0x18(%rbp), %rax
movq $0x0, 0x70(%rax)
movq -0x80(%rbp), %rdi
movq -0x18(%rbp), %rsi
xorl %edx, %edx
callq 0x61ba0
movq %rax, -0x90(%rbp)
movq -0xa8(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0xa0(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x98(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x50(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x18(%rbp), %rax
movb $0x71, 0x8(%rax)
movq -0x18(%rbp), %rax
movq $0x0, 0x60(%rax)
cmpq $0x0, -0x90(%rbp)
jne 0x6c5cb
movq -0xb0(%rbp), %rax
movq %rax, -0x90(%rbp)
jmp 0x6c5ec
movq -0xb0(%rbp), %rcx
movq -0x90(%rbp), %rax
movq %rcx, 0x50(%rax)
movq -0x90(%rbp), %rax
movq $0x0, 0x60(%rax)
movq -0x90(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x50(%rax)
movq -0x80(%rbp), %rax
cmpb $0x0, 0x50(%rax)
je 0x6c611
movl $0x1, -0x4(%rbp)
jmp 0x6cbb7
jmp 0x6c613
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x6c4cb
movq -0x78(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x48(%rbp)
movq %rax, -0x40(%rbp)
movq -0x80(%rbp), %rdi
movq -0x78(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x9cd0
movq -0x80(%rbp), %rdi
movq -0x78(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x9cd0
movq -0x80(%rbp), %rdi
movq -0x78(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x9cd0
movq -0x78(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x78(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x78(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x78(%rbp), %rax
movq $0x0, 0x28(%rax)
movq -0x78(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x6c74f
movq -0x78(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movzwl 0x44(%rax), %eax
cmpl $0x1, %eax
jne 0x6c730
movq -0x10(%rbp), %rax
cmpq $0x0, 0x1d8(%rax)
je 0x6c6e7
movq -0x10(%rbp), %rax
movq 0x1d8(%rax), %rax
movq %rax, -0xd8(%rbp)
jmp 0x6c6f2
movq -0x10(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0xc0(%rbp), %rax
movq 0x288(%rax), %rcx
movq -0xb8(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0xb8(%rbp), %rcx
movq -0xc0(%rbp), %rax
movq %rcx, 0x288(%rax)
jmp 0x6c743
movq -0xb8(%rbp), %rax
movw 0x44(%rax), %cx
addw $-0x1, %cx
movw %cx, 0x44(%rax)
movq -0x78(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x18(%rbp), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x6cba3
movb $0x0, -0xc5(%rbp)
movq -0x40(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movzbl (%rax), %eax
movl %eax, -0xc4(%rbp)
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x6c7a4
movq -0x78(%rbp), %rax
movb 0x38(%rax), %al
movb %al, -0xc5(%rbp)
jmp 0x6c7d1
movq -0x80(%rbp), %rdi
xorl %eax, %eax
movl %eax, %ecx
movq %rcx, %rsi
movq %rcx, %rdx
callq 0x54b60
movq -0x38(%rbp), %rcx
movq %rax, 0x28(%rcx)
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0x6c7cf
jmp 0x6cba3
jmp 0x6c7d1
cmpl $0x1, -0xc4(%rbp)
jle 0x6c816
movq -0x80(%rbp), %rdi
movq -0x50(%rbp), %rsi
movl -0xc4(%rbp), %edx
subl $0x1, %edx
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
callq 0x70490
movq %rax, %rcx
movq %rcx, -0x50(%rbp)
movq -0x38(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x80(%rbp), %rax
cmpb $0x0, 0x50(%rax)
je 0x6c814
jmp 0x6cba3
jmp 0x6c816
movl $0x0, -0x68(%rbp)
movl -0x68(%rbp), %eax
cmpl -0xc4(%rbp), %eax
jge 0x6c8b2
movq -0x80(%rbp), %rdi
movq -0x50(%rbp), %rax
addq $0x8, %rax
movl -0x68(%rbp), %ecx
addl -0x1c(%rbp), %ecx
movslq %ecx, %rcx
imulq $0x68, %rcx, %rcx
addq %rcx, %rax
movq 0x48(%rax), %rsi
callq 0x476c0
movq -0x50(%rbp), %rdi
addq $0x8, %rdi
movl -0x68(%rbp), %eax
addl -0x1c(%rbp), %eax
cltq
imulq $0x68, %rax, %rax
addq %rax, %rdi
movq -0x58(%rbp), %rsi
addq $0x8, %rsi
movslq -0x68(%rbp), %rax
imulq $0x68, %rax, %rax
addq %rax, %rsi
movl $0x68, %edx
callq 0x82f0
movq -0x58(%rbp), %rdi
addq $0x8, %rdi
movslq -0x68(%rbp), %rax
imulq $0x68, %rax, %rax
addq %rax, %rdi
xorl %esi, %esi
movl $0x68, %edx
callq 0x8200
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x6c81d
movb -0xc5(%rbp), %cl
movq -0x50(%rbp), %rax
addq $0x8, %rax
movslq -0x1c(%rbp), %rdx
imulq $0x68, %rdx, %rdx
addq %rdx, %rax
movb %cl, 0x38(%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x60(%rbp)
movl $0x0, -0x68(%rbp)
movl -0x68(%rbp), %eax
movq -0x60(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x6c966
movq -0x60(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x68(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
cmpq $0x0, 0x8(%rax)
jne 0x6c956
movq -0x80(%rbp), %rdi
movq -0x60(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x68(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rsi
callq 0x11720
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rdi
callq 0x5e890
movq -0xd0(%rbp), %rcx
movq -0x60(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x68(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
jmp 0x6c958
movl -0x68(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x68(%rbp)
jmp 0x6c8e0
movq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rax
movq (%rax), %rsi
movl -0x64(%rbp), %edx
movq -0x40(%rbp), %rax
movq (%rax), %rcx
callq 0x70610
cmpl $0x0, -0x20(%rbp)
je 0x6c9c7
movq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x38(%rax), %rsi
movl -0x64(%rbp), %edx
movq -0x40(%rbp), %rax
movq (%rax), %rcx
callq 0x70610
movq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rsi
movl -0x64(%rbp), %edx
movq -0x40(%rbp), %rax
movq (%rax), %rcx
callq 0x706a0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x6c9f0
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x40(%rbp), %rax
movq $0x0, 0x48(%rax)
jmp 0x6ca18
movq -0x38(%rbp), %rax
cmpq $0x0, 0x48(%rax)
je 0x6ca16
movq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rsi
movl -0x64(%rbp), %edx
movq -0x40(%rbp), %rax
movq (%rax), %rcx
callq 0x70610
jmp 0x6ca18
movq -0x40(%rbp), %rax
cmpq $0x0, 0x30(%rax)
je 0x6ca3c
movq -0x80(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x30(%rax), %rsi
xorl %edx, %edx
callq 0x61690
movq %rax, -0x70(%rbp)
jmp 0x6ca44
movq $0x0, -0x70(%rbp)
cmpl $0x0, -0x24(%rbp)
je 0x6cafe
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x70(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rsi
movl -0x64(%rbp), %edx
movq -0x40(%rbp), %rax
movq (%rax), %rcx
callq 0x706a0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x80(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0xe0(%rbp)
movq -0x80(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x40(%rax), %rsi
xorl %edx, %edx
callq 0x61690
movq -0xe8(%rbp), %rdi
movq -0xe0(%rbp), %rsi
movq %rax, %rdx
callq 0x64b70
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x80(%rbp), %rdi
movq -0x40(%rbp), %rax
movq 0x38(%rax), %rsi
xorl %edx, %edx
callq 0x61da0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x38(%rax)
jmp 0x6cb44
movq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rsi
movl -0x64(%rbp), %edx
movq -0x40(%rbp), %rax
movq (%rax), %rcx
callq 0x706a0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rsi
movq -0x70(%rbp), %rdx
callq 0x64b70
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x40(%rbp), %rax
movzwl 0xa(%rax), %edx
andl $0x1, %edx
movq -0x38(%rbp), %rax
movzwl 0xa(%rax), %ecx
orl %edx, %ecx
movw %cx, 0xa(%rax)
movq -0x40(%rbp), %rax
cmpq $0x0, 0x68(%rax)
je 0x6cb84
movq -0x40(%rbp), %rax
movq 0x68(%rax), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x68(%rax)
movq -0x40(%rbp), %rax
movq $0x0, 0x68(%rax)
jmp 0x6cb86
movq -0x38(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x40(%rbp)
jmp 0x6c757
movq -0x80(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x47420
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xf0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)