static void dequantize_mul_mat_vec_q5_k(const void *__restrict__ vx,
                                        const float *__restrict__ yy,
                                        float *__restrict__ dst,
                                        const int ncols,
                                        const sycl::nd_item<3> &item_ct1) {

    const int row = item_ct1.get_group(2);
    const int num_blocks_per_row = ncols / QK_K;
    const int ib0 = row*num_blocks_per_row;

    const block_q5_K * x = (const block_q5_K *)vx + ib0;

    float tmp = 0; // partial sum for thread in warp

#if QK_K == 256
    const uint16_t kmask1 = 0x3f3f;
    const uint16_t kmask2 = 0x0f0f;
    const uint16_t kmask3 = 0xc0c0;

    const int tid = item_ct1.get_local_id(2) / 2; // 0...15
    const int ix = item_ct1.get_local_id(2) % 2;

    const int il  = tid/4;     // 0...3
    const int ir  = tid - 4*il;// 0...3
    const int n   = 2;

    const int im = il/2;  // 0 or 1. 0 computes 0,32 + 128,160, 1 computes 64,96 + 192,224
    const int in = il%2;

    const int l0 = n*(2*ir + in);
    const int q_offset = 32*im + l0;
    const int y_offset = 64*im + l0;

    const uint8_t hm1  = 1 << (2*im);
    const uint8_t hm2  = hm1 << 4;

    uint16_t aux[4];
    const uint8_t * sc = (const uint8_t *)aux;

    uint16_t q16[8];
    const uint8_t * q4 = (const uint8_t *)q16;

    for (int i = ix; i < num_blocks_per_row; i += 2) {

        const uint8_t * ql1 = x[i].qs + q_offset;
        const uint8_t * qh  = x[i].qh + l0;
        const float   * y1  = yy + i*QK_K + y_offset;
        const float   * y2  = y1 + 128;

        const float dall = x[i].dm[0];
        const float dmin = x[i].dm[1];

        const uint16_t * a = (const uint16_t *)x[i].scales;
        aux[0] = a[im+0] & kmask1;
        aux[1] = a[im+2] & kmask1;
        aux[2] = ((a[im+4] >> 0) & kmask2) | ((a[im+0] & kmask3) >> 2);
        aux[3] = ((a[im+4] >> 4) & kmask2) | ((a[im+2] & kmask3) >> 2);

        sycl::float4 sum = {0.f, 0.f, 0.f, 0.f};
        float smin = 0;
        const uint16_t * q1 = (const uint16_t *)ql1;
        const uint16_t * q2 = q1 + 32;
        q16[0] = q1[0] & 0x0f0f;
        q16[1] = q1[8] & 0x0f0f;
        q16[2] = (q1[0] >> 4) & 0x0f0f;
        q16[3] = (q1[8] >> 4) & 0x0f0f;
        q16[4] = q2[0] & 0x0f0f;
        q16[5] = q2[8] & 0x0f0f;
        q16[6] = (q2[0] >> 4) & 0x0f0f;
        q16[7] = (q2[8] >> 4) & 0x0f0f;
        for (int l = 0; l < n; ++l) {
            sum.x() +=
                y1[l + 0] * (q4[l + 0] + (qh[l + 0] & (hm1 << 0) ? 16 : 0)) +
                y1[l + 16] * (q4[l + 2] + (qh[l + 16] & (hm1 << 0) ? 16 : 0));
            sum.y() +=
                y1[l + 32] * (q4[l + 4] + (qh[l + 0] & (hm1 << 1) ? 16 : 0)) +
                y1[l + 48] * (q4[l + 6] + (qh[l + 16] & (hm1 << 1) ? 16 : 0));
            sum.z() +=
                y2[l + 0] * (q4[l + 8] + (qh[l + 0] & (hm2 << 0) ? 16 : 0)) +
                y2[l + 16] * (q4[l + 10] + (qh[l + 16] & (hm2 << 0) ? 16 : 0));
            sum.w() +=
                y2[l + 32] * (q4[l + 12] + (qh[l + 0] & (hm2 << 1) ? 16 : 0)) +
                y2[l + 48] * (q4[l + 14] + (qh[l + 16] & (hm2 << 1) ? 16 : 0));
            smin += (y1[l] + y1[l+16]) * sc[2] + (y1[l+32] + y1[l+48]) * sc[3]
                  + (y2[l] + y2[l+16]) * sc[6] + (y2[l+32] + y2[l+48]) * sc[7];
        }
        tmp += dall * (sum.x() * sc[0] + sum.y() * sc[1] + sum.z() * sc[4] +
                       sum.w() * sc[5]) -
               dmin * smin;
    }

#else
    const int tid = item_ct1.get_local_id(2)/(2*K_QUANTS_PER_ITERATION);  // 0...15
    const int ix  = item_ct1.get_local_id(2)%(2*K_QUANTS_PER_ITERATION);
    const int step = tid * K_QUANTS_PER_ITERATION;
    const int im = step/8;
    const int in = step%8;

    for (int i = ix; i < num_blocks_per_row; i += 2*K_QUANTS_PER_ITERATION) {
        const uint8_t * q = x[i].qs + step;
        const int8_t  * s = x[i].scales;
        const float   * y = yy + i*QK_K + step;
        const float     d = x[i].d;
        float sum = 0.f;
        for (int j = 0; j < K_QUANTS_PER_ITERATION; ++j) {
            const uint8_t h = x[i].qh[in+j] >> im;
            sum += y[j+ 0] * d * s[0] * ((q[j+ 0] & 0xF) - ((h >> 0) & 1 ? 0 : 16))
                 + y[j+16] * d * s[1] * ((q[j+16] & 0xF) - ((h >> 2) & 1 ? 0 : 16))
                 + y[j+32] * d * s[2] * ((q[j+ 0] >>  4) - ((h >> 4) & 1 ? 0 : 16))
                 + y[j+48] * d * s[3] * ((q[j+16] >>  4) - ((h >> 6) & 1 ? 0 : 16));
        }
        tmp += sum;
    }
#endif

    // sum up partial sums and write back result
#pragma unroll
    for (int mask = QK_WARP_SIZE / 2; mask > 0; mask >>= 1) {
        tmp +=
            dpct::permute_sub_group_by_xor(item_ct1.get_sub_group(), tmp, mask);
    }

    if (item_ct1.get_local_id(2) == 0) {
        dst[row] = tmp;
    }
}

/*
DPCT1110:7: The total declared local variable size in device function
dequantize_mul_mat_vec_q5_k exceeds 128 bytes and may cause high register
pressure. Consult with your hardware vendor to find the total register size
available and adjust the code, or use smaller sub-group size to avoid high
register pressure.
*/


std::string vars() override {
        return VARS_TO_STR6(type, n, m, r, b, v);
    }


void DriveWidget::leaveEvent(QEvent *event)
{
  stop();
}

// When the mouse leaves the widget but the button is still held down,
// we don't get the leaveEvent() because the mouse is "grabbed" (by
// default from Qt).  However, when the mouse drags out of the widget
// and then other buttons are pressed (or possibly other
// window-manager things happen), we will get a leaveEvent() but not a
// mouseReleaseEvent().  Without catching this event you can have a
// robot stuck "on" without the user controlling it.


bool detexDecompressBlockBPTC_SIGNED_FLOAT(const uint8_t * DETEX_RESTRICT bitstring,
uint32_t mode_mask, uint32_t flags, uint8_t * DETEX_RESTRICT pixel_buffer) {
	return DecompressBlockBPTCFloatShared(bitstring, mode_mask, flags, true,
		pixel_buffer);
}

/* Decompress a 128-bit 4x4 pixel texture block compressed using the */
/* BPTC_FLOAT (BC6H_FLOAT) format. The output format is */
/* DETEX_PIXEL_FORMAT_SIGNED_FLOAT_RGBX16. */


