Cache-Control header behavior has changed in 1.4.x

Hey there, we've recently upgraded our version of Grape from 1.2.2 -> 1.4.0. We saw a sudden spike in cached requests in our CDN (Fastly) for our API. Fastly relies on the Cache-Control header to determine if it should or should not cache the response.
We also use the Rack::ETag middleware (default in Rails afaik), which by default sets the Cache-Control header, see here: https://github.com/rack/rack/blob/master/lib/rack/etag.rb#L18
However, this middleware will not set the cache control header if one is already present. See: https://github.com/rack/rack/blob/master/lib/rack/etag.rb#L39
This is where I believe Grape introduced a difference, I have a request spec that added an assertion to verify these findings:
expect(response.headers['Cache-Control']).to include('private') # tells fastly to skip caching, set by Rack::Etag

In Grape 1.2.5, this passes, in Grape 1.4.0 however...
  1) PublicAPI::V1::Ping /v1/ping Header Authentication for bots returns a successful response with a bot token provided in the header
     Failure/Error: expect(response.headers['Cache-Control']).to include('private')
       expected "no-cache" to include "private"
     # ./spec/requests/public_api/ping_spec.rb:36:in `block (5 levels) in <top (required)>'
     # ./spec/rails_helper.rb:29:in `with_flag'
     # ./spec/rails_helper.rb:108:in `block (2 levels) in <top (required)>'

I believe something has changed in the way that Grape assigns response headers, including the Cache-Control header. And my gut is that is has something to do with this change in the compare I looked through:
https://github.com/ruby-grape/grape/compare/v1.2.2..v1.4.0#diff-417f63bb9cd022ea7ea57549e03fcb5bR33-R54
This is a potential security risk for people
This change can cause API responses to be cached in CDNs unbeknownst to people upgrading Grape and served to other users for an API endpoint they do not have access to simply because they hit some endpoint with a unique identifier (/api/tasks for example)

I believe I see why:
https://github.com/ruby-grape/grape/compare/v1.2.2..v1.4.0#diff-8e15cddb80f42ca7d43872846d80ecbeR277
This is calling the #stream method, which explicitly assigns the Cache-Control header here: https://github.com/ruby-grape/grape/compare/v1.2.2..v1.4.0#diff-e9e8424a5238d48301e313d8fe285697R333

This looks like it's fixed in master, but I really recommend pushing a patch version for this at 1.4.1, this can really be bad for folks behind a CDN.

Closing this since I see there was a discussion, apologies. I definitely think this needs a patch level push.
Ref:
https://github.com/ruby-grape/grape/pull/2088
https://github.com/ruby-grape/grape/issues/2087

If you really want to do a 1.4.1 patch go for it @bobbytables, otherwise i'll release 1.5.0 soon (unless someone beats me to it).


Fix bash/Haskell scripts for the E2E Plonk test

[x] Resolve possible PlutusV3 bug or error in our PlutusTx code.
[x] An "always succeeds" version of minting script should mint.
[ ] Minting with "plonk verifier" should work.
[ ] Burning transaction should work.
[ ] Update documentation.

Got useful feedback pointing out that in PlutusV3 all validators should have type signature BuiltinData -> BuiltinUnit.  Had to modify PlutusTx scripts accordingly.  Now able to mint with trivial "always succeeds" version of the script.

Waiting for comments on pull-request.


set_health should be add_health

This function
https://github.com/krazyjakee/nodot/blob/e6848c5c4972369d9435e4513455c78f5335c2d7/addons/nodot/interaction/Health.gd#L18
Is used to add or subtract health, not set a specific health value. I suggest renaming to add_health().
Additionally, there's no reason an objects health should be limited to integers. Think for example rapid poison or some other form of DOT damage that rapidly ticks down health. Suggest converting it to a float.
I can PR if you're happy.

Sounds great, yes please!


Output path handling overhaul (all modules)

Create a class (possibly a global?) that is capable of handling and generating output paths for any file type.  It seems as if similar code is used for almost all of the pdf.conduit modules so that can likely be replaced with a class or function call.  Further, not every module has the ability to specify an output directory at this time.

Create directory if it does not exist should be one of the features.


Display approximate dates as "ca. [date]"

These currently display with a question mark behind them.
A single approximate date should read "ca. 1492"
An approximate data range should read as one of the following, depending on whether one or both dates are approximate:

ca. 1492 - ca. 1529
ca. 1492 - 1529
ca 1492 - ca. 1529

FYI, the curent display is using the EDTF specification for dates http://www.loc.gov/standards/datetime/ (but we can convert that into displaying something else).

Date display logic expects w3cdtf dates (unless the date is before the year 1000).

@arcadiafalcone what display logic are you referring to?

@jcoyne I was thinking of mods_display.

@arcadiafalcone I think Amy is just talking about in the H2 app, which doesn't use mods at all. It just has a database column with a EDTF date/range in it.  Currently we're just printing out that value without applying any formatting.

@jcoyne is right -- I just mean the display in the app. It's currently a bit confusing in that it doesn't match to Stanford time (the local time for most users) and it doesn't tell you what time zone it is.


⚠ ClamAV has degraded performance

In a83fb03, ClamAV (https://spamassassin.apache.org/) experienced degraded performance:

HTTP code: 200
Response time: 270 ms

Resolved: ClamAV performance has improved in f723a42 after 5 minutes.


Mention the need for zones with NVIDIA Tesla K80 Accelerators for the default GCP configuration

Solves #1987

@abhi-g
Can you (or find someone in your company to) review this PR? Thanks!

/assign

preview: https://deploy-preview-1988--competent-brattain-de2d6d.netlify.app/docs/gke/deploy/deploy-cli/

@Bobgy, do you know if the following manifest requires NVIDIA K80 GPUs?
https://raw.githubusercontent.com/kubeflow/manifests/v1.0-branch/kfdef/kfctl_gcp_iap.v1.0.2.yaml

Yes, that's true.
Thanks for updating the doc!
/lgtm
/approve

/approve

@yashjakhotiya Can you please resolve the merge conflict?
Thanks!

Hi @yashjakhotiya I hope all is good! Please resolve the merge issue (cc @Bobgy @joeliedtke @RFMVasconcelos). This PR has gone a bit stale

I've helped resolve merge conflicts and update some content.
/assign @8bitmp3
do you want to review?

@8bitmp3 I don't think @yashjakhotiya has responded since creating the PR.
Let's get this in, because it's already an improvement
/lgtm
/approve


Manually setting texture mipmap levels

I want to be able to manually set which image is used for the different texture mipmap levels (I don't want these to be automatically generated). For your info I'm working in 3D.
I have a set of images: "image_mipmap_0.png", "image_mipmap_1.png", "image_mipmap_3.png" and then in my shader I choose which level I need with this:
float mipmapLevel = 2.0;
texture2D(image, uv, mipmapLevel);

This works when the mipmap levels gets automatically generated, but when trying to manually set these levels, it doesn't work (the mipmap levels are not used at all). I have created my own resource type (MipMapResource) because I thought it would be a good idea to set the mipmap levels at the same time as the resource gets uploaded:
class MipMapResource extends PIXI.resources.ImageResource {
  constructor(source, options) {
    super(source, options)
  }
  upload(renderer, baseTexture, glTexture, source) {
    super.upload(renderer, baseTexture, glTexture, source)
    for (let i=1; i<9; i++) {
       let imageData = getImageData(i)
       renderer.gl.texImage2D(baseTexture.target, i, baseTexture.format, baseTexture.format, baseTexture.type, imageData);
    }
  }
  static test(source, extension) {
    return extension === "jpg"
  }
}
PIXI.resources.INSTALLED.push(MipMapResource);

I just can't figure out how this is done, it seems this should work. I have tried to change MipMapResource.upload so it uploads a completely different texture (just to make sure MipMapResource works).
Could it be that PIXI automatically generates the mipmap levels after I have set them (in that case my mipmap levels is overwritten)?

Hello!
Congratulations with being the first pixi fan who's trying to upload custom mips.
I'm very happy to help you!
To solve this, you need to make sure that our texture manager actually sets mip parameters correctly.
Please look here:
https://github.com/pixijs/pixi.js/blob/dev/packages/core/src/textures/TextureSystem.js#L318
https://github.com/pixijs/pixi.js/blob/dev/packages/core/src/textures/TextureSystem.js#L390
if you override style method of resource, you'll be able to set correct mip params there, and then case default logic wont override your levels (https://github.com/pixijs/pixi.js/blob/dev/packages/core/src/textures/TextureSystem.js#L415)
I'm gonna experiment with it today or tomorrow. I want to replicate https://twitter.com/JasperRLZ/status/1198133920841129985

Also, did you see by a chance any other renderer that allows you to call texImage2D's manually?
I'll be happy to have your feedback after we resolve this, I'm trying to persuade other renderer creators to adopt something like that.

Just to be sure, its better to create MipMapResource manually.
Suppose you have image or canvas element, you can use new BaseTexture(new MipMapResource(myImage, options)). Don't forget to wrap it in Texture too.

Thanks for the help! This is what I did to make it work:

Create a loader which understand the concept of mipmaps. This will make it easier later when having a relation between base texture and it's mipmaps.

PIXI.Loader.registerPlugin({
  use(resource, next) {
    if (resource.type !== PIXI.LoaderResource.TYPE.IMAGE || !resource.texture || !resource.metadata.mipmaps) {
      return next()
    }
    for (let i = 0; i < resource.metadata.mipmaps.length; i++) {
      this.add({
        url: resource.metadata.mipmaps[i],
        parentResource: resource,
      })
    }
    return next()
  }
})

After doing that, I can load my mipmaps like this:
app.loader.add(cubemap_posx_0.png, {
  metadata: {
    mipmaps: [
      "cubemap_posx_1.png",
      "cubemap_posx_2.png",
      "cubemap_posx_3.png",
      "cubemap_posx_4.png"
    ]
  }
})

Create a mipmap resource which will upload the mipmaps at the same time as the base texture.

class MipMapResource extends PIXI.resources.ImageResource {
  constructor(source, options) {
    super(source, options)

    let resource = app.loader.resources[source]

    this.mipmaps = []
    for (let i = 0; i < resource.metadata.mipmaps.length; i++) {
      let url = resource.metadata.mipmaps[i]
      this.mipmaps[i] = app.loader.resources[url].data
    }
  }
  upload(renderer, baseTexture, glTexture, source) {
    if (!super.upload(renderer, baseTexture, glTexture, source)) {
      return false
    }
    for (let i = 0; i < this.mipmaps.length; i++) {
      renderer.gl.texImage2D(baseTexture.target, i + 1, baseTexture.format,
        baseTexture.format, baseTexture.type, this.mipmaps[i])
    }
    return true;
  }
  static test(source, extension) {
    return extension === "png"
  }
}

PIXI.resources.INSTALLED.push(MipMapResource);

Create a cubemap mipmap resource which can set the correct texture parameters.

class CubeMipMapResource extends PIXI.resources.CubeResource {
  constructor(resources, options) {
    super(resources, options)
  }
  style(renderer, texture, glTexture) {
    let gl = renderer.gl

    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_BASE_LEVEL, 0)
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAX_LEVEL, 6)

    return true
  }
}