void BlockATI1::flip4()
{
	alpha.flip4();
}


void
TileWorkQueue::clampToPass(unsigned passIdx)
{
    MNRY_ASSERT(mNumPasses);
    passIdx = std::min(passIdx, mNumPasses - 1u);
    mGroupClampIdx = mPassInfos[passIdx].mEndGroupIdx;
}

// Executes the up until and including this pass and then stops.


CharIterator::CharIterator ()
{
   it = NULL;
}


void a_Menu_bugmeter_popup(BrowserWindow *bw, const DilloUrl *url)
{
   static Fl_Menu_Item pm[] = {
      {"Validate URL with W3C", 0, Menu_bugmeter_validate_w3c_cb,0,0,0,0,0,0},
      {"Validate URL with WDG", 0, Menu_bugmeter_validate_wdg_cb, 0,
       FL_MENU_DIVIDER,0,0,0,0},
      {"About bug meter", 0, Menu_bugmeter_about_cb,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0,0}
   };

   popup_x = Fl::event_x();
   popup_y = Fl::event_y();
   popup_bw = bw;
   a_Url_free(popup_url);
   popup_url = a_Url_dup(url);

   a_Timeout_add(0.0, Menu_simple_popup_cb, (void*)pm);
}

/*
 * Bugmeter popup menu (construction & popup)
 */


bool ClipperBase::PopScanbeam(cInt &Y) {
  if (m_Scanbeam.empty())
    return false;
  Y = m_Scanbeam.top();
  m_Scanbeam.pop();
  while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) {
    m_Scanbeam.pop();
  } // Pop duplicates.
  return true;
}


void insertAtTail(Node* &tail, int d) {
    Node* temp = new Node(d);
    tail->next = temp;
    tail = temp;
}


int main(int argc, char** argv)
{
    std::vector<std::string> inputFiles;
    std::vector<std::string> outputDirOrFiles;
    std::string              whiteListFile;
    int                      opts;
    int                      verbosity;

    // handle errors by exiting
    spv::spirvbin_t::registerErrorHandler(errHandler);

    // Log messages to std::cout
    spv::spirvbin_t::registerLogHandler(logHandler);

    if (argc < 2)
        usage(argv[0]);

    parseCmdLine(argc, argv, inputFiles, outputDirOrFiles, whiteListFile, opts, verbosity);

    if (outputDirOrFiles.empty())
        usage(argv[0], "Output directory or file(s) required.");

    const bool isMultiInput      = inputFiles.size() > 1;
    const bool isMultiOutput     = outputDirOrFiles.size() > 1;
    const bool isSingleOutputDir = !isMultiOutput && std::filesystem::is_directory(outputDirOrFiles[0]);

    if (isMultiInput && !isMultiOutput && !isSingleOutputDir)
        usage(argv[0], "Output is not a directory.");

    if (isMultiInput && isMultiOutput && (outputDirOrFiles.size() != inputFiles.size()))
        usage(argv[0], "Output must be either a single directory or one output file per input.");

    // Main operations: read, remap, and write.
    execute(inputFiles, outputDirOrFiles, isSingleOutputDir, whiteListFile, opts, verbosity);

    // If we get here, everything went OK!  Nothing more to be done.
}


void TShader::setHlslIoMapping(bool hlslIoMap)          { intermediate->setHlslIoMapping(hlslIoMap); }

// See comment above TDefaultHlslIoMapper in iomapper.cpp:


int TIntermediate::addUsedLocation(const TQualifier& qualifier, const TType& type, bool& typeCollision)
{
    typeCollision = false;

    int set;
    if (qualifier.isPipeInput())
        set = 0;
    else if (qualifier.isPipeOutput())
        set = 1;
    else if (qualifier.storage == EvqUniform)
        set = 2;
    else if (qualifier.storage == EvqBuffer)
        set = 3;
    else if (qualifier.storage == EvqTileImageEXT)
        set = 4;
    else if (qualifier.isAnyPayload())
        set = 0;
    else if (qualifier.isAnyCallable())
        set = 1;
    else if (qualifier.isHitObjectAttrNV())
        set = 2;
    else
        return -1;

    int size;
    if (qualifier.isAnyPayload() || qualifier.isAnyCallable()) {
        size = 1;
    } else if (qualifier.isUniformOrBuffer() || qualifier.isTaskMemory()) {
        if (type.isSizedArray())
            size = type.getCumulativeArraySize();
        else
            size = 1;
    } else {
        // Strip off the outer array dimension for those having an extra one.
        if (type.isArray() && qualifier.isArrayedIo(language)) {
            TType elementType(type, 0);
            size = computeTypeLocationSize(elementType, language);
        } else
            size = computeTypeLocationSize(type, language);
    }

    // Locations, and components within locations.
    //
    // Almost always, dealing with components means a single location is involved.
    // The exception is a dvec3. From the spec:
    //
    // "A dvec3 will consume all four components of the first location and components 0 and 1 of
    // the second location. This leaves components 2 and 3 available for other component-qualified
    // declarations."
    //
    // That means, without ever mentioning a component, a component range
    // for a different location gets specified, if it's not a vertex shader input. (!)
    // (A vertex shader input will show using only one location, even for a dvec3/4.)
    //
    // So, for the case of dvec3, we need two independent ioRanges.
    //
    // For raytracing IO (payloads and callabledata) each declaration occupies a single
    // slot irrespective of type.
    int collision = -1; // no collision
    if (qualifier.isAnyPayload() || qualifier.isAnyCallable() || qualifier.isHitObjectAttrNV()) {
        TRange range(qualifier.layoutLocation, qualifier.layoutLocation);
        collision = checkLocationRT(set, qualifier.layoutLocation);
        if (collision < 0)
            usedIoRT[set].push_back(range);
        return collision;
    }
    if (size == 2 && type.getBasicType() == EbtDouble && type.getVectorSize() == 3 &&
        (qualifier.isPipeInput() || qualifier.isPipeOutput())) {
        // Dealing with dvec3 in/out split across two locations.
        // Need two io-ranges.
        // The case where the dvec3 doesn't start at component 0 was previously caught as overflow.

        // First range:
        TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation);
        TRange componentRange(0, 3);
        TIoRange range(locationRange, componentRange, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);

        // check for collisions
        collision = checkLocationRange(set, range, type, typeCollision);
        if (collision < 0) {
            usedIo[set].push_back(range);

            // Second range:
            TRange locationRange2(qualifier.layoutLocation + 1, qualifier.layoutLocation + 1);
            TRange componentRange2(0, 1);
            TIoRange range2(locationRange2, componentRange2, type.getBasicType(), 0, qualifier.centroid, qualifier.smooth, qualifier.flat);

            // check for collisions
            collision = checkLocationRange(set, range2, type, typeCollision);
            if (collision < 0)
                usedIo[set].push_back(range2);
        }
        return collision;
    }

    // Not a dvec3 in/out split across two locations, generic path.
    // Need a single IO-range block.

    TRange locationRange(qualifier.layoutLocation, qualifier.layoutLocation + size - 1);
    TRange componentRange(0, 3);
    if (qualifier.hasComponent() || type.getVectorSize() > 0) {
        int consumedComponents = type.getVectorSize() * (type.getBasicType() == EbtDouble ? 2 : 1);
        if (qualifier.hasComponent())
            componentRange.start = qualifier.layoutComponent;
        componentRange.last  = componentRange.start + consumedComponents - 1;
    }

    // combine location and component ranges
    TBasicType basicTy = type.getBasicType();
    if (basicTy == EbtSampler && type.getSampler().isAttachmentEXT())
        basicTy = type.getSampler().type;
    TIoRange range(locationRange, componentRange, basicTy, qualifier.hasIndex() ? qualifier.getIndex() : 0, qualifier.centroid, qualifier.smooth, qualifier.flat);

    // check for collisions, except for vertex inputs on desktop targeting OpenGL
    if (! (!isEsProfile() && language == EShLangVertex && qualifier.isPipeInput()) || spvVersion.vulkan > 0)
        collision = checkLocationRange(set, range, type, typeCollision);

    if (collision < 0)
        usedIo[set].push_back(range);

    return collision;
}

// Accumulate locations used for inputs, outputs, and uniforms, payload, callable data, and tileImageEXT
// and check for collisions as the accumulation is done.
//
// Returns < 0 if no collision, >= 0 if collision and the value returned is a colliding value.
//
// typeCollision is set to true if there is no direct collision, but the types in the same location
// are different.
//


static void SetupGenMidi()
{
	// The OPL renderer should not care about where this comes from.
	// Note: No I_Error here - this needs to be consistent with the rest of the music code.
	auto lump = fileSystem.CheckNumForName("GENMIDI", ns_global);
	if (lump < 0)
	{
		Printf("No GENMIDI lump found. OPL playback not available.\n");
		return;
	}
	auto genmidi = fileSystem.ReadFile(lump);

	if (genmidi.size() < 8 + 175 * 36 || memcmp(genmidi.data(), "#OPL_II#", 8)) return;
	ZMusic_SetGenMidi(genmidi.bytes() + 8);
}


void SoundEngine::UnlinkChannel(FSoundChan *chan)
{
	*(chan->PrevChan) = chan->NextChan;
	if (chan->NextChan != NULL)
	{
		chan->NextChan->PrevChan = chan->PrevChan;
	}
}


void InterplayDecoder::DecodeBlock7(int32_t offset)
{
    uint8_t* pBuffer = GetCurrentFrame() + (intptr_t)offset;
    uint32_t flags = 0;

    uint8_t P[2];
    P[0] = *ChunkPtr++;
    P[1] = *ChunkPtr++;

    // 2-color encoding
    if (P[0] <= P[1])
    {
        // need 8 more bytes from the stream
        for (int y = 0; y < 8; y++)
        {
            flags = (*ChunkPtr++) | 0x100;
            for (; flags != 1; flags >>= 1) {
                *pBuffer++ = P[flags & 1];
            }
            pBuffer += (videoStride - 8);
        }
    }
    else
    {
        // need 2 more bytes from the stream
        flags = LE_16(ChunkPtr);
        ChunkPtr += 2;

        for (int y = 0; y < 8; y += 2)
        {
            for (int x = 0; x < 8; x += 2, flags >>= 1)
            {
                pBuffer[x] =
                    pBuffer[x + 1] =
                    pBuffer[x + videoStride] =
                    pBuffer[x + 1 + videoStride] = P[flags & 1];
            }
            pBuffer += videoStride * 2;
        }
    }
}


static void Atomic()
{
	// Flip current white
	CurrentWhite = OtherWhite();
	SweepPos = &Root;
	State = GCS_Sweep;
	Estimate = AllocBytes;
}


void FDInputMouse::Ungrab()
{
	Device->Unacquire();
	Grabbed = false;
	SetCursorState(true);
	ClearButtonState();
}


void FRawPS2Manager::GetDevices(TArray<IJoystickConfig *> &sticks)
{
	for (unsigned i = 0; i < Devices.Size(); ++i)
	{
		if (Devices[i]->IsConnected())
		{
			sticks.Push(Devices[i]);
		}
	}
}


ExpEmit FxBoolCast::Emit(VMFunctionBuilder *build)
{
	ExpEmit from = basex->Emit(build);

	if(from.Konst && from.RegType == REGT_INT)
	{ // this is needed here because the int const assign optimization returns a constant
		ExpEmit to;
		to.Konst = true;
		to.RegType = REGT_INT;
		to.RegNum = build->GetConstantInt(!!build->FindConstantInt(from.RegNum));
		return to;
	}

	assert(!from.Konst);
	assert(basex->ValueType->GetRegType() == REGT_INT || basex->ValueType->GetRegType() == REGT_FLOAT || basex->ValueType->GetRegType() == REGT_POINTER);

	if (NeedValue)
	{
		ExpEmit to(build, REGT_INT);
		from.Free(build);
		build->Emit(OP_CASTB, to.RegNum, from.RegNum, from.RegType == REGT_INT ? CASTB_I : from.RegType == REGT_FLOAT ? CASTB_F : CASTB_A);
		return to;
	}
	else
	{
		return from;
	}
}


void DStatusBarCore::StatusbarToRealCoords(double& x, double& y, double& w, double& h) const
{
	if (SBarScale.X == -1 || ForcedScale)
	{
		int hres = HorizontalResolution;
		int vres = VerticalResolution;
		ValidateResolution(hres, vres);

		VirtualToRealCoords(twod, x, y, w, h, hres, vres, true, true);
	}
	else
	{
		x = ST_X + x * SBarScale.X;
		y = ST_Y + y * SBarScale.Y;
		w *= SBarScale.X;
		h *= SBarScale.Y;
	}
}


void MD5Context::Final(uint8_t digest[16])
{
	int count = bytes[0] & 0x3f;	/* Number of bytes in ctx->in */
	uint8_t *p = (uint8_t *)in + count;

	/* Set the first char of padding to 0x80.  There is always room. */
	*p++ = 0x80;

	/* Bytes of padding needed to make 56 bytes (-8..55) */
	count = 56 - 1 - count;

	if (count < 0)		/* Padding forces an extra block */
	{
		memset(p, 0, count + 8);
		byteSwap(in, 16);
		MD5Transform(buf, in);
		p = (uint8_t *)in;
		count = 56;
	}
	memset(p, 0, count);
	byteSwap(in, 14);

	/* Append length in bits and transform */
	in[14] = bytes[0] << 3;
	in[15] = (bytes[1] << 3) | (bytes[0] >> 29);
	MD5Transform(buf, in);

	byteSwap(buf, 4);
	memcpy(digest, buf, 16);
	memset(this, 0, sizeof(*this));	/* In case it's sensitive */
}

/*
 * Final wrapup - pad to 64-byte boundary with the bit pattern
 * 1 0* (64-bit count of bits processed, MSB-first)
 */


void FMugShot::Reset()
{
	FaceHealthNow = FaceHealthLast = -1;
	bEvilGrin = false;
	bNormal = true;
	bDamageFaceActive = false;
	bOuchActive = false;
	CurrentState = NULL;
	RampageTimer = 0;
	LastDamageAngle = 1;
}


void DBaseStatusBar::DrawBottomStuff (EHudState state)
{
	primaryLevel->localEventManager->RenderUnderlay(state);
	DrawMessages (HUDMSGLayer_UnderHUD, (state == HUD_StatusBar) ? GetTopOfStatusbar() : twod->GetHeight());
}


void FTextureAnimator::UpdateAnimations (uint64_t mstime)
{
	for (unsigned int i = 0; i < mFireTextures.Size(); i++)
	{
		FFireTexture* fire = &mFireTextures[i];
		bool updated = false;

		if (fire->SwitchTime == 0)
		{
			fire->SwitchTime = mstime + fire->Duration;
		}
		else while (fire->SwitchTime <= mstime)
		{
			static_cast<FireTexture*>(fire->texture->GetTexture())->Update();
			fire->SwitchTime = mstime + fire->Duration;
			updated = true;
		}

		if (updated)
		{
			fire->texture->CleanHardwareData();

			if (fire->texture->GetSoftwareTexture())
				delete fire->texture->GetSoftwareTexture();

			fire->texture->SetSoftwareTexture(nullptr);
		}
	}
	for (unsigned int j = 0; j < mAnimations.Size(); ++j)
	{
		FAnimDef *anim = &mAnimations[j];

		// If this is the first time through R_UpdateAnimations, just
		// initialize the anim's switch time without actually animating.
		if (anim->SwitchTime == 0)
		{
			anim->SetSwitchTime (mstime);
		}
		else while (anim->SwitchTime <= mstime)
		{ // Multiple frames may have passed since the last time calling
		  // R_UpdateAnimations, so be sure to loop through them all.

			AdvanceFrame(anim->CurFrame, anim->AnimType, *anim);
			anim->SetSwitchTime (mstime);
		}

		if (anim->bDiscrete)
		{
			TexMan.SetTranslation (anim->BasePic, anim->Frames[anim->CurFrame].FramePic);
		}
		else
		{
			for (unsigned int i = 0; i < anim->NumFrames; i++)
			{
				TexMan.SetTranslation (anim->BasePic + i, anim->BasePic + (i + anim->CurFrame) % anim->NumFrames);
			}
		}
	}
}