Create a cubemap mipmap texture just for convenience.

class CubeMipMapTexture extends PIXI.BaseTexture {
  static from(resources, options) {
    return new CubeMipMapTexture(new CubeMipMapResource(resources, options));
  }
}

It now ready to be used like this:

let cubemap = CubeMipMapTexture.from([
    "cubemap_posx_0.png",
    "cubemap_negx_0.png",
    "cubemap_posy_0.png",
    "cubemap_negy_0.png",
    "cubemap_posz_0.png",
    "cubemap_negz_0.png"
  ]);

Could something be done in a better way?

Yes, if your target is PC and not mobile devices, you can just use DDS textures from pixi-compressed-textures. or even more - use BASIS. There are bad sides of those formats but i dont know about your case :)
I can help you to make a simple plugin or example out of this, or you can make just make an article,

@jnsmalm I think your approach is pretty good, but there would be a couple things I would change if I wanted to make it more scalable. (I think this could be a good plugin, if you smooth out rough bits a little).
The concept of resources is a somewhat opaque API from the standpoint of the BaseTexture. I would try to eliminate CubeMipMapTexture as a class and rely on BaseTexture's autoDetectResource to figure out what the resource is.
For instance, let's define a structure for our MipMap:
{
  "source": "cubemap_posx_0.png",
  "mipmaps": [
     "cubemap_posx_1.png",
      "cubemap_posx_2.png",
      "cubemap_posx_3.png",
      "cubemap_posx_4.png"
  ]
}

Create your resource, and provide a test function that will be used to auto-detect the resource when it's passed to BaseTexture.from:
class MipMapResource extends PIXI.resources.CubeResource {
  // omitting logic, just to show the `test` function
   static test(source) {
      return typeof source === 'object' &&
        source.source instanceof PIXI.Texture && Array.isArray(source.mipmaps);
   }
}
// Will be used in auto-detect list
PIXI.resources.INSTALLED.push(MipMapResource);

Then create a Loader plugin. Let's externalize your mipmap object as cubemap_posx.mipp and use the loader to load it as JSON:
const MipMapLoader = {
  add() {
    PIXI.LoaderResource.setExtensionXhrType('mipp', LoaderResource.XHR_RESPONSE_TYPE. JSON);
    PIXI.LoaderResource.setExtensionLoadType('mipp', LoaderResource.LOAD_TYPE.JSON);
  },
  use(resource, next) {
     if (!resource.data && resource.type !== LoaderResource.TYPE.JSON) {
         return next();
     }
     // load the images here contained in the mipp file, reference SpritesheetLoader as an example
     // for loading resource contained in another data file. Then create a new texture with images:
     resource.texture = PIXI.Texture.from(resource.data);
     next();
   }
};

Then simply load the mipp file and the loader should handle the rest:
app.loader.add('cubemap_posx', 'cubemap_posx.mipp');
app.loader.load((loader, resources) => {
    // get your texture, the baseTexture.resource should be a MipMapResource
    console.log(resources.cubemap_posx.texture);
});

Thanks for the suggestions, I'll continue working on this

@bigtimebuddy Is this below correct? It doesn't work for me, the only argument I get in test function is source (which is a string) so I can't check the mipmaps there.
class MipMapResource extends PIXI.resources.CubeResource {
  // omitting logic, just to show the `test` function
   static test(source) {
      return typeof source === 'object' &&
        source.source instanceof PIXI.Texture && Array.isArray(source.mipmaps);
   }
}

If anyone else is looking for a solution, here is the code for how I solved it using TypeScript. In my case I'm using this for loading cubemaps.
import { CubeMipMapResource } from "./cube-mipmap"
import { ImageMipMapResource } from "./image-mipmap"

export interface CubeMapResource { source: string, mipmap?: string[] }

export const CubeMapLoader = {
  use: (resource: any, next: () => void) => {
    if (resource.extension !== "cubemap") {
      return next()
    }
    let faces = createFacesResource(resource.data)
    if (resource.data.mipmap) {
      ImageMipMapResource.install()
      resource.texture = new PIXI.CubeTexture(
        new CubeMipMapResource(faces, resource.data.mipmap.length))
    } else {
      resource.texture = PIXI.CubeTexture.from(
        faces.map((value) => { return value.source }))
    }
    next()
  },
  add: () => {
    PIXI.LoaderResource.setExtensionXhrType(
      "cubemap", PIXI.LoaderResource.XHR_RESPONSE_TYPE.JSON)
  }
}

const FACES = ["posx", "negx", "posy", "negy", "posz", "negz"]

function createFacesResource(data: CubeMapResource): CubeMapResource[] {
  return FACES.map((value) => {
    let result: CubeMapResource = {
      source: data.source.replace("{{face}}", value),
      mipmap: []
    }
    if (data.mipmap && data.mipmap.length > 0) {
      for (let i = 0; i < data.mipmap.length; i++) {
        let url = data.mipmap[i].replace("{{face}}", value)
        if (result.mipmap) {
          result.mipmap.push(url)
        }
      }
    }
    return result
  })
}

export class CubeMipMapResource extends PIXI.resources.CubeResource {
  constructor(resources: any, public levels: number) {
    super(resources)
  }

  style(renderer: any) {
    let gl = renderer.gl

    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR)
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_BASE_LEVEL, 0)
    gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAX_LEVEL, this.levels - 1)

    return true
  }
}

import { CubeMapResource } from "./cubemap-loader"

export class ImageMipMapResource extends PIXI.resources.ImageResource {
  mipmap: PIXI.Texture[] = []

  constructor(source: CubeMapResource, options: any) {
    super(source.source, options)
    if (source.mipmap) {
      for (let i = 0; i < source.mipmap.length; i++) {
        this.mipmap.push(PIXI.Texture.from(source.mipmap[i]))
      }
    }
  }

  upload(renderer: any, baseTexture: PIXI.BaseTexture, glTexture: any, source: any) {
    if (!super.upload(renderer, baseTexture, glTexture, source)) {
      return false
    }
    for (let i = 0; i < this.mipmap.length; i++) {
      let data = this.mipmap[i].baseTexture.resource.source
      renderer.gl.texImage2D(baseTexture.target, i + 1, baseTexture.format,
        baseTexture.format, baseTexture.type, data)
    }
    return true;
  }

  static test(source: any) {
    return typeof source === "object" && typeof source.source === "string" &&
      Array.isArray(source.mipmap)
  }

  static install() {
    if (PIXI.resources.INSTALLED.indexOf(ImageMipMapResource) < 0) {
      PIXI.resources.INSTALLED.push(ImageMipMapResource)
    }
  }
}

The cube map resource looks like this for example:
test.cubemap
{
  "source": "radiance/test/test_{{face}}_0_128x128.png",
  "mipmap": [
    "radiance/test/test_{{face}}_1_64x64.png",
    "radiance/test/test_{{face}}_2_32x32.png",
    "radiance/test/test_{{face}}_3_16x16.png",
    "radiance/test/test_{{face}}_4_8x8.png",
    "radiance/test/test_{{face}}_5_4x4.png"
  ]
}

Just load it with this:
app.loader.add("cubemap", "test.cubemap")
app.loader.load(() => {
  let cubemap = app.loader.resources["cubemap"].texture
})


[Feature Request] option to swap A and B button functionality