void DBaseDecal::SetShade (int r, int g, int b)
{
	AlphaColor = MAKEARGB(ColorMatcher.Pick (r, g, b), r, g, b);
}


static void CheckForPushSpecial(line_t *line, int side, AActor *mobj, DVector2 *posforwindowcheck)
{
	if (line->special && !(mobj->flags6 & MF6_NOTRIGGER))
	{
		if (posforwindowcheck && !(mobj->Level->i_compatflags2 & COMPATF2_PUSHWINDOW) && line->backsector != NULL)
		{ // Make sure this line actually blocks us and is not a window
			// or similar construct we are standing inside of.
			DVector3 pos = mobj->PosRelative(line);
			double fzt = line->frontsector->ceilingplane.ZatPoint(*posforwindowcheck);
			double fzb = line->frontsector->floorplane.ZatPoint(*posforwindowcheck);
			double bzt = line->backsector->ceilingplane.ZatPoint(*posforwindowcheck);
			double bzb = line->backsector->floorplane.ZatPoint(*posforwindowcheck);
			if (fzt >= mobj->Top() && bzt >= mobj->Top() &&
				fzb <= mobj->Z() && bzb <= mobj->Z())
			{
				if (line->flags & ML_3DMIDTEX)
				{
					double top, bot;
					P_GetMidTexturePosition(line, side, &top, &bot);
					if (bot < mobj->Top() && top > mobj->Z())
					{
						goto isblocking;
					}
				}
				// we must also check if some 3D floor in the backsector may be blocking
				for (auto rover : line->backsector->e->XFloor.ffloors)
				{
					if (!(rover->flags & FF_SOLID) || !(rover->flags & FF_EXISTS)) continue;

					double ff_bottom = rover->bottom.plane->ZatPoint(*posforwindowcheck);
					double ff_top = rover->top.plane->ZatPoint(*posforwindowcheck);

					if (ff_bottom < mobj->Top() && ff_top > mobj->Z())
					{
						goto isblocking;
					}
				}
				return;
			}
		}
	isblocking:
		if (mobj->flags2 & MF2_PUSHWALL)
		{
			P_ActivateLine(line, mobj, side, SPAC_Push);
		}
		else if (mobj->flags2 & MF2_IMPACT)
		{
			if ((mobj->Level->flags2 & LEVEL2_MISSILESACTIVATEIMPACT) ||
				!(mobj->flags & MF_MISSILE) ||
				(mobj->target == NULL))
			{
				P_ActivateLine(line, mobj, side, SPAC_Impact);
			}
			else
			{
				P_ActivateLine(line, mobj->target, side, SPAC_Impact);
			}
		}
	}
}


bool P_MoveThing(AActor *source, const DVector3 &pos, bool fog)
{
	DVector3 old = source->Pos();

	source->SetOrigin (pos, true);
	if (P_TestMobjLocation (source))
	{
		if (fog)
		{
			P_SpawnTeleportFog(source, pos, false, true);
			P_SpawnTeleportFog(source, old, true, true);
		}
		source->ClearInterpolation();
		source->renderflags |= RF_NOINTERPOLATEVIEW;
		return true;
	}
	else
	{
		source->SetOrigin (old, true);
		return false;
	}
}


bool FPolyObj::CheckMobjBlocking (side_t *sd)
{
	static TArray<AActor *> checker;
	FBlockNode *block;
	AActor *mobj;
	int i, j, k;
	int left, right, top, bottom;
	line_t *ld;
	bool blocked;
	bool performBlockingThrust;
	int bmapwidth = Level->blockmap.bmapwidth;
	int bmapheight = Level->blockmap.bmapheight;

	ld = sd->linedef;

	top = Level->blockmap.GetBlockY(ld->bbox[BOXTOP]);
	bottom = Level->blockmap.GetBlockY(ld->bbox[BOXBOTTOM]);
	left = Level->blockmap.GetBlockX(ld->bbox[BOXLEFT]);
	right = Level->blockmap.GetBlockX(ld->bbox[BOXRIGHT]);

	blocked = false;
	checker.Clear();

	bottom = bottom < 0 ? 0 : bottom;
	bottom = bottom >= bmapheight ? bmapheight-1 : bottom;
	top = top < 0 ? 0 : top;
	top = top >= bmapheight  ? bmapheight-1 : top;
	left = left < 0 ? 0 : left;
	left = left >= bmapwidth ? bmapwidth-1 : left;
	right = right < 0 ? 0 : right;
	right = right >= bmapwidth ?  bmapwidth-1 : right;

	for (j = bottom*bmapwidth; j <= top*bmapwidth; j += bmapwidth)
	{
		for (i = left; i <= right; i++)
		{
			for (block = Level->blockmap.blocklinks[j+i]; block != nullptr; block = block->NextActor)
			{
				mobj = block->Me;
				for (k = (int)checker.Size()-1; k >= 0; --k)
				{
					if (checker[k] == mobj)
					{
						break;
					}
				}
				if (k < 0)
				{
					checker.Push (mobj);
					if ((mobj->flags&MF_SOLID) && !(mobj->flags&MF_NOCLIP))
					{
						FLineOpening open;
						open.top = LINEOPEN_MAX;
						open.bottom = LINEOPEN_MIN;
						// [TN] Check wether this actor gets blocked by the line.
						if (ld->backsector != nullptr && !P_IsBlockedByLine(mobj, ld)
							&& (!(ld->flags & ML_3DMIDTEX) ||
								(!P_LineOpening_3dMidtex(mobj, ld, open) &&
									(mobj->Top() < open.top)
								) || (open.abovemidtex && mobj->Z() > mobj->floorz))
							)
						{
							// [BL] We can't just continue here since we must
							// determine if the line's backsector is going to
							// be blocked.
							performBlockingThrust = false;
						}
						else
						{
							performBlockingThrust = true;
						}

						DVector2 pos = mobj->PosRelative(ld).XY();
						FBoundingBox box(pos.X, pos.Y, mobj->radius);

						if (!inRange(box, ld) || BoxOnLineSide(box, ld) != -1)
						{
							continue;
						}

						if (ld->isLinePortal())
						{
							// Fixme: this still needs to figure out if the polyobject move made the player cross the portal line.
							if (P_TryMove(mobj, mobj->Pos().XY(), false))
							{
								continue;
							}
						}
						// We have a two-sided linedef so we should only check one side
						// so that the thrust from both sides doesn't cancel each other out.
						// Best use the one facing the player and ignore the back side.
						if (ld->sidedef[1] != nullptr)
						{
							int side = P_PointOnLineSidePrecise(mobj->Pos(), ld);
							if (ld->sidedef[side] != sd)
							{
								continue;
							}
							// [BL] See if we hit below the floor/ceiling of the poly.
							else if(!performBlockingThrust && (
									mobj->Z() < ld->sidedef[!side]->sector->GetSecPlane(sector_t::floor).ZatPoint(mobj) ||
									mobj->Top() > ld->sidedef[!side]->sector->GetSecPlane(sector_t::ceiling).ZatPoint(mobj)
								))
							{
								performBlockingThrust = true;
							}
						}

						if(performBlockingThrust)
						{
							ThrustMobj (mobj, sd);
							blocked = true;
						}
						else
							continue;
					}
				}
			}
		}
	}
	return blocked;
}


void HWDrawInfo::AddLines(subsector_t * sub, sector_t * sector, FRenderState& state)
{
	currentsector = sector;
	currentsubsector = sub;

	ClipWall.Clock();
	if (sub->polys != nullptr)
	{
		AddPolyobjs(sub, state);
	}
	else
	{
		int count = sub->numlines;
		seg_t * seg = sub->firstline;

		while (count--)
		{
			if (seg->linedef == nullptr)
			{
				if (!(sub->flags & SSECMF_DRAWN)) AddLine (seg, mClipPortal != nullptr, state);
			}
			else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
			{
				AddLine (seg, mClipPortal != nullptr, state);
			}
			seg++;
		}
	}
	ClipWall.Unclock();
}


static int isLinePortal(line_t *self)
 {
	 return self->isLinePortal();
 }


static void ParseActor(FScanner &sc, PNamespace *ns)
{
	PClassActor *info = NULL;
	Baggage bag;

	bag.Namespace = ns;
	bag.Version = { 2, 0, 0 };
	bag.fromDecorate = true;
	bag.ScriptPosition = sc;
	info = ParseActorHeader(sc, &bag);
	sc.MustGetToken('{');
	while (sc.MustGetAnyToken(), sc.TokenType != '}')
	{
		switch (sc.TokenType)
		{
		case TK_Const:
			ParseConstant (sc, &info->VMType->Symbols, info, ns);
			break;

		case TK_Enum:
			ParseEnum (sc, &info->VMType->Symbols, info, ns);
			break;

		case TK_Var:
			ParseUserVariable (sc, &info->VMType->Symbols, info, ns);
			break;

		case TK_Identifier:
			ParseActorProperty(sc, bag);
			break;

		case TK_States:
			ParseStates(sc, bag.Info, (AActor *)bag.Info->Defaults, bag);
			bag.StateSet = true;
			break;

		case '+':
		case '-':
			ParseActorFlag(sc, bag, sc.TokenType);
			break;

		default:
			sc.ScriptError("Unexpected '%s' in definition of '%s'", sc.String, bag.Info->TypeName.GetChars());
			break;
		}
	}
	if (bag.DropItemSet)
	{
		bag.Info->SetDropItems(bag.DropItemList);
	}
	try
	{
		FinalizeClass(info, bag.statedef);
	}
	catch (CRecoverableError &err)
	{
		sc.ScriptError("%s", err.GetMessage());
	}
	sc.SetCMode (false);
}


void S_PrecacheLevel(FLevelLocals* Level)
{
	if (GSnd && Level == primaryLevel)
	{
		soundEngine->MarkAllUnused();

		AActor* actor;
		auto iterator = Level->GetThinkerIterator<AActor>();

		// Precache all sounds known to be used by the currently spawned actors.
		while ((actor = iterator.Next()) != nullptr)
		{
			IFVIRTUALPTR(actor, AActor, MarkPrecacheSounds)
			{
				VMValue params[1] = { actor };
				VMCall(func, params, 1, nullptr, 0);
			}
		}
		for (auto snd : gameinfo.PrecachedSounds)
		{
			soundEngine->MarkUsed(snd);
		}
		// Precache all extra sounds requested by this map.
		for (auto snd : primaryLevel->info->PrecacheSounds)
		{
			soundEngine->MarkUsed(snd);
		}
		soundEngine->CacheMarkedSounds();
	}
}


static uint32_t FastDecodeTag(uint16_t coded_tag) {
  uint32_t result = coded_tag;
  result += static_cast<int8_t>(coded_tag);
  return result >> 1;
}

// On the fast path, a (matching) 2-byte tag always needs to be decoded.


void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
{
    if (c == 0 && InputQueueSurrogate == 0)
        return;

    if ((c & 0xFC00) == 0xD800) // High surrogate, must save
    {
        if (InputQueueSurrogate != 0)
            InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID);
        InputQueueSurrogate = c;
        return;
    }

    ImWchar cp = c;
    if (InputQueueSurrogate != 0)
    {
        if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate
        {
            InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID);
        }
        else
        {
#if IM_UNICODE_CODEPOINT_MAX == 0xFFFF
            cp = IM_UNICODE_CODEPOINT_INVALID; // Codepoint will not fit in ImWchar
#else
            cp = (ImWchar)(((InputQueueSurrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000);
#endif
        }

        InputQueueSurrogate = 0;
    }
    InputQueueCharacters.push_back(cp);
}

// UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so
// we should save the high surrogate.


void BowVector::saveM(const std::string &filename, size_t W) const
{
  std::fstream f(filename.c_str(), std::ios::out);

  WordId last = 0;
  BowVector::const_iterator bit;
  for(bit = this->begin(); bit != this->end(); ++bit)
  {
    for(; last < bit->first; ++last)
    {
      f << "0 ";
    }
    f << bit->second << " ";

    last = bit->first + 1;
  }
  for(; last < (WordId)W; ++last)
    f << "0 ";

  f.close();
}


void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
{
    if ((c == 0 && InputQueueSurrogate == 0) || !AppAcceptingEvents)
        return;

    if ((c & 0xFC00) == 0xD800) // High surrogate, must save
    {
        if (InputQueueSurrogate != 0)
            AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID);
        InputQueueSurrogate = c;
        return;
    }

    ImWchar cp = c;
    if (InputQueueSurrogate != 0)
    {
        if ((c & 0xFC00) != 0xDC00) // Invalid low surrogate
        {
            AddInputCharacter(IM_UNICODE_CODEPOINT_INVALID);
        }
        else
        {
#if IM_UNICODE_CODEPOINT_MAX == 0xFFFF
            cp = IM_UNICODE_CODEPOINT_INVALID; // Codepoint will not fit in ImWchar
#else
            cp = (ImWchar)(((InputQueueSurrogate - 0xD800) << 10) + (c - 0xDC00) + 0x10000);
#endif
        }

        InputQueueSurrogate = 0;
    }
    AddInputCharacter((unsigned)cp);
}


void ImGui::OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags)
{
    ImGuiContext& g = *GImGui;
    ImGuiWindow* parent_window = g.CurrentWindow;
    const int current_stack_size = g.BeginPopupStack.Size;

    if (popup_flags & ImGuiPopupFlags_NoOpenOverExistingPopup)
        if (IsPopupOpen((ImGuiID)0, ImGuiPopupFlags_AnyPopupId))
            return;

    ImGuiPopupData popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
    popup_ref.PopupId = id;
    popup_ref.Window = NULL;
    popup_ref.BackupNavWindow = g.NavWindow;            // When popup closes focus may be restored to NavWindow (depend on window type).
    popup_ref.OpenFrameCount = g.FrameCount;
    popup_ref.OpenParentId = parent_window->IDStack.back();
    popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
    popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos;

    IMGUI_DEBUG_LOG_POPUP("[popup] OpenPopupEx(0x%08X)\n", id);
    if (g.OpenPopupStack.Size < current_stack_size + 1)
    {
        g.OpenPopupStack.push_back(popup_ref);
    }
    else
    {
        // Gently handle the user mistakenly calling OpenPopup() every frame. It is a programming mistake! However, if we were to run the regular code path, the ui
        // would become completely unusable because the popup will always be in hidden-while-calculating-size state _while_ claiming focus. Which would be a very confusing
        // situation for the programmer. Instead, we silently allow the popup to proceed, it will keep reappearing and the programming error will be more obvious to understand.
        if (g.OpenPopupStack[current_stack_size].PopupId == id && g.OpenPopupStack[current_stack_size].OpenFrameCount == g.FrameCount - 1)
        {
            g.OpenPopupStack[current_stack_size].OpenFrameCount = popup_ref.OpenFrameCount;
        }
        else
        {
            // Close child popups if any, then flag popup for open/reopen
            ClosePopupToLevel(current_stack_size, false);
            g.OpenPopupStack.push_back(popup_ref);
        }

        // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow().
        // This is equivalent to what ClosePopupToLevel() does.
        //if (g.OpenPopupStack[current_stack_size].PopupId == id)
        //    FocusWindow(parent_window);
    }
}