Hello,
I thought it would be useful for some. On most retro handhelds, the button layout is the Nintendo layout with the ability to change the style between retro and Xbox. When the style is set to xbox, this means that in daijisho, the B button is set to select and A button is set to back. This if counterintuitive for some. The Xbox style makes it easier to play some Android games.
For example, in the Castlevania SOTN android port. On retro style, the Abutton is for jump and the B and X are attack buttons. This makes it awkward. But on xbox style, B is Jump and Y and A are attack buttons. This feels more natural.
So I believe the option to swap A and B button functionality in Daijisho would be beneficial, but I understand if it cannot be done or if it is too difficult. (I'm not a coder, so I have no idea)
Thank you.

Daijishou doesn't interact in any way a controller binds it's keys. That's decided by Android. You can however change the image of the footer of Daijishou's screen if that's what your talking about:

Daijishou > Settings > Appearance > enable Swap A and Buttons

I know it can change the footer, I mean the actual function of the buttons. Simply, it would be convenient if there was an option to make it so that instead of A = Select and B = Back, reverse the function. So that daijisho sees A button as back and B button as select. I really hope I'm making sense 😅


Adding weighted_sample() and balanced_sample() utils

Adds a fiftyone.utils.random module with two new helpful randomized sampling utils:

weighted_sample(): Generates a random sample of size k from the given collection such that the probability of selecting each sample is proportional to the given per-sample weights
balanced_sample(): Generates a random sample of size k from the given collection such that the expected histogram of path values in the sample is uniform

Also migrates the existing fiftyone.utils.splits.random_split() util to the fiftyone.utils.random module, because it seems like a better organization (put all randomized utils in one-place).
Example usage:
import fiftyone as fo
import fiftyone.utils.random as four
import fiftyone.zoo as foz
from fiftyone import ViewField as F

dataset = foz.load_zoo_dataset("cifar10", split="train")

# Sample proportional to label length
weights = dataset.values(F("ground_truth.label").strlen())
view1 = four.weighted_sample(dataset, 10000, weights)

# Now take a balanced sample from this unbalanced sample
view2 = four.balanced_sample(view1, 2000, "ground_truth.label")

# Plot results
plot1 = fo.CategoricalHistogram("ground_truth.label", init_view=dataset)
plot2 = fo.CategoricalHistogram(
    "ground_truth.label",
    order=lambda kv: -len(kv[0]),  # order by label length
    init_view=view1,
)
plot3 = fo.CategoricalHistogram("ground_truth.label", init_view=view2)
plot = fo.ViewGrid([plot1, plot2, plot3])
plot.show()

@ehofesmann thanks for the ideas!
I agree that always using tags to encode the splits was unnecessary complexity. My goal was to match the API of the random_split() method, which does use tags. But I think I found a cleaner approach 🤗 :
I made tags an optional argument for weighted_sample() and balanced_sample(), so no tags are used by default, and I added a new syntax to random_split():
list, of, view = four.random_split(dataset, [list, of, fracs])

Regarding the "split" terminology, I agree that it's a bit overloaded with our Sample, but on the other hand taking a random "sample" is standard terminology in statistics, so I think it might be best to stick with the sample terminology in the fiftyone.utils.random module. Cool with that?


Enhancement: Implement StrictClient

Q
A

Bug fix?
no

New feature?
yes

BC breaks?
no

Deprecations?
no

Related tickets
fixes #41

Documentation
todo

License
MIT

What's in this PR?
This PR

[x] introduces a StrictClient which allows configuration of a sequence of matchers, and which will throw an exception when a request was sent that was not expected

Example Usage
Without configured sequence
<?php

use Http\Mock\StrictClient;
use Nyholm\Psr7\Request;

$httpClient = new StrictClient();

var_dump($httpClient->hasCompletedSequence()); // true

// UnexpectedRequestException will be thrown
$httpClient->sendRequest(new Request(
    'GET',
    '/foo/bar'
));

With configured sequence and an unexpected additional request
<?php

use Http\Message\RequestMatcher\CallbackRequestMatcher;
use Http\Mock\StrictClient;
use Nyholm\Psr7\Request;
use Nyholm\Psr7\Response;
use Psr\Http\Message\RequestInterface;

$httpClient = new StrictClient();

var_dump($httpClient->hasCompletedSequence()); // true

$httpClient->on(
    new CallbackRequestMatcher(static function (RequestInterface $request): bool {
        return 'POST' === $request->getMethod() && '/foo/bar' === (string) $request->getUri();
    }),
    new Response(
        200,
        [],
        'Sounds good!'
    )
);

var_dump($httpClient->hasCompletedSequence()); // false

$httpClient->sendRequest(new Request(
    'POST',
    '/foo/bar'
));

var_dump($httpClient->hasCompletedSequence()); // true

// UnexpectedRequestException will be thrown
$httpClient->sendRequest(new Request(
    'POST',
    '/foo/bar'
));

With configured sequence and an unexpected request
<?php

use Http\Message\RequestMatcher\CallbackRequestMatcher;
use Http\Mock\StrictClient;
use Nyholm\Psr7\Request;
use Nyholm\Psr7\Response;
use Psr\Http\Message\RequestInterface;

$httpClient = new StrictClient();

var_dump($httpClient->hasCompletedSequence()); // true

$httpClient->on(
    new CallbackRequestMatcher(static function (RequestInterface $request): bool {
        return 'POST' === $request->getMethod() && '/foo/bar' === (string) $request->getUri();
    }),
    new Response(
        200,
        [],
        'Sounds good!'
    )
);

var_dump($httpClient->hasCompletedSequence()); // false

$httpClient->sendRequest(new Request(
    'POST',
    '/foo/bar'
));

var_dump($httpClient->hasCompletedSequence()); // true

// UnexpectedRequestException will be thrown
$httpClient->sendRequest(new Request(
    'GET',
    '/foo/bar'
));

With configured sequence, but not all requests have been sent yet
<?php

use Http\Message\RequestMatcher\CallbackRequestMatcher;
use Http\Mock\StrictClient;
use Nyholm\Psr7\Request;
use Nyholm\Psr7\Response;
use Psr\Http\Message\RequestInterface;

$httpClient = new StrictClient();

var_dump($httpClient->hasCompletedSequence()); // true

$httpClient->on(
    new CallbackRequestMatcher(static function (RequestInterface $request): bool {
        return 'POST' === $request->getMethod() && '/foo/bar' === (string) $request->getUri();
    }),
    new Response(
        200,
        [],
        'Sounds good!'
    )
);

$httpClient->on(
    new CallbackRequestMatcher(static function (RequestInterface $request): bool {
        return 'GET' === $request->getMethod() && '/foo/bar' === (string) $request->getUri();
    }),
    new Response(
        400,
        [],
        'Now is not a good time'
    )
);

var_dump($httpClient->hasCompletedSequence()); // false

$httpClient->sendRequest(new Request(
    'POST',
    '/foo/bar'
));

var_dump($httpClient->hasCompletedSequence()); // false

With configured sequence and all requests have been sent in correct order
<?php

use Http\Message\RequestMatcher\CallbackRequestMatcher;
use Http\Mock\StrictClient;
use Nyholm\Psr7\Request;
use Nyholm\Psr7\Response;
use Psr\Http\Message\RequestInterface;

$httpClient = new StrictClient();

var_dump($httpClient->hasCompletedSequence()); // true

$httpClient->on(
    new CallbackRequestMatcher(static function (RequestInterface $request): bool {
        return 'POST' === $request->getMethod() && '/foo/bar' === (string) $request->getUri();
    }),
    new Response(
        200,
        [],
        'Sounds good!'
    )
);

$httpClient->on(
    new CallbackRequestMatcher(static function (RequestInterface $request): bool {
        return 'GET' === $request->getMethod() && '/foo/bar' === (string) $request->getUri();
    }),
    new Response(
        400,
        [],
        'Now is not a good time'
    )
);

var_dump($httpClient->hasCompletedSequence()); // false

$httpClient->sendRequest(new Request(
    'POST',
    '/foo/bar'
));

var_dump($httpClient->hasCompletedSequence()); // false

$httpClient->sendRequest(new Request(
    'GET',
    '/foo/bar'
));

var_dump($httpClient->hasCompletedSequence()); // true

Checklist

[ ] Updated CHANGELOG.md to describe BC breaks / deprecations | new feature | bugfix
[ ] Documentation pull request created (if not simply a bugfix)

@dbu
I probably should have openend a draft pull request.
We're currently testing this in a project, perhaps we'll wait a bit to see how well this goes, and then I'll circle back to see if this needs improvements.


Cmd line argument to set log level

Logging level can be configured from cmd line, default INFO.
fix #743
Contributor Checklist:

[x] I have added a changelog entry for my contribution
[x] I have added/updated documentation for all user-facing changes

Alias of --local-directory is changed to -d,  so -l can be used for --log-level. Is this ok @sk1p ?

Alias of --local-directory is changed to -d,  so -l can be used for --log-level. Is this ok @sk1p ?

Yep! 👍

is there anything else to do? @sk1p

Sorry, didn't want to approve actually - read it as a "functionality approved, usability should be improved", please :grin:

Thx for the review : ) will fix ASAP :+1:

Nice, thanks! :sparkles:


Get the full PWA configuration done for mobile “installed”