// Mark popup as open (toggle toward open state).
// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)


bool Document::isRowHidden(int row)
{
	if (Worksheet *sheet = currentWorksheet())
	   return sheet->isRowHidden(row);
	 return false;
}

/*!
 Returns true if \a row is hidden.
*/


void Worksheet::saveToXmlFile(QIODevice *device) const
{
	Q_D(const Worksheet);
	d->relationships->clear();

	QXmlStreamWriter writer(device);

	writer.writeStartDocument(QStringLiteral("1.0"), true);
	writer.writeStartElement(QStringLiteral("worksheet"));
	writer.writeAttribute(QStringLiteral("xmlns"), QStringLiteral("http://schemas.openxmlformats.org/spreadsheetml/2006/main"));
	writer.writeAttribute(QStringLiteral("xmlns:r"), QStringLiteral("http://schemas.openxmlformats.org/officeDocument/2006/relationships"));

	//for Excel 2010
	//    writer.writeAttribute("xmlns:mc", "http://schemas.openxmlformats.org/markup-compatibility/2006");
	//    writer.writeAttribute("xmlns:x14ac", "http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac");
	//    writer.writeAttribute("mc:Ignorable", "x14ac");

	writer.writeStartElement(QStringLiteral("dimension"));
	writer.writeAttribute(QStringLiteral("ref"), d->generateDimensionString());
	writer.writeEndElement();//dimension

	writer.writeStartElement(QStringLiteral("sheetViews"));
	writer.writeStartElement(QStringLiteral("sheetView"));
	if (d->windowProtection)
		writer.writeAttribute(QStringLiteral("windowProtection"), QStringLiteral("1"));
	if (d->showFormulas)
		writer.writeAttribute(QStringLiteral("showFormulas"), QStringLiteral("1"));
	if (!d->showGridLines)
		writer.writeAttribute(QStringLiteral("showGridLines"), QStringLiteral("0"));
	if (!d->showRowColHeaders)
		writer.writeAttribute(QStringLiteral("showRowColHeaders"), QStringLiteral("0"));
	if (!d->showZeros)
		writer.writeAttribute(QStringLiteral("showZeros"), QStringLiteral("0"));
	if (d->rightToLeft)
		writer.writeAttribute(QStringLiteral("rightToLeft"), QStringLiteral("1"));
	if (d->tabSelected)
		writer.writeAttribute(QStringLiteral("tabSelected"), QStringLiteral("1"));
	if (!d->showRuler)
		writer.writeAttribute(QStringLiteral("showRuler"), QStringLiteral("0"));
	if (!d->showOutlineSymbols)
		writer.writeAttribute(QStringLiteral("showOutlineSymbols"), QStringLiteral("0"));
	if (!d->showWhiteSpace)
		writer.writeAttribute(QStringLiteral("showWhiteSpace"), QStringLiteral("0"));
	writer.writeAttribute(QStringLiteral("workbookViewId"), QStringLiteral("0"));
	writer.writeEndElement();//sheetView
	writer.writeEndElement();//sheetViews

	writer.writeStartElement(QStringLiteral("sheetFormatPr"));
	writer.writeAttribute(QStringLiteral("defaultRowHeight"), QString::number(d->default_row_height));
	if (d->default_row_height != 15)
		writer.writeAttribute(QStringLiteral("customHeight"), QStringLiteral("1"));
	if (d->default_row_zeroed)
		writer.writeAttribute(QStringLiteral("zeroHeight"), QStringLiteral("1"));
	if (d->outline_row_level)
		writer.writeAttribute(QStringLiteral("outlineLevelRow"), QString::number(d->outline_row_level));
	if (d->outline_col_level)
		writer.writeAttribute(QStringLiteral("outlineLevelCol"), QString::number(d->outline_col_level));
	//for Excel 2010
	//    writer.writeAttribute("x14ac:dyDescent", "0.25");
	writer.writeEndElement();//sheetFormatPr

    if (!d->colsInfo.isEmpty())
    {
		writer.writeStartElement(QStringLiteral("cols"));
		QMapIterator<int, QSharedPointer<XlsxColumnInfo> > it(d->colsInfo);
        while (it.hasNext())
        {
			it.next();
			QSharedPointer<XlsxColumnInfo> col_info = it.value();
			writer.writeStartElement(QStringLiteral("col"));
			writer.writeAttribute(QStringLiteral("min"), QString::number(col_info->firstColumn));
			writer.writeAttribute(QStringLiteral("max"), QString::number(col_info->lastColumn));
			if (col_info->width)
				writer.writeAttribute(QStringLiteral("width"), QString::number(col_info->width, 'g', 15));
			if (!col_info->format.isEmpty())
				writer.writeAttribute(QStringLiteral("style"), QString::number(col_info->format.xfIndex()));
			if (col_info->hidden)
				writer.writeAttribute(QStringLiteral("hidden"), QStringLiteral("1"));
			if (col_info->width)
				writer.writeAttribute(QStringLiteral("customWidth"), QStringLiteral("1"));
			if (col_info->outlineLevel)
				writer.writeAttribute(QStringLiteral("outlineLevel"), QString::number(col_info->outlineLevel));
			if (col_info->collapsed)
				writer.writeAttribute(QStringLiteral("collapsed"), QStringLiteral("1"));
			writer.writeEndElement();//col
		}
		writer.writeEndElement();//cols
	}

	writer.writeStartElement(QStringLiteral("sheetData"));
	if (d->dimension.isValid())
		d->saveXmlSheetData(writer);
	writer.writeEndElement();//sheetData

	d->saveXmlMergeCells(writer);
    for (const ConditionalFormatting &cf : d->conditionalFormattingList)
		cf.saveToXml(writer);
	d->saveXmlDataValidations(writer);

    //{{ liufeijin :  write  pagesettings  add by liufeijin 20181028

    // fixed by j2doll [dev18]
    // NOTE: empty element is not problem. but, empty structure of element is not parsed by Excel.

    // pageMargins
    if ( false == d->PMleft.isEmpty() &&
         false == d->PMright.isEmpty() &&
         false == d->PMtop.isEmpty() &&
         false == d->PMbotton.isEmpty() &&
         false == d->PMheader.isEmpty() &&
         false == d->PMfooter.isEmpty()
         )
    {
        writer.writeStartElement(QStringLiteral("pageMargins"));

        writer.writeAttribute(QStringLiteral("left"),   d->PMleft );
        writer.writeAttribute(QStringLiteral("right"),  d->PMright );
        writer.writeAttribute(QStringLiteral("top"),    d->PMtop );
        writer.writeAttribute(QStringLiteral("bottom"), d->PMbotton );
        writer.writeAttribute(QStringLiteral("header"), d->PMheader );
        writer.writeAttribute(QStringLiteral("footer"), d->PMfooter );

        writer.writeEndElement(); // pageMargins
    }

    // dev57
    if ( !d->Prid.isEmpty() )
    {
        writer.writeStartElement(QStringLiteral("pageSetup")); // pageSetup

        writer.writeAttribute(QStringLiteral("r:id"), d->Prid);

        if ( !d->PverticalDpi.isEmpty() )
        {
            writer.writeAttribute(QStringLiteral("verticalDpi"), d->PverticalDpi);
        }

        if ( !d->PhorizontalDpi.isEmpty() )
        {
            writer.writeAttribute(QStringLiteral("horizontalDpi"), d->PhorizontalDpi);
        }

        if ( !d->PuseFirstPageNumber.isEmpty() )
        {
            writer.writeAttribute(QStringLiteral("useFirstPageNumber"), d->PuseFirstPageNumber);
        }

        if ( !d->PfirstPageNumber.isEmpty() )
        {
            writer.writeAttribute(QStringLiteral("firstPageNumber"), d->PfirstPageNumber);
        }

        if ( !d->Pscale.isEmpty() )
        {
            writer.writeAttribute(QStringLiteral("scale"), d->Pscale);
        }

        if ( !d->PpaperSize.isEmpty() )
        {
            writer.writeAttribute(QStringLiteral("paperSize"), d->PpaperSize);
        }

        if ( !d->Porientation.isEmpty() )
        {
            writer.writeAttribute(QStringLiteral("orientation"), d->Porientation);
        }

        if(!d->Pcopies.isEmpty())
        {
            writer.writeAttribute(QStringLiteral("copies"), d->Pcopies);
        }

        writer.writeEndElement(); // pageSetup

    } // if ( !d->Prid.isEmpty() )

    // headerFooter
    if( !(d->ModdHeader.isNull()) ||
        !(d->MoodFooter.isNull()) )
    {
        writer.writeStartElement(QStringLiteral("headerFooter")); // headerFooter

        if ( !d->MoodalignWithMargins.isEmpty() )
        {
            writer.writeAttribute(QStringLiteral("alignWithMargins"), d->MoodalignWithMargins);
        }

        if ( !d->ModdHeader.isNull() )
        {
            writer.writeStartElement(QStringLiteral("oddHeader"));
            writer.writeCharacters(d->ModdHeader);
            writer.writeEndElement(); // oddHeader
        }

        if ( !d->MoodFooter.isNull() )
        {
            writer.writeTextElement(QStringLiteral("oddFooter"), d->MoodFooter);
        }

        writer.writeEndElement(); // headerFooter
    }

	d->saveXmlHyperlinks(writer);
	d->saveXmlDrawings(writer);

    writer.writeEndElement(); // worksheet
	writer.writeEndDocument();
}