The app currently works just okay on mobile browsers. We really need to create the PWA manifest and set some things like the app icon and browser details. It’s been a long time since I’ve done this so I don’t have any other guidance to provide, off the top of my head, but even just a first pass at the manifest would be an improvement.

@jasonpaulso say hi on this comment thread, for some reason github doesn't let me assign an issue to you until you've commented on them.

👋


file .dll

Hi, where i can found the .dll file? downloaded today but i didn't found it :(

https://github.com/anoyetta/ACT.SpecialSpellTimer/releases/download/v1.6.4/ACT.SpecialSpellTimer-v1.6.4.zip


Deserialization error when executing PublishAllXmlAsyncRequest

I'm using the PowerPlatform.Dataverse.Client v1.0.9 on .NET v4.8.
When trying to call the new PublishAllXmlAsyncRequest, I'm getting a deserialization error.
Code:
ServiceClient client = new ServiceClient(connectionString);
var req = new PublishAllXmlAsyncRequest { RequestId = Guid.NewGuid() };
PublishAllXmlAsyncResponse publishResponse = (PublishAllXmlAsyncResponse)client.Execute(req);
Console.WriteLine("Waiting for PublishAll async job to complete");
Error:
System.ServiceModel.ProtocolException: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://schemas.microsoft.com/xrm/2011/Contracts/Services:request. The InnerException message was 'Error in line 1 position 711. Element 'http://schemas.microsoft.com/xrm/2011/Contracts/Services:request' contains data from a type that maps to the name 'http://schemas.microsoft.com/crm/2011/Contracts:PublishAllXmlAsyncRequest'. The deserializer has no knowledge of any type that maps to this name. Consider changing the implementation of the ResolveName method on your DataContractResolver to return a non-null value for name 'PublishAllXmlAsyncRequest' and namespace 'http://schemas.microsoft.com/crm/2011/Contracts'.'.  Please see InnerException for more details.\r\n\r\nServer stack trace: \r\n   at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConve
rter faultConverter)\r\n   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)\r\n   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)\r\n   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)\r\n   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)\r\n\r\nException rethrown at [0]: \r\n   at Microsoft.PowerPlatform.Dataverse.Client.ServiceClient.Execute(OrganizationRequest request)\r\n

fyi, same error when using the CrmServiceClient of CrmSdk/XrmTooling. Seems both SDKs have the same issue with this new request.

That SDK message is very new,
Please check DVSvcClient 1.0.23, I believe it should be included there.
for the CrmServiceClient, Update the Microsoft.crmsdk.coreassemblies to the current release.

@Chielus
This appears to be a bug with the message format in the dataverse server definition, the owning team is looking into it currently.
In the mean time,   Please try this:
var req = new OrganizationRequest("PublishAllXmlAsync");
var resp = client.Execute(req);
let me know if that unblocks you for now.

Folks,
The fix for this should have rolled out to all regions at this point,
Please reopen if your still experiencing an issue.
thanks !


fixed the check for duplicate route being pushed

Noticed that there is an issue with NavigationStateUtils.push method. In the original react-native version you will notice that it uses invariant check for indexOf(state, route.key) === -1:
function push(state: NavigationState, route: NavigationRoute): NavigationState {
  invariant(
    indexOf(state, route.key) === -1,
    'should not push route with duplicated key %s',
    route.key,
  );
...
}

Where as the react-native-mock version throws an error if indexOf(state, route.key) === -1 is true:
function push(state, route) {
  if (indexOf(state, route.key) === -1) {
    throw new Error('should not push route with duplicated key ' + route.key);
  }
...
}

Invariant throws an error for falsy values (https://github.com/zertosh/invariant#invariantcondition-message). Therefore the above should be: indexOf(state, route.key) !== -1

Duplicate of #81, closing


Control flow based type analysis

This PR introduces control flow based type analysis for local variables and parameters as initially suggested in #2388 and prototyped in #6959. Previously, the type analysis performed for type guards was limited to if statements and ?: conditional expressions and didn't include effects of assignments and control flow constructs such as return and break statements. With this PR, the type checker analyses all possible flows of control in statements and expressions to produce the most specific type possible (the narrowed type) at any given location for a local variable or parameter that is declared to have a union type.
Some examples:
function foo(x: string | number | boolean) {
    if (typeof x === "string") {
        x; // type of x is string here
        x = 1;
        x; // type of x is number here
    }
    x; // type of x is number | boolean here
}

function bar(x: string | number) {
    if (typeof x === "number") {
        return;
    }
    x; // type of x is string here
}

Control flow based type analysis is particuarly relevant in --strictNullChecks mode because nullable types are represented using union types:
function test(x: string | null) {
    if (x === null) {
        return;
    }
    x; // type of x is string in remainder of function
}

Furthermore, in --strictNullChecks mode, control flow based type analysis includes definite assignment analysis for local variables of types that don't permit the value undefined.
function mumble(check: boolean) {
    let x: number; // Type doesn't permit undefined
    x; // Error, x is undefined
    if (check) {
        x = 1;
        x; // Ok
    }
    x; // Error, x is possibly undefined
    x = 2;
    x; // Ok
}

The narrowed type of a local variable or parameter at a given source code location is computed by starting with the initial type of the variable and then following each possible code path that leads to the given location, narrowing the type of the variable as appropriate based on type guards and assignments.

The initial type of local variable is undefined.
The initial type of a parameter is the declared type of the parameter.
The initial type of an outer local variable or a global variable is the declared type of that variable.
A type guard narrows the type of a variable in the code path that follows the type guard.
An assignment (including an initializer in a declaration) of a value of type S to a variable of type T changes the type of that variable to T narrowed by S in the code path that follows the assignment.
When multiple code paths lead to a particular location, the narrowed type of a given variable at that location is the union type of the narrowed types of the variable in those code paths.

The type T narrowed by S is computed as follows:

If T is not a union type, the result is T.
If T is a union type, the result is the union of each constituent type in T to which S is assignable.

Thanks to @ivogabe for providing inspiration and tests for this PR.
Fixes #2388.

If T is not a union type, the result is T.

Would it be interesting to consider sub-classes narrowing? Just thinking out loud, not sure if it has value:
class Human { };

class Wizard extends Human {
  void castSpell();
};

let x: Human;
x = new Wizard();
x.castSpell(); // <- statically ok?

I guess I'll be the one to start the heated discussion, please don't hate me:

Furthermore, in --strictNullChecks mode, control flow based type analysis includes definite assignment analysis for local variables of types that don't permit the value undefined.

Should you do the same check for a variable that permit the value undefined? I am personnally OK with the answer "no", but some people want to use undefined as their "empty" value, maybe even promote some sugar for it (either var x?: number or var x: number?). Under those assumptions, I would find the following code suspicious in a strongly-typed language:
let x?: number;
// lots of fancy logic with a single unassigned code path
return x; // did we intend x to be undefined here, or did we forget one code path?

I won't be championing that as I'm using null for my empty values anyway. But to be fair with the undefined fans I think it has to be asked.

@jods4 we were discussing the exact Human / Wizard scenario earlier and have some theories about what might work.
The problem with directly narrowing is cases like this:
interface Options {
  name: string;
  length?: number;
  width?: number;
}
let x: Options = { name: 'a' }; // 1
x = { name: 'other', length: 10 }; // 2
x.width = 32; // 3

On line 2, we can't blindly take the RHS type and overwrite the declared type of x, because it'd break line 3.
It hasn't been implemented yet, but using intersection may solve this problem (in your example, we'd assign the type Human & Wizard to x and allow the method call).
One open question from that discussion was whether or not this code ought to be an error:
let x: { a?: string; b?: number };
let y: { a: string; } = { a: 'foo' };
x = y;
x.b = 30;

@jods4 @RyanCavanaugh You can also get issues with generics:
let x: Array<string | number>;
x = ["a", "b"];
x.push(42)

If x would be narrowed to Array<string>, the last line would give an error. I think narrowing only union types after an assignment would support most use cases.

@RyanCavanaugh Structural typing with optional members is indeed more complicated: reading is ok, but you may want to assign missing optional parent members!
I think your & idea would work fine: the initial variable keeps its declared type, yet is extended with additionnal members that are provably there by definite assignment.
The Wizard was "real" inheritance, which seems easy as you can't hide/miss existing members.
Wizard extends Human => Human & Wizard simplifies to just Wizard, right?
I think your x / y example ought to work. x was declared as having an optional member b, so you should be allowed to assign x.b no matter what the underlying object is.
If there should be an error then it would be the assignment x = y, but under current TS structural typing rules it's fine. I think the saying y has the shape { a: string } doesn't exclude the fact that it may have other members, or prevent it from gaining new members in other ways than manipulating y... Types in TS are not closed.
Applying & logic in this case would yield this result.
Note that your code is unsafe for another reason, though:
let x: { a?: string; b?: number };
let y: { a: string; } = { a: 'foo' };
x = y;
x.a = undefined;
y.a.length; // oops!

On what line is this an error?
@ivogabe This is a different case... Array<string> is not a subclass of Array<string | number> (which was my initial suggestion). And if we apply @RyanCavanaugh's extended logic to all types, then we get x: Array<string> & Array<string | number> which would work just fine in your example?

@ahejlsberg In my branch, I only tried to figure out the type of an assignment if the variable was of a union type. In this branch, you always try to get the type, and then only narrow if the variable is a union type. For non-union variables, I only check whether it was assigned, not what. That might prevent some issues, for instance issues similar to the one with the // !!! comment. And it might improve the performance of the language service a bit.
@jods4 @RyanCavanaugh Sorry, I thought you were talking about subtypes instead of subclasses. Though in a structural type system, subclasses do not really exist, strictly spoken. I think that intersection types would be a better way to model this, but they can still have issues with generics:
function sum(xs: number[]) { return xs.reduce(...) }
let x: Array<string | number>;
x = [1, 4];
// x: Array<number> & Array<string | number>
x.push("");
sum(x);

This would compile with the proposed behavior. Also error messages would be uglier with this change. I think this would be something to consider after this PR.

@ahejlsberg Would the following code show an error that x might not be assigned (eg, might be null)?
let x: string;
x = "";
for (;;) {
    x = x;
    x.substring; // <-- here
}

I'm asking this because of the loop, which causes the narrowing after the assignment to fail (due to recursion). Though I think that that should not break assignment checking, as an assigned value should not be null.

@ivogabe Your example is already broken in TS today, because we have array covariance like in C# and Java... Without any narrowing:
var x: (string | number)[];
var y = [0, 1];
x = y;
x.push("two");
y[2].toPrecision(3); // runtime fail: y[2] is not a number

And the same happens with nullables, because reading is covariant and writing contra-variant but the language just goes for co- all the time, copied from my comment above:
let x: { a?: string; b?: number };
let y: { a: string; } = { a: 'foo' };
x = y;
x.a = undefined;
y.a.length; // oops!

The & idea just extends how the language already works. Not saying we must have it, I was just submitting some random thoughts about the narrowing description by @ahejlsberg.

@ivogabe If you look at the code in checkIdentifier starting here you'll see that if the initial type of a variable is its declared type, and if the variable is not of a "narrowable" type (i.e. not a union type but for example a primitive type), then I don't compute the narrowed type. This is definitely an important optimization.
There is no error in your example:
let x: string;
x = "";
for (;;) {
    x = x;
    x.substring; // Ok
}

Since the declared type of x is string and the narrowed type of x is string in the first code path into the loop, we never even examine the back branch because there is nothing it could do to further affect the type of x. Specifically, when there are multiple code paths leading to a given location, if one of the code paths already yields the declared type (the least specific type the variable could have), then no other code path could affect the result because we're going to union the types together in the end.

@ahejlsberg Thanks for the explanations. I have played a bit with it and it works pretty good. Though I found two issues. First, the assignment checks report multiple errors for the same issue. In this example, the compiler reports an error that x is not assigned and that substring does not exist on the empty type. I would say that even though x will be undefined there, it would be better to type it as the initial type there, since you already got the real error.
    let x: string;
    x.substring;
//  ~            Used before assigned
//    ~~~~~~~~~  `substring` does not exist on `{}`

In unreachable code, you will get a lot of not-assigned errors:
let x = "";
while (true);
x = ""; // Unreachable
x; // Used before assigned

I think that you shouldn't get the error there. Also, I think that if the third line would be absent, it should still not give an error that x is not assigned since you already have the unreachable code error. Instead, it can fall back to the initial type.
A more serious issue is that the back flow of a loop only works if the condition is a type guard. In the first example, y is narrowed to string, so number is missing. The second example works correctly.
let y: string | number | boolean;
y = "";
while (true) {
	y; // string
	y = 1;
}

let y: string | number | boolean;
y = "";
while (typeof x === "string") {
	y; // string | number
	y = 1;
}

@ivogabe The problem with the missing back flow is caused by an overly aggressive optimization in the finishFlow function in the binder. Good catch. I'll have a fix for it shortly.

might be relevant
https://github.com/Microsoft/TypeScript/issues/4040

@ivogabe Improved the error reporting as you suggested. It does indeed reduce the noise.

Latest commit implement what I think is a reasonable compromise for the "evolving types" issue discussed here. Now, when computing the narrowed type of a variable reference leads to resolving call signatures (for example because the variable is assigned the result of a function call along the control flow path), we don't cache the result of those call signature resolutions. Thus, in the subsequent actual type check of the call, we'll re-check with the further evolved type of the variable. Effectively, this handles evolving types as long as the types settle out after the first iteration. It does not handle cycles or ladders of overloads by exhaustively iterating to a fixed point, but I don't really consider those to be real world scenarios anyway.
Here's an example that is now handled correctly:
declare function foo(s: string | number): number;

function f() {
    let x: string | number | boolean;
    x = "";
    while (cond) {
        x; // string | number
        x = foo(x);
        x; // number
    }
    x; // string | number
}

Determination of the type of the first reference to x within the loop proceeds as follows: First we visit the code path leading to the loop. That produces type string for x (which is cached). Next we examine the loop-back code path. That requires us to resolve the call to foo(x). This in turn requires us to determine the type of x, which leads us back to the top of the loop. Here we see string cached from the first code path and an indication that we're processing the loop-back path, so we consider the type of x to simply be string. This is used to resolve foo(x) to type number, and the result of the outer resolution of the loop-back path becomes number (which is cached). Now, the subsequent actual type check of foo(x) will see string | number as the type of x.

@ahejlsberg I think this is the right compromise.

I've been playing around with this branch the past couple of days and I've noticed that any doesn't narrow on control-flow assignments. Is this expected behavior?
For example:
let a: any;
a = "10";
a; // a: any ... expected a: string
a.toFixed(2); // no compile error!

We are using noImplicitAny in our codebase, and try to avoid explicit any as much as humanly possible, but it seems like a generally good thing to continue to catch errors when using any (implicitly or explicitly).

@thebanjomatic That is the expected behavior currently. There are simple cases (such as your example) where we know the exact type of a value assigned to an any, but typically we only know parts of the truth. For example:
declare function foo(): { x: number };

let a: any;
a = foo();
let y = a.y;  // Can't error here

It would be a breaking change from the current behavior to give an error above. That said, we're thinking about ways we can do better with any and control flow analysis, but it probably won't be in the initial PR.

I found another issue in my code-base relating to destructuring assignments when noImplicitAny is enabled. It can be simplified to the following:
let [a, b, c] = [1, 2, 3];

The control flow appears to work correctly, however, 3 errors is produced saying that a, b, and c have an implicit type of any.

Nevermind, that appears to also be the case in master, I will file a separate issue for that.

Just trying out typescript now and working out for to get type check actions in redux. Looks like this feature could be very helpful for this?
https://github.com/reactjs/redux/issues/992


How to get cropped image?

Hey, I can get the cropped image? There's a button on the demo page, but in documentation, I didn't find it. Can anyone tell me how to get the cropped image? Probably there will a function.

Please post your answer, if you found one to this issue.

You can get it from the @input event or with v-model. It returns a base64 png image.


fix: DEV-3315: Custom column order needs to be different for different tabs

Hi @yyassi-heartex!
This PR was created in response to a PRs in upstream repo:

https://github.com/heartexlabs/dm2/pull/102

Closed as stale


Unable to receive file on a ramdisk(ramfs)

$ wormhole receive 2-candidate-wayside
Error: insufficient free space (0B) for file (10B)
TransferError: transfer rejected

I regularly need to send files that shouldn't touch a physical disk. Can something be done to fix this error?

Looks like your ramdisk is simply out of space?
In general it should be no problem to transfer to a ramdisk, as the software should see this like any other disk.

$ df -h
Filesystem                   Size  Used Avail Use% Mounted on
tmpfs                        3.2G  2.1M  3.2G   1% /run
/dev/mapper/ubuntu--vg-root  883G   38G  801G   5% /
tmpfs                         16G  962M   15G   7% /dev/shm
tmpfs                        5.0M  8.0K  5.0M   1% /run/lock
/dev/mapper/LUKS_BOOT        737M  313M  371M  46% /boot
/dev/nvme0n1p3               128M  6.1M  122M   5% /boot/efi
tmpfs                        3.2G  132K  3.2G   1% /run/user/1000

$ dd if=/dev/zero of=/home/alistair/ramdisk/test bs=100k count=1
1+0 records in
1+0 records out

Ram disk is not out of space...

Is there any other data I can provide to help?
I'm working with Ubuntu Lunar 23.04. ram disk is mounted by
mount -t ramfs -o size=100M /dev/ram0 /home/${LOCALUSER}/ramdisk
wormhole version is magic-wormhole 0.12.0

Thanks, that helps.
I haven't looked in any detail yet -- my suspicion is obviously with whatever code is trying to determine free space. That said, a ram-disk shouldn't be different in this regard from any other sort, but obviously something is up :)

Might be the source of the problem, but no idea how to resolve it...
https://github.com/magic-wormhole/magic-wormhole/blob/cbb00cbba1aa58dae46feac1fb521efc6ccb0511/src/wormhole/util.py#L66

I have tried on PureOS 10, with similar setup. I created the ramdisk with incantation mount -t tmpfs -o size=100M /dev/ram0 /tmp/ramdisk and successfully transferred "README.md" to this ramdisk.

Also tried with the ramdisk mounted in a user homedir and it worked too.

I have reached a wall for my current capabilities. I will have to wait for Ubuntu to package 0.13.0 to proceed further. Thank you for your attention thus far!