void Mutex::ThreadSafeLazyInit() {
  // Dynamic mutexes are initialized in the constructor.
  if (type_ == kStatic) {
    switch (
        ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) {
      case 0:
        // If critical_section_init_phase_ was 0 before the exchange, we
        // are the first to test it and need to perform the initialization.
        owner_thread_id_ = 0;
        critical_section_ = new CRITICAL_SECTION;
        ::InitializeCriticalSection(critical_section_);
        // Updates the critical_section_init_phase_ to 2 to signal
        // initialization complete.
        GTEST_CHECK_(::InterlockedCompareExchange(
                          &critical_section_init_phase_, 2L, 1L) ==
                      1L);
        break;
      case 1:
        // Somebody else is already initializing the mutex; spin until they
        // are done.
        while (::InterlockedCompareExchange(&critical_section_init_phase_,
                                            2L,
                                            2L) != 2L) {
          // Possibly yields the rest of the thread's time slice to other
          // threads.
          ::Sleep(0);
        }
        break;

      case 2:
        break;  // The mutex is already initialized and ready for use.

      default:
        GTEST_CHECK_(false)
            << "Unexpected value of critical_section_init_phase_ "
            << "while initializing a static mutex.";
    }
  }
}

// Initializes owner_thread_id_ and critical_section_ in static mutexes.


bool ValidateRegex(const char* regex) {
  if (regex == NULL) {
    // TODO(wan@google.com): fix the source file location in the
    // assertion failures to match where the regex is used in user
    // code.
    ADD_FAILURE() << "NULL is not a valid simple regular expression.";
    return false;
  }

  bool is_valid = true;

  // True iff ?, *, or + can follow the previous atom.
  bool prev_repeatable = false;
  for (int i = 0; regex[i]; i++) {
    if (regex[i] == '\\') {  // An escape sequence
      i++;
      if (regex[i] == '\0') {
        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
                      << "'\\' cannot appear at the end.";
        return false;
      }

      if (!IsValidEscape(regex[i])) {
        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
                      << "invalid escape sequence \"\\" << regex[i] << "\".";
        is_valid = false;
      }
      prev_repeatable = true;
    } else {  // Not an escape sequence.
      const char ch = regex[i];

      if (ch == '^' && i > 0) {
        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
                      << "'^' can only appear at the beginning.";
        is_valid = false;
      } else if (ch == '$' && regex[i + 1] != '\0') {
        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
                      << "'$' can only appear at the end.";
        is_valid = false;
      } else if (IsInSet(ch, "()[]{}|")) {
        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
                      << "'" << ch << "' is unsupported.";
        is_valid = false;
      } else if (IsRepeat(ch) && !prev_repeatable) {
        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
                      << "'" << ch << "' can only follow a repeatable token.";
        is_valid = false;
      }

      prev_repeatable = !IsInSet(ch, "^$?*+");
    }
  }

  return is_valid;
}

// Generates non-fatal failures and returns false if regex is invalid;
// otherwise returns true.


GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); }

// Creates a cardinality that allows at least n calls.


GTEST_API_ bool LogIsVisible(LogSeverity severity) {
  if (GMOCK_FLAG(verbose) == kInfoVerbosity) {
    // Always show the log if --gmock_verbose=info.
    return true;
  } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) {
    // Always hide it if --gmock_verbose=error.
    return false;
  } else {
    // If --gmock_verbose is neither "info" nor "error", we treat it
    // as "warning" (its default value).
    return severity == kWarning;
  }
}

// Returns true iff a log with the given severity is visible according
// to the --gmock_verbose flag.


TEST(Rotation, UnitQuaternionToAngleAxis) {
  double quaternion[4] = { 1, 0, 0, 0 };
  double axis_angle[3];
  double expected[3] = { 0, 0, 0 };
  QuaternionToAngleAxis(quaternion, axis_angle);
  EXPECT_THAT(axis_angle, IsNearAngleAxis(expected));
}

// Transforms a unit quaternion to an axis angle.


UncertainBackProjection::UncertainBackProjection(
    const sm::kinematics::UncertainVector3 & ray)
    : ray(ray) {
}

/// \brief the view origin is set to zero


RotationExpression RotationExpression::inverse()
    {
      boost::shared_ptr<RotationExpressionNode> newRoot( new RotationExpressionNodeInverse(_root) );
      return RotationExpression(newRoot);
    }

/// \brief return the expression that inverts the rotation.


Function function_namespace_env(){
    Environment ns = Environment::namespace_env( "stats" ) ;
    Function fun = ns[".asSparse"] ;  // accesses a non-exported function
    return fun;
}


NumericMatrix runit_SubMatrix( ){
    NumericMatrix xx(4, 5);
    xx(0,0) = 3;
    xx(0,1) = 4;
    xx(0,2) = 5;
    xx(1,_) = xx(0,_);
    xx(_,3) = xx(_,2);
    SubMatrix<REALSXP> yy = xx( Range(0,2), Range(0,3) ) ;
    NumericMatrix res = yy ;
    return res;
}


List list_erase( List list ){
    list.erase( list.begin() ) ;
    return list ;
}


String vec_print_character(CharacterVector v) {
    std::ostringstream buf;
    buf << v;
    return buf.str();
}


List runit_dt( NumericVector xx){
    return List::create(
        _["false"] = dt( xx, 5),
        _["true"]	 = dt( xx, 5, true ));
}