If I remember correctly, Ubuntu puts the home directory on a different partition. I doubt this makes a meaningful difference, but can you try with the ramdisk mounted somewhere else?
Alternatively I can try with a Lunar VM.


Using Search vs GDS

Hi Tom,
Quick question: is there any way I could use your two libraries at once?
Since the document creation is so close to the regular entity creation on GDS, how can I utilize both so that my entities go to the datastore and be searchable at once

Hi there,
I am sure you could build a layer of software to do this - the two
libraries are currently not linked together.
Tom
On 10 May 2016 at 20:17, Emil Orol<EMAIL_ADDRESS>wrote:

Hi Tom,
Quick question: is there any way I could use your two libraries at once?
Since the document creation is so close to the regular entity creation on
GDS, how can I utilize both so that my entities go to the datastore and be
searchable at once
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub
https://github.com/tomwalder/php-appengine-search/issues/13

--
Tom Walder, CTO
We're hiring. Find out more at www.docnet.nu/jobs
http://www.docnet.nu/jobs?utm_source=email_signature&utm_medium=email&utm_campaign=email_signature
Call: 0161 660 7110 / Web: www.docnet.nu
http://www.docnet.nu/?utm_source=email_signature&utm_medium=email&utm_campaign=email_signature
This message is private and confidential. If you have received this message
in error, please notify us and remove it from your system. Venditan Limited
t/a Docnet is a company registered in England and Wales. Registered number:
9604502. Registered office: Speakers House, 39 Deansgate, Manchester, M3 2BA

Hi Tom,
Thank you for your quick answer. Those this mean that if I want to use the entities I have on GDS with the Search at creation or update time I also have to create an document for them so that they can be search?

Seems like this is a common question:
http://stackoverflow.com/questions/10951936/when-should-i-not-use-app-engines-full-text-search-api
http://stackoverflow.com/questions/23317280/appengine-search-api-vs-datastore
And the solution will seem to be use the datastore to keep your entities and the search API to retrieve their content using a full text search.
http://sookocheff.com/post/appengine/syncing-search-documents-with-datastore-entities/

Hey Emil.
Thanks for the post.
Tom


LaTeX scanner: Find > 1 includes per line

^[^%\n]* at the beginning of the reg ex would match all but the last include so that they were lost. There is no point checking for % since comments are stripped anyways (and this would also fail on lines containing an escaped percent sign \%, right?). Also, I don't see the point of checking for the newline, so I just removed that altogether.

[x] I have created a new test or updated the unit tests to cover the new/changed functionality.
[x] I have updated master/src/CHANGES.txt directory (and read the README.txt in that directory)
[ ] I have updated the appropriate documentation

Please update src/CHANGES.txt to add a blurb for this change.

OK, done that (and also restored alphabetical order).

I removed the PR number from CHANGES.txt. I don't think there has been an issue for this to reference.

I"m not very familiar with LaTEX syntax. but does the comment before the regex not still apply?
        # We have to include \n with the % we exclude from the first part
        # part of the regex because the expression is compiled with re.M.
        # Without the \n,  the ^ could match the beginning of a *previous*
        # line followed by one or more newline characters (i.e. blank
        # lines), interfering with a match on the next line.
        # add option for whitespace before the '[options]' or the '{filename}'

It seems like if you change the regex, minimally you should update the comment before it referring to the bit you changed? Or am I misreading the comment/regex?

Oops, I missed that. So it seems like checking for \n is necessary in combination with checking for %, otherwise a possible match may not be found because there was a comment in a previous line. But as I said, I don't think checking for comments is necessary since they are stripped in canonical_text() anyways. Therefore I removed the (Python source code) comment.


TODO: Sign the plugin

Currently, the plugin is unsigned, which requires users to allow unsigned backend plugins (not a default setting).
However, as of right now there is no process to sign a community plugin like this.
See here: https://grafana.com/docs/grafana/latest/developers/plugins/sign-a-plugin/#sign-a-plugin

Fixed in v0.1.4 and v0.2.0


Introduce Resource Interface

After experimenting with Type Hints for pipeline-dsl I found out that it could be useful to have some kind of interface or abstract class for the resource objects. We then could use the interface also for the Type Hints.
Unfortunately, Type Hints is a pretty new feature in python and it is not that mature (e.g. types like Any are pretty slow in python <3.7).
WDYT?

Let's first merge this PR with these resources and then create a new PR for the remaining resources.
The only things where I'm not sure yet are the username and password fields because they are all marked as optional from their API documentation.
@phil9909 WDYT?


Add argument parameter for Launch Application process keyword #23

a side comment i see that as well in docu as in code the second arg of the lunch app is called arguments with s. Despite of the fact that it can not take more than one argument and forward it to the exe.

a side comment i see that as well in docu as in code the second arg of the lunch app is called arguments with s. Despite of the fact that it can not take more than one argument and forward it to the exe.

It can take more than one argument as a string representation. See FlaUI arguments in Application.cs
https://github.com/FlaUI/FlaUI/blob/master/src/FlaUI.Core/Application.cs
--> public static Application Launch(string executable, string arguments = null)


support view in nv/amd

length and size should use the passed in size, not length - offset. it can truncate from the end


New Widget for Comic format

For the science comic on Dylen, we need a new widget that allows a image or pdf to (almost) fill the width and height of the device screen, scalable to device; possibly offer zoom in.
Maybe offer flipbook option for 1+ page comics.
Ideally Alttext overlay in various positions (flexible?)
Dylen comic is current a high res PDF, could be converted to image format.

suggested markup:
<Carousel>
  <Figure caption="The first image" image="/images/first.png" />
  <Figure caption="The second image" image="/images/second.png" />
</Carousel>


Adding Socket Timeout Option to Mailer

What steps will reproduce the problem?
Migrate from Swift Mailer to Symfony Mailer
What's expected?
SwiftMailer has a transport->timeout property that can be set in the config.  Defaults to 30.
What do you get instead?
The Symfony Mailer does not have an exposed way to set the timeout for the EsmtpTransport.  (There is a value and a setter Method, but there is no way to call it since the transport is private...)
Additional info
If the Symfony Transport timeout property is not set it will default to the php.ini setting, 'default_socket_timeout'  which default to 60.
We can wrap the mailer->send() call, but it would be nice to be able to config the Mailer's timeout value.
We cannot add a new property to the transport itself, but we can add one to the yii Mailer class.
Possible solution:
class Mailer extends BaseMailer
 {
    /**
     * @var int transport_timeout defaults to 0 since this would only apply to smtp/smtps transports.
     */
    public $transport_timeout = 0;
    ...
    /**
     * {@inheritDoc}
     *
     * @throws TransportExceptionInterface If sending failed.
     */
    protected function sendMessage($message): bool
    {
        ...
        try {
            if (!empty($this->transport_timeout) && (int) $this->transport_timeout > 0) {
                $default_socket_timeout = ini_set('default_socket_timeout', (int) $this->transport_timeout);
            }
            $this->getSymfonyMailer()->send($message);
        } catch (\Exception $exception) {
            Yii::getLogger()->log($exception->getMessage(), \yii\log\Logger::LEVEL_ERROR, __METHOD__);
            // need to re-throw the exception so that caller can extract transport errors
            throw($exception);
        } finally {
            if (!empty($default_socket_timeout) && (int) $default_socket_timeout > 0) {
                ini_set('default_socket_timeout', (int) $default_socket_timeout);
            }
        }
        return true;
    }
}

Q
A

Yii version
2.0.45

Yii SymfonyMailer version
2.0.3

SymfonyMailer version
v6.0.11

PHP version
8.1.9

Operating system
Linux Mint 20.3 with Kernel Linux 5.15.0-46-generic

Copied from https://github.com/yiisoft/yii2-symfonymailer/pull/27#issuecomment-1216300900
You'd use a wrapper class (composition instead of inheritance) since Symfony even goes so far as to make their classes final so you cannot extend them.
class SmtpTransportWithTimeoutFactory implements TransportFactoryInterface {
    public function __construct(private TransportFactoryInterface $factory, private float $timeout)
    {
    }

    public function create(Dsn $dsn): TransportInterface
    {
        $result = $this->factory->create($dsn);
        if ($result instanceof SmtpTransport) {
            $result->getStream()->setTimeout($this->timeout);
        }
        return $result;
    }

    public function supports(Dsn $dsn): bool {
        return $this->factory->supports($dsn);
    }
}

Thanks!  This will be a big help.  I hadn't realized that Symfony classes were final.  I'd suggest even including this Factory with the Yii2 extension.

I was thinking that lack of control for the timeout of the Symfony smtp/smtps Transport was a major hurdle for migrating from Swift to Symfony.
It might be helpful in the Migrating From yiisoft/yii2-swiftmailer section (https://github.com/yiisoft/yii2-symfonymailer#migrating-from-yiisoftyii2-swiftmailer) to include the sample wrapper and how to wire it up in the config file.

Feel free to make a PR for the docs!


Overhaul command UX

[x] Make stop command return an ephemeral message
[x] Hide permission sync deprecation notice
[x] Display feature flags on start command
[x] Display session creation time on start command
[x] Update start command response on stopping session
[x] Add start command mention to the stop command response
[x] Display ended at time on stop command response
[x] Gather feedback after using stop command
[x] Improve error message after using start command

Todos:

[] add support link to start command
[] replace time stamp copy with old copy
[] remove feedback button colours and add three feedback levels - 😃, 🫤 and 🙁


bug: Error: 416: unexpected token at '"libpng'

install homebrew per the instruction on brew.sh (bash -c... etc)
add export HOMEBREW_INSTALL_FROM_API=1 to .zprofile
uninstall homebrew (/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)")
sudo rm -rf /opt/homebrew
install homebrew
cd Documents (where the Brewfile is located) && brew bundle install
in the middle of the process remember that there are unneeded (after setting HOMEBREW_INSTALL_FROM_API) taps in the list
remove from the top of Brewfile

tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/cask-fonts"
tap "homebrew/core"

none of the taps left (actually i think i left out /bundle and /cask-fonts, not sure)
uninstall brew && install brew
cd Documents && brew bundle install

==> Tapping homebrew/bundle
Cloning into '/opt/homebrew/Library/Taps/homebrew/homebrew-bundle'...
remote: Enumerating objects: 6844, done.
remote: Counting objects: 100% (47/47), done.
remote: Compressing objects: 100% (35/35), done.
remote: Total 6844 (delta 20), reused 32 (delta 12), pack-reused 6797
Receiving objects: 100% (6844/6844), 1.60 MiB | 333.00 KiB/s, done.
Resolving deltas: 100% (3986/3986), done.
Tapped 1 command (98 files, 2.0MB).
Using homebrew/bundle
Tapping homebrew/cask-fonts
Error: 416: unexpected token at '"libpng'
Please report this bug:
  https://github.com/Homebrew/homebrew-bundle/issues
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/json/common.rb:156:in `parse'
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/json/common.rb:156:in `parse'
/opt/homebrew/Library/Homebrew/api/formula.rb:38:in `all_formulae'
/opt/homebrew/Library/Homebrew/formulary.rb:678:in `loader_for'
/opt/homebrew/Library/Homebrew/formulary.rb:561:in `factory'
/opt/homebrew/Library/Homebrew/formula.rb:1917:in `[]'
/opt/homebrew/Library/Taps/homebrew/homebrew-bundle/lib/bundle/brew_dumper.rb:43:in `formulae_by_full_name'
/opt/homebrew/Library/Taps/homebrew/homebrew-bundle/lib/bundle/skipper.rb:12:in `skip?'
/opt/homebrew/Library/Taps/homebrew/homebrew-bundle/lib/bundle/installer.rb:37:in `block in install'
/opt/homebrew/Library/Taps/homebrew/homebrew-bundle/lib/bundle/installer.rb:11:in `each'
/opt/homebrew/Library/Taps/homebrew/homebrew-bundle/lib/bundle/installer.rb:11:in `install'
/opt/homebrew/Library/Taps/homebrew/homebrew-bundle/lib/bundle/commands/install.rb:10:in `run'
/opt/homebrew/Library/Taps/homebrew/homebrew-bundle/cmd/bundle.rb:94:in `bundle'
/opt/homebrew/Library/Homebrew/brew.rb:95:in `<main>'

i'm really struggling to follow your reproduction. can you re-word it to clarify the points a little more? on first glance, this looks more to be related to a local issue (install/cleanup failure) as opposed to one with bundle itself.

i've made some corrections. what points would you like me to clarify further?
there is a message that says
Please report this bug:
  https://github.com/Homebrew/homebrew-bundle/issues

so i followed the link and reported this bug 🙂

i'm not following:

why you are installing and uninstalling brew multiple times; and
why you are interrupting the bundle process.

this seems like a recipe for problems. I would recommend that you start with a clean install, remove any bundle files that you have previously created and start again to reproduce with a minimal test case.
the error reporting is shown if for any reason the tool hits unhandled exceptions (including if the user gets it into a weird state).
fwiw, installing from the API for all the formula you mentioned works fine for me so i'm leaning even further into this being a local issue.

this seems like a recipe for problems. I would recommend that you start with a clean install, remove any bundle files that you have previously created and start again to reproduce with a minimal test case.

fwiw, installing from the API for all the formula you mentioned works fine for me so i'm leaning even further into this being a local issue.

Agreed.


In HBase Ver 0.94.6, get error log of "[Thread-2] ERROR org.apache.hadoop.hbase.client.HConnectionManager.deleteConnection:301 - Connection not found in the list, can't delete it..."

Indeed, there are two problems.

In the sample of spring-data-book-hadoop-hbase, UserUtils.java is not safe as HBaseConnection
may be not closed when ApplicationContext is closed. Because,
@Override
public void afterPropertiesSet() throws Exception {
admin = new HBaseAdmin(config);
}
will create a connection and increase a count of connections.
If we have two class as UserUtils.java, that means 'new HBaseAdmin(config)' will be invoked twice, then
the count of connections is 2.

However, when xxxApplicationContext.close(), the count will be only decreased once, so the connection will not
really be closed/released. The detail ref to HConnectionManager.deleteConnection (line 301 in hbase 0.94.6 version).
So, I think a more safe UserUtils.java should implements DisposableBean interface like these:
@Component
public class UserUtils implements InitializingBean, DisposableBean {

    ............

    public void afterPropertiesSet() throws Exception {
        admin = new HBaseAdmin(config);
    }

    public void destroy() {
        try {
            admin.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    .......
}

I doubt the usefulness of <hdp:hbase-confi guration delete-connection="true" ..>.

If upgrading hbase lib to 0.94.6, and modifying UserUtils.java as above, We will get
the following ERROR information when xxxApplicationContext.close() (due to HbaseConfigurationFactoryBean.destroy()):
12:21:07.824 [Thread-2] ERROR org.apache.hadoop.hbase.client.HConnectionManager.deleteConnection:301 - Connection not found in the list, can't delete it (connection key=HConnectionKey{properties={hbase.zookeeper.property.clientPort=2181, hbase.client.pause=1000, zookeeper.znode.parent=/hbase, hbase.client.retries.number=10, hbase.zookeeper.quorum=vs1}, username='tim'}). May be the key was modified?
In HConnectionManager.deleteConnection (line 301 in hbase 0.94.6):
    public class HConnectionManager{
      ....
      private static void deleteConnection(HConnectionKey connectionKey,
          boolean staleConnection) {
        synchronized (HBASE_INSTANCES) {
          HConnectionImplementation connection = HBASE_INSTANCES
              .get(connectionKey);
          if (connection != null) {
            connection.decCount();
            if (connection.isZeroReference() || staleConnection) {
              HBASE_INSTANCES.remove(connectionKey);
              connection.internalClose();
            }
          }else {
301:        LOG.error("Connection not found in the list, can't delete it "+
              "(connection key="+connectionKey+"). May be the key was modified?");
          }
        }
      }
      ....
    }

We knows that when xxxxApplicationContext.close(), the HConnectionManager.deleteConnection() will be invoked.
As all connections will be correctlly closed if we use Spring HbaseTemplate, so BASE_INSTANCES.get(connectionKey) will
return null, then we will get this information.

Closing old issues


Add “Diffy JSON”

More info: https://www.npmjs.com/package/format-json#why

By the way, this PR took a while because I couldn’t find a node-based double of the Unix mv.
So I wrote it: https://github.com/studio-b12/mve :)

cool :+1:


[BUG] TS011F Plug kWh slow updates

Describe the bug
I have multiple tuya "TS011F" plugs, they all show "A" and "W" in real time, the issue is with kWh it is calculating the total but it takes really long to notify changes and data is not showing or takes a lot to show up on Electric dashboard, sometimes it does not update until I reboot Home Assistant, watching the changes I can't figure out any update pattern.
Expected behavior
I would expect the device to notify when there are changes in the total kWh or at least every hour.
Screenshots
All devices are the same model

Blank spaces ar due to no power arriving to the switch as power to this switch was managed from another place.

This is a nother device and it's conected all the time and consuming 140W/200W continous

As you can see "W" and "A" are getting updates constantly

Adding device Sign:
{
  "node_descriptor": "NodeDescriptor(logical_type=<LogicalType.Router: 1>, complex_descriptor_available=0, user_descriptor_available=0, reserved=0, aps_flags=0, frequency_band=<FrequencyBand.Freq2400MHz: 8>, mac_capability_flags=<MACCapabilityFlags.AllocateAddress|RxOnWhenIdle|MainsPowered|FullFunctionDevice: 142>, manufacturer_code=4098, maximum_buffer_size=82, maximum_incoming_transfer_size=82, server_mask=11264, maximum_outgoing_transfer_size=82, descriptor_capability_field=<DescriptorCapability.NONE: 0>, *allocate_address=True, *is_alternate_pan_coordinator=False, *is_coordinator=False, *is_end_device=False, *is_full_function_device=True, *is_mains_powered=True, *is_receiver_on_when_idle=True, *is_router=True, *is_security_capable=False)",
  "endpoints": {
    "1": {
      "profile_id": 260,
      "device_type": "0x010a",
      "in_clusters": [
        "0x0000",
        "0x0003",
        "0x0004",
        "0x0005",
        "0x0006",
        "0x0702",
        "0x0b04",
        "0xe000",
        "0xe001"
      ],
      "out_clusters": [
        "0x000a",
        "0x0019"
      ]
    }
  },
  "manufacturer": "_TZ3000_ew3ldmgx",
  "model": "TS011F",
  "class": "zhaquirks.tuya.ts011f_plug.Plug"
}

I have received 4  new plugs, this ones are “ _TZ3000_typdpbpg” using the same quirk “ zhaquirks.tuya.ts011f_plug.Plug” and this ones are reporting super fast, any way I can make my other plugs “ _TZ3000_ew3ldmgx” report fast?

Deleting them and adding them back to ZHA seems to improve the update interval.

After some days the switches stop reporting data (kWh)  :(
kWh (22-23/02/2022)

Ampers (22-23/02/2022)

Wats (22-23/02/2022)

As you can see there has been a consumption from 00:00 till 08:00 of 1600W continuous +o- but kWh is not updating

Any idea what is causing my devices to just stop reporting kWh? i have now 4 devices that sum the kWh but not report values back and HA is not showing data in Energy dashboard, If I reboot devices or HA it then reports but then after some times stops reporting again.


Enable ignored directories

The exclude_directory function wasn't actually being used, so I've put it to use, and allowed it to be disabled with a --no-ignore-dirs flag.

I'd like to add the ability for the user to pass additional globs to ignore in a separate PR. I might also add support for ignoring files in the user's .gitignore too at a later date.


Swimlanes automatic actions

Now that we have swimlanes, it would be nice to be able to use them in automatic actions.
External label A -> Swimlane A
Category B -> Swimlane B
User C -> Swimlane C
etc.
In case of conflicts, I guess it would be nice to be able to re-arrange automatic actions instead of having to start from scratch.

:+1:  for this, I was just thinking this yesterday :)

:+1:

Maybe it could be possible to do the other way too?
For example: When a task is dropped into a swimlane, it triggers an action (assign to user A).

I just created a pull request that allows the use of swimlane change as a trigger also includes two new actions: set colour on swimlane change and set priority on swimlane change. You can view my pull request here: https://github.com/kanboard/kanboard/pull/2587

This issue has been closed automatically for inactivity after more than 1 year. If you still need this feature, you should consider contributing to this open-source project.


Reinstate Disposal

https://github.com/jet/equinox and propulsion both depend on the following taskSeq features

disposal via use! in task expressions
logging via try/finally

This PR reinstates the functionality that accidentally got disabled in https://github.com/fsprojects/FSharp.Control.TaskSeq/commit/27486f3f1811694de0135b2760d2a1b6840bafc0

Tests pass on the desktop.
Would love to give a 0.3.1 or a 0.4.0-alpha.1 a test drive...

Thanks for testing this!!! Sorry to leave this hanging so long, I kinda/sorta wanted to get other stuff baselined as well, but this is too important and should've been fixed already.
Merging now, publishing tomorrow.

Strange, I thought I can edit this with GH CodeSpaces. While it allows me to edit, I get a 403 when trying to commit to this PR. When I do it locally though, just check out this PR and commit & push, it "just works" ™


Example

Hi, can you please advise what the passphrase is for your example?

Hi, my apologies, I forgot to include the 'private_key_passphrase' parameter in the PGPDecrypt-Message example. Also, the PGP keys in the example expired about one week ago. I created a new PGP key and used it in the examples for both PGPDecrypt-Message and PGPEncrypt-Message. I also made sure to include the 'private_key_passphrase' parameter in the PGPDecrypt-Message example. Thank you.


No wakeup from Alarm in 6.3.4

In 6.3.4 a Teensy 3.5 doesn't wakeup from Alarm. It does wakeup from Timer or e.g. falling edge on a Digital pin.
In 6.3.2 also the Alarm wakeup works properly, but with this version I don't get the right wakeup source returned.
My environment is:
Teensy 3.5 w crystal and CR2032 battery, Arduino 1.8.9, Teensyduino 1.4.7
Thanks for providing this library, time and effort to maintain it, this is not taken for granted.
H

I just updated Snooze only deepSleep and hibernate work so far you can download here, let me know if you have any problems.


fix: update user management filters for emails with special characters

Description
This PR fixes an issue where the user management filters were not working for email addresses containing special characters like + . Examples of problematic emails include:

<EMAIL_ADDRESS>

<EMAIL_ADDRESS>

App Access Management -> Add Role -> User List
App Access Management -> Add Role -> User List have same special character (+) related issue on search input.

Why

Updated the email filter logic to correctly handle special characters such as +.

Issue

Issue: #1128

Checklist

[x] I have followed the contributing guidelines
[x] I have created and linked IP issues or requested their creation by a committer
[x] I have created and linked IP issues or requested their creation by a committer
[x] I have performed a self-review of my own code
[x] I have successfully tested my changes locally
[x] I have checked that new and existing tests pass locally with my changes

Hi @manojava-gk,
As per your suggestions I have moved Search email regex into Patterns file. Can you please review it again.
Thank you!

Move regex to patterns file

Hello @manojava-gk,
Regex moved into Patterns file and I have added testcases for this newly added pattern. Can you please review it again.
Thank you!!

@manojava-gk could you please review again?

Hi @oyo, I made a changes according to your feedback. Please review it again.


fix(57590): [Formatting] Remove spaces between ... and type name in tuple spread

Fixes #57590

@microsoft-github-policy-service agree


Add BackOff when SQS Poll throws an exception

Fixes #714
Adds support for a Spring Retry BackOffPolicy to be executed when an exception is thrown by a polling thread.
Adds the configuration to ContainerOptions with a exponential default of 1000ms / 2.0 / 10000ms.

@tomazfernandes  @maciejwalkowiak how to integrate exponential retry? I found it in the interface ContainerOptionsBuilder but it seems not to be supported yet in version 3.1.1? Or is it just becoming a default behavior for SQS Listeners?
Is there an example how to use it?


Zoom limit not recalculated when container resizes

I have a page that automatically adjust SVG container size when window re-sizes. I also set the minZoom and maxZoom property for svgpanzoom.
I opened the page in a small window, when I re-size the window (e.g. maximize), the zoom limit does not gets recalculated uisng the newer, bigger container size. My artwork remain in a very small size even when fully zoomed in.

When I zoom in fully to the limit, and maximize a window from a small window...
What I expect:
Since container is bigger now, I can zoom in deeper, thus artwork can become bigger
What I see:
I cannot zoom in further.
It looks like the zoom level is restricted to the original container size, not the current size

If this sounds confusing, try to imagine if the original window/container size is 200x200, the artwork is fitted and sized to 200x200 when load. I can zoom for example 200% to 400x400 at max.
When I maximize the window/container to 1000x1000, I expect the artwork can zoom in to become 2000x2000 size, but it doesn't allow me to do so. The artwork is still fully zoomed in at 400x400 in a 1000x1000 container, I cannot zoom in futher.
This is fixed when I reload the page in maximized state. i.e., I can zoom in to 2000x2000 in maximized window with 1000x1000 container

Did you try calling .resize() on svgPanZoom instance after browser resize? There is a demo with that.
If this doesn't help then please check provide a reproducible example https://github.com/ariutta/svg-pan-zoom#support with required steps.

Hi @bumbu, I did call resize() but issue is still there.
I found that it is hard to demo the bug using jsfiddle because we need to react with window resize event. I made a gist instead: https://gist.github.com/kevinlaw91/82d9b7d0ebf00c2120ca
You can download and run in browser, then use inspect element(docked) to trigger window resize event. I also created screenshot and steps on how to reproduce the bug:
issue185.pdf

I have a similar problem.
Chrome: 48.0.2564.116 m
SvgPanZoom: 3.2.6
When I resize of the container, contents of the container does not fit, and extends beyond the boundaries.
The content is still the same size as it was before resize. I watched the zoom ratio before and after resize - _panZoom.getSizes().realZoom. And they were equal.
SvgPanZoom v3.2.3
We use this version.
Behavior to resize different from v3.2.6
When you resize the content to be fit.
But, when i call - _panZoom.zoomOut(), I'll get the content size before to resize
I'm use methods resize->fit->center when changing the size of the container.

Same issue here, any ETA on merging the fix?


[FEATURE] Add an Incident Notification Sysmtem.

Detailed description
I propose we develop an Incident Notification System that will serve different purposes such as , customizable subscriptions , educational content and maybe real-time alerts on cybersecurity incidents or found vulnerabilities.
Context
This feature could be crucial not only for educational purposes but also for helping the users interact and keep track on updates and user related content.
Possible implementation
It could leverage APIs from respected cybersecurity data sources and incorporate machine learning to categorize and prioritize alerts based on user preferences.
Additional information
No response
Code of Conduct

[X] I agree to follow this project's Code of Conduct

@kabir0x23 What do you think?

real-time alerts on cybersecurity incidents or found vulnerabilities.

u mean too use public apis for this?


Reading y with missing values

I might be doing something wrong:
output = load_afq_data(unsupervised=False,
                       dwi_metrics=["dki_fa", "dki_md", "dki_mk", "dki_awf"],
                       fn_nodes=DATA + 'hbn_tract_profiles.csv',
                       fn_subjects=DATA + 'hbn_participants.csv',
                       index_col="subject_id",
                       target_cols=["age"])

Where the "age" column in "hbn_participants.csv" contains some missing values. But, I wasn't expecting:
y = output.y
np.all(np.isnan(y))

True

Turns out this is already fixed on main :-)