void formatXP(BOOL bUpgrade, WCHAR *pBSection, WCHAR *pCSection, WCHAR *pText) {
    WCHAR pDashedKey[PK_LENGTH + 4 + NULL_TERMINATOR]{};
    INT   pSSection = 0;

    for (int i = 0; i < wcslen(pCSection); i++)
        pSSection -= pCSection[i] - '0';

    while (pSSection < 0)
        pSSection += 7;

    CHAR  pKey[PK_LENGTH + NULL_TERMINATOR]{};
    DWORD nChannelID = wcstoul(pBSection, nullptr, 10),
          nSequence = wcstoul(pCSection, nullptr, 10);

    BOOL  bValid = keyXP(pKey, pBINKPreset, nChannelID, nSequence, bUpgrade);

    QWORD pRaw[2]{},
          pSignature;

    DWORD pChannelID,
          pSequence,
          pSerial,
          pHash;

    BOOL  pUpgrade;

    unbase24((BYTE *)pRaw, pKey);
    unpackXP(pRaw, pUpgrade, pChannelID, pSequence, pHash, pSignature);

    pSerial = pChannelID * 1'000'000 + pSequence;

    for (int i = 0; i < 5; i++)
        wsprintfW(pDashedKey, L"%s%s%.5S", pDashedKey, i != 0 ? L"-" : L"", &pKey[5 * i]);

    swprintf(
        pText,
        L"PRODUCT ID:\tPPPPP-%03d-%06d%d-23XXX\r\n\r\nBYTECODE:\t%016llX %016llX\r\nUPGRADE:\t%s\r\nSERIAL:\t\t0x%lX (%d)\r\nHASH:\t\t0x%lX\r\nSIGNATURE:\t0x%llX\r\nCURVE POINT:\t%s\r\n\r\n\r\n%s\r\n",
        pChannelID,
        pSequence,
        pSSection,
        pRaw[1], pRaw[0],
        pUpgrade ? L"TRUE" : L"FALSE",
        pSerial, pSerial,
        pHash,
        pSignature,
        bValid ? L"TRUE" : L"FALSE",
        pDashedKey
    );
}


void CMpegAudEncPropertyPageAdv::SetDirty()
{
    m_bDirty = TRUE;
    if (m_pPageSite)
        m_pPageSite->OnStatusChange(PROPPAGESTATUS_DIRTY);
}

//
// SetDirty
//
// notifies the property page site of changes


static bool isBusyFifoRead() {
  return !(SDHC_PRSSTAT & SDHC_PRSSTAT_BREN);
}


ark::bfloat16_t abs(ark::bfloat16_t const& h) { return ark::abs(h); }


void FastAccelStepperEngine::setDebugLed(uint8_t ledPin) {
  fas_ledPin = ledPin;
  pinMode(fas_ledPin, OUTPUT);
  digitalWrite(fas_ledPin, LOW);
}


ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() {
  internal::UnitTestImpl* const impl = internal::GetUnitTestImpl();
  if (intercept_mode_ == INTERCEPT_ALL_THREADS) {
    impl->SetGlobalTestPartResultReporter(old_reporter_);
  } else {
    impl->SetTestPartResultReporterForCurrentThread(old_reporter_);
  }
}

// The d'tor restores the test part result reporter used by Google Test
// before.


void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) {
  if (default_result_printer_ != listener) {
    // It is an error to pass this method a listener that is already in the
    // list.
    delete Release(default_result_printer_);
    default_result_printer_ = listener;
    if (listener != nullptr) Append(listener);
  }
}

// Sets the default_result_printer attribute to the provided listener.
// The listener is also added to the listener list and previous
// default_result_printer is removed from it and deleted. The listener can
// also be NULL in which case it will not be added to the list. Does
// nothing if the previous and the current listener objects are the same.


void CaptureStderr() {
  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
}


TEST_F(ASSERT_PRED_FORMAT4Test, FunctionOnUserTypeSuccess) {
  ASSERT_PRED_FORMAT4(PredFormatFunction4,
                      Bool(++n1_),
                      Bool(++n2_),
                      Bool(++n3_),
                      Bool(++n4_));
  finished_ = true;
}

// Tests a successful ASSERT_PRED_FORMAT4 where the
// predicate-formatter is a function on a user-defined type (Bool).


FailureOr<std::pair<unsigned, int64_t>> getNonUnitDimension(
    RankedTensorType tensorTy) {
  auto shape = tensorTy.getShape();

  if (llvm::count_if(shape, [](auto dim) { return dim != 1; }) != 1) {
    return failure();
  }

  unsigned nonUnitIndex = std::distance(
      shape.begin(), llvm::find_if(shape, [&](auto dim) { return dim != 1; }));

  return std::make_pair(nonUnitIndex, shape[nonUnitIndex]);
}

// Returns the unique non-unit dimension of a tensor and its rank.
// Returns failure if the tensor has more than one non-unit dimension.


BOOL WINAPI DetourUpdateProcessWithDll(_In_ HANDLE hProcess,
                                       _In_reads_(nDlls) LPCSTR *rlpDlls,
                                       _In_ DWORD nDlls)
{
    // Find the next memory region that contains a mapped PE image.
    //
    BOOL bHas64BitDll = FALSE;
    BOOL bHas32BitExe = FALSE;
    BOOL bIs32BitProcess;
    HMODULE hModule = NULL;
    HMODULE hLast = NULL;

    DETOUR_TRACE(("DetourUpdateProcessWithDll(%p,dlls=%d)\n", hProcess, nDlls));

    for (;;) {
        IMAGE_NT_HEADERS32 inh;

        if ((hLast = EnumerateModulesInProcess(hProcess, hLast, &inh)) == NULL) {
            break;
        }

        DETOUR_TRACE(("%p  machine=%04x magic=%04x\n",
                      hLast, inh.FileHeader.Machine, inh.OptionalHeader.Magic));

        if ((inh.FileHeader.Characteristics & IMAGE_FILE_DLL) == 0) {
            hModule = hLast;
            if (inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC
                && inh.FileHeader.Machine != 0) {

                bHas32BitExe = TRUE;
            }
            DETOUR_TRACE(("%p  Found EXE\n", hLast));
        }
        else {
            if (inh.OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC
                && inh.FileHeader.Machine != 0) {

                bHas64BitDll = TRUE;
            }
        }
    }

    if (hModule == NULL) {
        SetLastError(ERROR_INVALID_OPERATION);
        return FALSE;
    }

    if (!bHas32BitExe) {
        bIs32BitProcess = FALSE;
    }
    else if (!bHas64BitDll) {
        bIs32BitProcess = TRUE;
    }
    else {
        if (!IsWow64Process(hProcess, &bIs32BitProcess)) {
            return FALSE;
        }
    }

    DETOUR_TRACE(("    32BitExe=%d 32BitProcess\n", bHas32BitExe, bIs32BitProcess));

    return DetourUpdateProcessWithDllEx(hProcess,
                                        hModule,
                                        bIs32BitProcess,
                                        rlpDlls,
                                        nDlls);
}


static std::filesystem::path get_appdata_dir()
{
	PWSTR pwstr_appdata_directory;
	HRESULT result = SHGetKnownFolderPath(FOLDERID_RoamingAppData, KF_FLAG_DEFAULT, NULL, &pwstr_appdata_directory);
	assert(SUCCEEDED(result));
	std::filesystem::path ret = pwstr_appdata_directory;
	CoTaskMemFree(pwstr_appdata_directory);
	return ret / "oxware";
}

// just a little hack over the fact that this code already exists inside the FileSystem code.. since we
// want to have the console ready right as soon as the application starts, we cannot just use the appdata manager
// or the filesystem, so yeah.. this kinda sucks but whatever, its worth it so that we can log as soon as we start..


public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
    {
        req.ThrowIfInvalid();
        var ret = 0;

        // ReSharper disable once LoopCanBeConvertedToQuery
        foreach (var item in req.Items) {
            ret += await DeleteAsync(item).ConfigureAwait(false);
        }

        return ret;
    }


public static IApplicationBuilder UseEndpoints(this IApplicationBuilder me)
    {
        return me.UseEndpoints(endpoints => {
            _ = endpoints.MapControllers();
            #if !DEBUG
            _ = endpoints.MapMetrics();
            #endif
        });
    }

/// <summary>
///     执行匹配的端点
/// </summary>