Some UI bug

Describe the task

[x] Flash screen in case input contract address when import NFT, import Token

https://github.com/Koniverse/SubWallet-Mobile/assets/117999489/8dbe1b27-0df2-410b-b8d4-129dc7d0c4d8

[x] Bug when open NFT detail
Actual: show CollectionImage when loading NFT Detail Image
Expect: show only activityIndicator when loading NFT Detail Image

https://github.com/Koniverse/SubWallet-Mobile/assets/117999489/e43572e7-044e-4e62-8048-67476292517e

[x] UI bug manage staking detail

[x] UI bug Buy token screen

[x] Do not show action in case data is loading when staking
Expect: When data is loading, disable ActionButton

Version test: PR 1175 17:52 21/11/2023
Device test: Samsung S20 FE 5G
Validation passed.


Add tab and backtab navigation

mentioned in #288.
We could introduce a binding description but I think it would be better to not since it could become cluttery. As of now it will only change the main panes which works best for my workflow but let me know if you disagree.

Thanks @blennster !


interactive mode

Ran on M2 Max and got an error:
Backend MacOSX is interactive backend. Turning interactive mode on.
How to Turn on interactive mode?

Please reopen the issue with "Bug/Help" the issue form. I cannot give help since the information in your description is limited.


Printful + NFT support

In order to support NFTs on Printful stores, we'll need to:

Allow non-Printful items to be added to Printful stores
Allow inventory to be tracked on non-Printful items
Allow an NFT contract address and list of available token IDs to be added on the product edit page
Allow customers to specify a receiving wallet when NFT items are present in the checkout (on the payment page)
Initiate an NFT transfer upon customer checkout

@nick initiating the transfer is going to be a manual step for now, correct?

@nick initiating the transfer is going to be a manual step for now, correct?

We can start with a manual transfer to make things easier, yea

We can start with a manual transfer to make things easier, yea

Allow non-Printful items to be added to Printful stores

Should I create the items on printfull using API?

Allow inventory to be tracked on non-Printful items

I guess it is already allowed

Allow an NFT contract address and list of available token IDs to be added on the product edit page

Where should I save the contract address and token IDs? In the product's data.json file?

Initiate an NFT transfer upon customer checkout

Is this a contract call? Where can I find a sample NFT contract code?

Allow non-Printful items to be added to Printful stores

Should I create the items on printfull using API?

Allow inventory to be tracked on non-Printful items

I guess it is already allowed

Allow an NFT contract address and list of available token IDs to be added on the product edit page

Where should I save the contract address and token IDs? In the product's data.json file?

Initiate an NFT transfer upon customer checkout

Is this a contract call? Where can I find a sample NFT contract code?

Should I create the items on printfull using API?
Right now a store is either Printful or Non-Printful. There's no way to add a non-Printful product (eg if I wanted to list cupcakes for sale) to my existing store that has Printful products. We want non-Printful products to be ignored by any Printful related functions... eg when an order is made with both Printful and non-Printful items (eg 1 t-shirt and 1 cupcake), the calls to Printful ignore the cupcake.

Allow inventory to be tracked on non-Printful items
Right now inventory is all or nothing. We want inventory to be tracked for the cupcake, but not the t-shirts and other Printful items

Where should I save the contract address and token IDs? In the product's data.json file?

Perhaps lets revisit the NFT stuff after the above has been done. We'll probably just process NFT orders manually initially.

Should I create the items on printfull using API?
Right now a store is either Printful or Non-Printful. There's no way to add a non-Printful product (eg if I wanted to list cupcakes for sale) to my existing store that has Printful products. We want non-Printful products to be ignored by any Printful related functions... eg when an order is made with both Printful and non-Printful items (eg 1 t-shirt and 1 cupcake), the calls to Printful ignore the cupcake.

Allow inventory to be tracked on non-Printful items
Right now inventory is all or nothing. We want inventory to be tracked for the cupcake, but not the t-shirts and other Printful items

Where should I save the contract address and token IDs? In the product's data.json file?

Perhaps lets revisit the NFT stuff after the above has been done. We'll probably just process NFT orders manually initially.

Right now inventory is all or nothing. We want inventory to be tracked for the cupcake, but not the t-shirts and other Printful items

I am adding printfull products also to the inventory
https://github.com/OriginProtocol/dshop/pull/870

Right now inventory is all or nothing. We want inventory to be tracked for the cupcake, but not the t-shirts and other Printful items

I am adding printfull products also to the inventory
https://github.com/OriginProtocol/dshop/pull/870


Can some explain the dot_axes ?

I am sorry to ask such a navie question. But i am really confused with the dot_axes. Can someone explain that, Thank you so much!

it chooses the dimensions to which operate an inner product. Say you have two tensors of dimensions (4, 2, 3) and (4, 5, 3). So you want to do a matrix inner product between the 4 (2, 3) matrices with the equivalent (5, 3). You just pick dot_axes=(2, 2) to say that the product dimension is the last one.
Not a super elaborate answer but i hope it helps.


⬆ Upgrade dojo to 0.7.0

Not working for now

@ponderingdemocritus I did the upgrade and the subscriptions seem to not work.
Note: the contrats are deployed on v0.7.0-alpha.5, but I dont think it is an issue


Cannot install extension because of version mismatch in Marketplace

Testing #164452
Several extensions fail to install, e.g.:
2022-10-26 10:23:00.857 [info] Electron sandbox mode is enabled!
2022-10-26 10:23:01.601 [info] [vscode.typescript-language-features]: Command `typescript.sortImports` appears multiple times in the `commands` section.
2022-10-26 10:23:01.601 [info] [vscode.typescript-language-features]: Command `javascript.sortImports` appears multiple times in the `commands` section.
2022-10-26 10:23:01.601 [info] [vscode.typescript-language-features]: Command `typescript.removeUnusedImports` appears multiple times in the `commands` section.
2022-10-26 10:23:01.601 [info] [vscode.typescript-language-features]: Command `javascript.removeUnusedImports` appears multiple times in the `commands` section.
2022-10-26 10:23:03.881 [info] [perf] Render performance baseline is 17ms
2022-10-26 10:23:48.993 [error] Invalid: Cannot install 'nagab.todo-tree' extension because of version mismatch in Marketplace
    at $.checkAndGetCompatibleVersion (vscode-file://vscode-app/usr/share/code-insiders/resources/app/out/vs/code/electron-browser/sharedProcess/sharedProcessMain.js:87:96873)
    at async $.installFromGallery (vscode-file://vscode-app/usr/share/code-insiders/resources/app/out/vs/code/electron-browser/sharedProcess/sharedProcessMain.js:87:86770)
2022-10-26 10:23:48.995 [error] Cannot install 'nagab.todo-tree' extension because of version mismatch in Marketplace: Invalid: Cannot install 'nagab.todo-tree' extension because of version mismatch in Marketplace
    at $.checkAndGetCompatibleVersion (vscode-file://vscode-app/usr/share/code-insiders/resources/app/out/vs/code/electron-browser/sharedProcess/sharedProcessMain.js:87:96873)
    at async $.installFromGallery (vscode-file://vscode-app/usr/share/code-insiders/resources/app/out/vs/code/electron-browser/sharedProcess/sharedProcessMain.js:87:86770)

Also: Many extensions are not found when searching in the Extensions viewlet. E.g., searching for "azure" in the Extensions viewlet shows no results.
Version: 1.73.0-insider
Commit: a887d72e8de27cf9042745fb09a9b9e9f451ebc0
Date: 2022-10-26T05:25:13.711Z
Electron: 19.0.17
Chromium: 102.0.5005.167
Node.js: 16.14.2
V8: <IP_ADDRESS>-electron.0
OS: Linux arm64 5.15.0-52-generic
Sandboxed: Yes

Same with the armhf server (the above was with arm64 desktop).

This is expected since the extension is indeed incompatible.

I also ran into this. Should version compatibility be surfaced in the extension's overview page upfront?

Yeah we can, but it can be expensive as we have to get all versions of the extension.


Make ParseException unchecked

checked exceptions are yucky

This is a breaking change though, so we might want to bump to 2.0.0 (?)

This is a breaking change though, so we might want to bump to 2.0.0 (?)

Actually, I don't think it is. I'll do it rn, because checked exceptions bruh.
But the reason it was checked is because you should be expected to handle a case where the version is incorrect in the code that parses versions.


Change workflow to mamba

Change workflow to mamba. Resolves #252. Equivalent of zppy's https://github.com/E3SM-Project/zppy/pull/429 & https://github.com/E3SM-Project/zppy/pull/428

@forsyth2, I don't have permission to push to this branch.  Could you please cherry-pick the last 2 commits from the following?
https://github.com/xylar/zstash/commits/issue-252

We still want to keep everything functioning if one were to use pip (think users installing a dev version in their custom envs) and this shouldn't be hard at all to obtain while still moving the main actions to mamba. The change in setup.py may break this, but I will need to look more into it.

I think our packages basically don't and never have worked with pip.  They require dependencies only available on conda-forge.  I can't say whether that's true for zstash but it's true for everything else (zppy, MPAS-Analysis, mache, E3SM_Diags, etc.)

I think keeping the docs actions running on pip is okay; I don't see a specific reason here to switch to mamba (but correct me if I am wrong). Using pip will be much lighter on the CI anyway. However, I think Xylar's commits in https://github.com/xylar/zstash/commits/issue-252 will fix the issues and this should run on mamba if we want it to.

I'll leave this up to @tomvothecoder and @forsyth2.  To me, it seems like an undesirable practice to use pip for CI and mamba for local testing.  I also like to use the automatic API generation features in sphinx and recommend that others use that.  That requires having the package installed before making the docs, so pip is out.

Could you please cherry-pick the last 2 commits from the following?

Cherry-picked to this branch.

To me, it seems like an undesirable practice to use pip for CI and mamba for local testing.

I agree that it probably makes more sense to stick to one tool here.

Ok, we'll wait to see how https://github.com/E3SM-Project/zppy/pull/438 does

@forsyth2, as I just commented here:
https://github.com/E3SM-Project/zppy/pull/438#issuecomment-1595729911
I think we can merge this.  The approach used here worked fine in zppy.


Button hides count if trailingVisual is present

Description
Both count and trailing visual fill the same slot, so count is not shown when trailing visual is present
<Button count={2} trailingVisual={TriangleDownIcon}>Button</Button>

Version
v36.4.0
Browser
Chrome

Hi!
This is not unique to SelectPanel, this is true for Button. Both count and trailingVisual fill the same slot with preference given to trailingVisual

I can see how the API is a bit confusing 🤔
Also, trailingAction is not yet documented: https://primer.style/components/button/react

Thanks again @siddharthkp ! Much appreciated 🙌


Uploading url of file to collection

This is what I have on my file.
However, the url of the file will not get updated to the collection below.
(image itself gets updated correctly)
Am I doing something wrong?
//file:/server/init.js
Meteor.startup(function () {
  UploadServer.init({
    tmpDir: process.env.PWD + '/.uploads/tmp',
    uploadDir: process.env.PWD + '/.uploads/',
    checkCreateDirectories: true,
    getDirectory: function(fileInfo, formData) {
      if (formData && formData.directoryName != null) {
        return formData.directoryName;
      }
      return "";
    },
    getFileName: function(fileInfo, formData) {
      if (formData && formData.prefix != null) {
        return formData.prefix + '_' + fileInfo.name;
      }
      return fileInfo.name;
    },
    finished: function(fileInfo, formData) {
      if (formData && formData._id != null) {
        Meteor.users.update(this.userId, { $set: { "profile.avatar":fileInfo }});
      }
    }
  })
  Uploader.finished = function(index, file) {
    Meteor.users.update(this.userId, { $set: { "profile.avatar":file }});
  }
});

Several things, first, on server the this.userId is not defined so following will do nothing:
finished: function(fileInfo, formData) {
      if (formData && formData._id != null) {
        Meteor.users.update(this.userId, { $set: { "profile.avatar":fileInfo }});
      }
    }

You may want to pass userId as part of formData.
On client, make sure that client modifications are permitted.

Ah, I'm a really big newb and I will try to write something up. Where does fileInfo and formData come from?

{{>upload__bootstrap formData=specificFormData}}

How would I pass the userId to that specificFormData?
Template.foo.helpers({
  specificFormData : function(){
    return Meteor.userId()
  }

Would this be the correct way?

Yes, that looks close to right except for some typos and I think you need to return an object.  In closed issue #53 I put some code in there which may help with the forms data.  In your code above, you may have to put the return value in an object, something like: return { userId : Meteor . userId ( ) } ;

@foxaal Hello. Thank you for your reply. I saw your link and did not quite understand it.
//file:/server/init.js
Meteor.startup(function () {
  UploadServer.init({
    tmpDir: process.env.PWD + '/.uploads/tmp',
    uploadDir: process.env.PWD + '/.uploads/',
    checkCreateDirectories: true,
    // maxFileSize: 100000,
    getDirectory: function(fileInfo, formData) {
      if (formData && formData.directoryName != null) {
        return formData.directoryName;
      }
      return "";
    },
    getFileName: function(fileInfo, formData) {
      if (formData && formData.prefix != null) {
        return formData.prefix + '_' + fileInfo.name;
      }
      return fileInfo.name;
    },
    finished: function(fileInfo, formData) {
      if (formData && formData._id != null) {
	        Meteor.users.update({_id:formData.userId}, { $set: { "profile.avatar":fileInfo }});
      }
    }
  })
});

This is what I have on my server side.
And this is what I have on my client
Template.postsList.helpers({
	specificFormData: function(){
		return { userId: Meteor.userId() };
	}
});

the url is not being updated to the users :(

I apologize if I cannot see exactly what you are trying to do, but it seems you may need a bit of help untangling how this works.  So do I, because a lot goes on automagically. although, perhaps less magically than one may think.  For me, always best to start looking at this from the templates and work down from there.  Somewhere in the html, you have must have:
{{> upload_bootstrap formData=specificFormData ..... }}
</template>

Your helper function, specificFormData will be called when the upload_bootstrap template renders, and by this mechanism, the upload_bootstrap template will receive the return value of specificFormData, namely, an object which has a userId property.  This object gets a name at this point called formData.  The getDirectory function which you fill in for the UploadServer is called with  formData -- which, from the code you have shown here, does not contain a directoryName property (or a prefix property, or an _id property) but only a userId property.  getDirectory will tell the UploadServer the name of a sub-directory to upload to.  In this case, that name will be the value of userId property of formData.

Did you solve it? Can I close this issue?

@tomitrescak Yes I solved it! I do not understand yet fully how this package handles data but this issue has been solved. Thank you


Middle click and scroll don't seem to work

Not sure if this is a planned feature or not, but it would be nice to be able to 'autoscroll' with middle-click and scroll as you would in a normal browser window.  Right now it seems like that functionality is unavailable.

Hey @andrewrota, yes unfortunately this feature does not work as we are overriding the browser native scrolling and reimplementing it, this means we have missed off some of these platform dependent features.
@wlis is looking into ways we can take advantage of the browsers native scrolling yet maintain (or increase :P) our scroll perf, which should fix this issue and some of the other related issues.

Cool, thanks for the quick response!

We had our own solution before you announced fixed-data-table in which we had a container with overflow: auto. Inside of that container we had another one with a height set to the calculated height of all rows combined. Inside of that we had a absolutely position container with overflow hidden. Inside of that container we rendered the actualt table. The top position always reflected the scroll position of the outer container. This way all of the native scolling aspects worked as expected.
Basically:
div.scollingContainer {overflow: auto}
    div {height: <actual height of all rows>}
        div {position: absolute, overflow: hidden, height: <height of .scrollingContainer>, top: <scrollTop of .scrollingContainer>}

Thank you for reporting this issue and appreciate your patience. We've  notified the core team for an update on this issue. We're looking for a response within the next 30 days or the issue may be closed.

Any news on support for this?  I almost exclusively use the middle mouse click to scroll, so this is a rather frustrating limitation for me.


Pageserver read trace utils

List, dump, and analyze read traces. Replay not implemented yet, I'm saving it for a separate PR. It will be complicated, since it might involve simultaneous wal replay.
The analysis is very primitive but it can be used to detect issues like https://github.com/neondatabase/neon/issues/2585

Not sure why tests are failing fatal: detected dubious ownership in repository at ...

Test failure is not transient:
INFO[2164] Running: [/bin/sh -c cd compute_tools && cargo build --locked --profile release-line-debug-size-lto]
error: failed to load manifest for workspace member `/home/nonroot/trace`

Caused by:
  failed to read `/home/nonroot/trace/Cargo.toml`

Caused by:
  No such file or directory (os error 2)
error building image: error building stage: failed to execute command: waiting for process to exit: exit status 101
Error: Process completed with exit code 101.

Seems like a dockerfile problem. @SomeoneToIgnore does the problem seem obvious? (I found you by git blame)


Auth is only needed for some URLs

I discovered that no auth is required for getting city or menus. Likely only for POST calls, KITCHEN_URL and RESERVATION_URL.
I suggest we whitelist the URLs (operations) that require credential. This makes cli commands to list cities or menus (#7) simpler to test and run, since it's stateless and doesn't require requests session or unnecessary logins.

Yes, I think this means mealpal.get_schedules('San Francisco') doesn't help verify cookies anymore. Will need to check this again though.

Good point about the false confidence from get_schedules. I wonder what response would be returned if hitting /login with no user and password.
Thinking harder about this, we don't actually need auth, it's only when we call initialize_mealpal in execute_reserve_meal:
https://github.com/edmundmok/mealpy/blob/5fc5bc7a97e4dda452b26d46552c5fccf084ee00/mealpy/mealpy.py#L206-L208
So I think this issue is more about cleaning up the structure of the code so that initialize_mealpal is more like "populate existing MealPal instance with cookie information". Rather than be the starting point for all commands.
Okay, I'd say this ticket is not yet actionable and may fix itself when other features (#7) make it more obvious what work needs to be done.


Added missing keywords

K_SHORTEST_PATHS
SEARCH

Thank you for adding the keywords!
However, you have to add them to components/prism-aql.js and then run npm ci && npx gulp which will generate components/prism-aql.min.js for you.
Also, the K_SHORTEST_PATHS keyword is not mentioned here. Are there different variants of AQL?

I found it in the example section. On that note, shouldn't TO and OPTIONS also be keywords?

Correct, TO and OPTIONS are missing as well.
And there are pseudo-values OLDand NEW. Perhaps they might need a different highlighting color.
FOR u IN users
   REMOVE u IN users
   LET removed = OLD
   RETURN removed._key

I've checked the syntax documentation on the ArangoDB website and might suggest the related changes there as well.

Why did you close this?

And there are pseudo-values OLD and NEW. Perhaps they might need a different highlighting color.

Maybe constant?


Element margins do not expand flexbox container with wrap_content

Version 0.2.4 introduced a layout bug, I believe it was this commit.
A FlexboxLayout with height="wrap_content" is supposed to set its height to fit all contained elements. This does not work correctly when elements have a margin. The container height only matches the height of the element itself, without the margin, but then the element gets shrunk so that it fits into the container with the margin. This results in a part of the element being cut off by the margin, like in the following example:

The above label has a marginBottom of 6dp and it's cut off at the bottom by 6dp. The glitch goes away if we remove the margin (which it not desirable), or if we revert to 0.2.3.
Layout code for the above example (simplified):
    <com.google.android.flexbox.FlexboxLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:flexWrap="wrap"
        app:justifyContent="flex_end">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginBottom="6dp"
            android:layout_gravity="top"
            android:layout_weight="1"
            app:layout_flexBasisPercent="50%"
            app:layout_flexGrow="1"
            app:layout_flexShrink="0"/>

Sorry about that, thanks for filing it. I'll take a look.


there are no backup fn in 0.13.0

is it only in master code?

Correct, it will be released as 0.13.1.

@jberkel thank you!


Automated Package Upgrade

:tada: This PR is included in version 2.2.178 :tada:
The release is available on:

npm package (@latest dist-tag)
GitHub release

Your semantic-release bot :package::rocket:


stable-2.2: ceph-nfs role is uninstallable on Ubuntu 16.04

The ceph-nfs role is uninstallable on Ubuntu 16.04. The nfs-ganesha-fsal package has a dependency on glusterfs-common (>= 3.8.8), which is not in the default Ubuntu Xenial repositories, nor in any of the other PPAs that the tasks/installs/debian_ceph_repository.yml tasks in ceph-common enable.
To make nfs-ganesha-fsal installable, another PPA is required (ppa:gluster/glusterfs-3.8).

Wow. nfs-ganesha-fsal installed from that PPA doesn't even contain libfsalceph.so. Has anyone ever used or tested this?

OK, answering my own question here: the role installed packages from the wrong PPA. In addition, the autogenerated ganesha.conf is non-functional. I'll try to fix up a PR for this.

Unfortunately, we don't do much testing on Ubuntu, we only have a single scenario for that. However, it's weird since we haven't noticed any issues so far.
Looking forward to seeing your PR.
Thanks!

@leseb PR is #1912.

Fixed in #1912.


cudatext-gtk: 1.169.2 -> 1.170.5

Automatic update generated by nixpkgs-update tools. This update was made based on information from passthru.updateScript.
meta.description for cudatext-gtk is: "Cross-platform code editor"
meta.homepage for cudatext-gtk is: "https://cudatext.github.io/"
meta.changelog for cudatext-gtk is: "https://cudatext.github.io/history.txt"
Updates performed

Ran passthru.UpdateScript

To inspect upstream changes

Release on GitHub

Compare changes on GitHub

Impact

Checks done (click to expand)

built on NixOS
The tests defined in passthru.tests, if any, passed
found 1.170.0 with grep in /nix/store/xx6gyry8pjbkzln7s5rn2y3fynd2wdmb-cudatext-1.170.0
found 1.170.0 in filename of file in /nix/store/xx6gyry8pjbkzln7s5rn2y3fynd2wdmb-cudatext-1.170.0

Rebuild report (if merged into master) (click to expand)

3 total rebuild path(s)

3 package rebuild(s)

First fifty rebuilds by attrpath
cudatext
cudatext-gtk
cudatext-qt

Instructions to test this update (click to expand)

Either download from Cachix:
nix-store -r /nix/store/xx6gyry8pjbkzln7s5rn2y3fynd2wdmb-cudatext-1.170.0 \
  --option binary-caches 'https://cache.nixos.org/ https://nix-community.cachix.org/' \
  --option trusted-public-keys '
  nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
  cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
  '

(The Cachix cache is only trusted for this store-path realization.)
For the Cachix download to work, your user must be in the trusted-users list or you can use sudo since root is effectively trusted.
Or, build yourself:
nix-build -A cudatext-gtk https://github.com/r-ryantm/nixpkgs/archive/5d7a2427f10b8f1a184cb51b18b9ae0420a0f4aa.tar.gz

After you've downloaded or built it, look at the files and if there are any, run the binaries:
ls -la /nix/store/xx6gyry8pjbkzln7s5rn2y3fynd2wdmb-cudatext-1.170.0
ls -la /nix/store/xx6gyry8pjbkzln7s5rn2y3fynd2wdmb-cudatext-1.170.0/bin

Pre-merge build results
We have automatically built all packages that will get rebuilt due to
this change.
This gives evidence on whether the upgrade will break dependent packages.
Note sometimes packages show up as failed to build independent of the
change, simply because they are already broken on the target branch.
Result of nixpkgs-review run on x86_64-linux 1

2 packages built:

cudatext
cudatext-gtk

Maintainer pings
cc @sikmir for testing.

Automatic update generated by nixpkgs-update tools. This update was made based on information from passthru.updateScript.
meta.description for cudatext-gtk is: "Cross-platform code editor"
meta.homepage for cudatext-gtk is: "https://cudatext.github.io/"
meta.changelog for cudatext-gtk is: "https://cudatext.github.io/history.txt"
Updates performed

Ran passthru.UpdateScript

To inspect upstream changes

Release on GitHub

Compare changes on GitHub

Impact

Checks done (click to expand)

built on NixOS
The tests defined in passthru.tests, if any, passed
found 1.170.5 with grep in /nix/store/66pa62750fp2dd7vrwg96qmlvvxfcrms-cudatext-1.170.5
found 1.170.5 in filename of file in /nix/store/66pa62750fp2dd7vrwg96qmlvvxfcrms-cudatext-1.170.5

Rebuild report (if merged into master) (click to expand)

3 total rebuild path(s)

3 package rebuild(s)

First fifty rebuilds by attrpath
cudatext
cudatext-gtk
cudatext-qt

Instructions to test this update (click to expand)

Either download from Cachix:
nix-store -r /nix/store/66pa62750fp2dd7vrwg96qmlvvxfcrms-cudatext-1.170.5 \
  --option binary-caches 'https://cache.nixos.org/ https://nix-community.cachix.org/' \
  --option trusted-public-keys '
  nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
  cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY=
  '

(The Cachix cache is only trusted for this store-path realization.)
For the Cachix download to work, your user must be in the trusted-users list or you can use sudo since root is effectively trusted.
Or, build yourself:
nix-build -A cudatext-gtk https://github.com/r-ryantm/nixpkgs/archive/6ce3c5148de829358bef0f3157e561ec7fb2ddf3.tar.gz

After you've downloaded or built it, look at the files and if there are any, run the binaries:
ls -la /nix/store/66pa62750fp2dd7vrwg96qmlvvxfcrms-cudatext-1.170.5
ls -la /nix/store/66pa62750fp2dd7vrwg96qmlvvxfcrms-cudatext-1.170.5/bin

Pre-merge build results
We have automatically built all packages that will get rebuilt due to
this change.
This gives evidence on whether the upgrade will break dependent packages.
Note sometimes packages show up as failed to build independent of the
change, simply because they are already broken on the target branch.
Result of nixpkgs-review run on x86_64-linux 1

2 packages built:

cudatext
cudatext-gtk

Maintainer pings
cc @sikmir for testing.

Duplicates #189229


Unexpected padding for TextField input when first child TextSpan has a non-zero letterSpacing

Is there an existing issue for this?

[X] I have searched the existing issues
[X] I have read the guide to filing a bug

Steps to reproduce

Run the code sample (tested for Web and iOS)

Expected results
No padding after "1" is entered as a first char
Actual results
Unexpected padding appears when "1" is entered as a first char
Code sample
Code sample
import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final controller = CustomEditingController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Container(
          color: Colors.yellow,
          // Center is a layout widget. It takes a single child and positions it
          // in the middle of the parent.
          child: TextField(controller: controller),
        ),
      ),
    );
  }
}

class CustomEditingController extends TextEditingController {
  @override
  TextSpan buildTextSpan({
    required BuildContext context,
    TextStyle? style,
    required bool withComposing,
  }) {
    final List<TextSpan> spans = [];
    for (int i = 0; i < text.length; i++) {
      spans.add(
        TextSpan(
          text: text[i],
          style: TextStyle(letterSpacing: text[i] == "1" ? 20 : 0),
        ),
      );
    }

    return TextSpan(children: spans);
  }
}

Screenshots or Video

Screenshots / Video demonstration
https://github.com/flutter/flutter/assets/13086492/2b92d4c7-b88e-4490-98e2-cdf7aeaf82be

Logs
Logs
[Paste your logs here]

Flutter Doctor output
Doctor output
[✓] Flutter (Channel stable, 3.13.1, on macOS 13.5.1 22G90 darwin-arm64, locale en-ES)
• Flutter version 3.13.1 on channel stable at /Users/skaterschikov/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision e1e47221e8 (2 weeks ago), 2023-08-22 21:43:18 -0700
• Engine revision b20183e040
• Dart version 3.1.0
• DevTools version 2.25.0
[!] Android toolchain - develop for Android devices (Android SDK version 32.0.0)
• Android SDK at /Users/skaterschikov/Library/Android/sdk
✗ cmdline-tools component is missing
Run path/to/sdkmanager --install "cmdline-tools;latest"
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run flutter doctor --android-licenses to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 14E300c
• CocoaPods version 1.11.2
[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
[!] Android Studio (not installed)
• Android Studio not found; download from https://developer.android.com/studio/index.html
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
[✓] IntelliJ IDEA Ultimate Edition (version 2023.2.1)
• IntelliJ at /Applications/IntelliJ IDEA.app
• Flutter plugin version 75.1.4
• Dart plugin version 232.9559.10
[✓] Connected device (2 available)
• macOS (desktop) • macos  • darwin-arm64   • macOS 13.5.1 22G90 darwin-arm64
• Chrome (web)    • chrome • web-javascript • Google Chrome 116.0.5845.140
[✓] Network resources
• All expected network resources are available.
! Doctor found issues in 2 categories.

`style: TextStyle(letterSpacing: text[i] == "1" ? 20 : 0),'
What does this line of code do in the code?
You are giving letterspacing when 1 is entered.
Right?

Correct

Hi @skaterschikov Thanks for filing this. From the code sample, you seem to be giving a spacing of 20 when 1 is entered with:
 TextSpan(
          text: text[i],
          style: TextStyle(letterSpacing: text[i] == "1" ? 20 : 0),
        )

Can you provide more information on where the Unexpected padding is?

Hi, please see the attached video, I am showing it with cursor. It appears to the left of "1" if text input starts with it.

Hi, from my point of view, it's just the same thing for Text widget as well. Try running the following code. Why is there no space between 1 and 2?

`import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State createState() => _MyHomePageState();
}
class _MyHomePageState extends State {
final controller = CustomEditingController();
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
children: [
Container(
color: Colors.yellow,
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: TextField(controller: controller),
),
Container(
color: Colors.yellow,
child: RichText(
text: const TextSpan(children: [
TextSpan(
text: "1",
style: TextStyle(
letterSpacing: 0,
)),
TextSpan(
text: "2",
style: TextStyle(
letterSpacing: 20,
)),
TextSpan(
text: "3",
style: TextStyle(
letterSpacing: 20,
)),
TextSpan(
text: "4",
style: TextStyle(
letterSpacing: 20,
)),
]),
),
)
],
),
),
);
}
}
class CustomEditingController extends TextEditingController {
@override
TextSpan buildTextSpan({
required BuildContext context,
TextStyle? style,
required bool withComposing,
}) {
final List spans = [];
for (int i = 0; i < text.length; i++) {
spans.add(
TextSpan(
text: text[i],
style: TextStyle(letterSpacing: text[i] == "1" ? 20 : 0),
),
);
}
return TextSpan(children: spans);

}
}
`

Thanks for your patience and response @skaterschikov. Per this, https://github.com/flutter/flutter/issues/134159#issuecomment-1711318192, seeing there is no space between 1 and 2, this seems to occur only with the first and last characters in the word, I am able to reproduce this on the latest master and stable channels and labelling for more insights.
stable, master flutter doctor -v

[✓] Flutter (Channel stable, 3.13.3, on macOS 13.0 22A380 darwin-arm64, locale
    en-NG)
    • Flutter version 3.13.3 on channel stable at
      /Users/damilolaalimi/sdks/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision<PHONE_NUMBER> (4 days ago), 2023-09-06 14:32:31 -0700
    • Engine revision b8d35810e9
    • Dart version 3.1.1
    • DevTools version 2.25.0

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/damilolaalimi/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • ANDROID_HOME = /Users/damilolaalimi/Library/Android/sdk
    • Java binary at: /Applications/Android
      Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build
      17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E300c
    • CocoaPods version 1.12.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build
      17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.81.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.50.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.0 22A380 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 116.0.5845.179

[✓] Network resources
    • All expected network resources are available.

• No issues found!

[!] Flutter (Channel master, 3.14.0-14.0.pre.211, on macOS 13.0 22A380 darwin-arm64, locale en-NG)
    • Flutter version 3.14.0-14.0.pre.211 on channel master at /Users/damilolaalimi/fvm/versions/master
    ! Warning: `flutter` on your path resolves to /Users/damilolaalimi/sdks/flutter/bin/flutter, which is not inside your current Flutter SDK checkout at /Users/damilolaalimi/fvm/versions/master. Consider adding /Users/damilolaalimi/fvm/versions/master/bin to the front of your path.
    ! Warning: `dart` on your path resolves to /Users/damilolaalimi/sdks/flutter/bin/dart, which is not inside your current Flutter SDK checkout at /Users/damilolaalimi/fvm/versions/master. Consider adding /Users/damilolaalimi/fvm/versions/master/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 69f6e7d15d (3 hours ago), 2023-09-11 00:50:38 -0400
    • Engine revision 7e41b064eb
    • Dart version 3.2.0 (build 3.2.0-134.0.dev)
    • DevTools version 2.27.0
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0)
    • Android SDK at /Users/damilolaalimi/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • ANDROID_HOME = /Users/damilolaalimi/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 14E300c
    • CocoaPods version 1.12.1

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2022.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b802.4-9586694)

[✓] VS Code (version 1.81.1)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.50.0

[✓] Connected device (2 available)
    • macOS (desktop) • macos  • darwin-arm64   • macOS 13.0 22A380 darwin-arm64
    • Chrome (web)    • chrome • web-javascript • Google Chrome 116.0.5845.179

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 1 category.

cc @LongCatIsLooong from triage.

I met the same issue, unexpected space before the first character

I tried it with SkParagraph and it works as I expect it to work: no space before or after the first character, 20 spaces after each other.


Trapping Rain Water  in Python

🚀 Feature
Given an array arr[] of N non-negative integers representing the height of blocks. If the width of each block is 1, compute how much water can be trapped between the blocks during the rainy season
Have you read the Contributing Guidelines on Pull Requests?
Yes
Motivation
To contributing to GSSOC'21
Pitch
Input:
arr[] = {7,4,0,9}
Output:
10
Explanation:
Water trapped by above
block of height 4 is 3 units and above
block of height 0 is 7 units. So, the
The total unit of water trapped is 10 units.

/assign


feat: added PWA asset generation

Features

Added and ran package.json script to handle PWA asset generation and integration
Used https://github.com/elegantapp/pwa-asset-generator for PWA asset generation

CI

Excluded PWA assets from bundle size calculation

PR 1 of 2 to close https://github.com/commaai/new-connect/issues/59.
2nd PR will include caching via service worker and testing via Lighthouse GitHub Actions. Could split up caching and testing if needed, but not sure if that's worth it/makes sense.
Original, full PR: https://github.com/commaai/new-connect/pull/108

Can we gitignore the generated assets and just generate them at build-time?

Sure. I went ahead and created separate build and build:prod commands since generating pwa-assets increases total build time from 1s to 5s, and you only need to generate pwa-assets once anyways.

Sure. I went ahead and created separate build and build:prod commands since generating pwa-assets increases total build time from 1s to 5s, and you only need to generate pwa-assets once anyways.

This is not a good tradeoff. What happens if the assets get updated? How do I discover this build:prod command? It should just be part of the normal build. One case is 10x better than two cases.

Sure. I went ahead and created separate build and build:prod commands since generating pwa-assets increases total build time from 1s to 5s, and you only need to generate pwa-assets once anyways.

This is not a good tradeoff. What happens if the assets get updated? How do I discover this build:prod command? It should just be part of the normal build. One case is 10x better than two cases.

That's fair. I wasn't sure about the reasoning for .gitignoring the pwa-assets since those assets would probably rarely change anyways, and it would prevent an extra build step, so I thought we were really just optimizing for cleanliness.
Was the main motivation of .gitignoring just to keep it our assets up-to-date with the source svg?

Yes, this way they're never out of date and the SVG is the source of truth.


Change the start date of a need to be todays date

Trello 110
Used this as test data
20201216-123600-test-and-trace.xlsx
Row 7 - Natalia is used for an import with the old calculation of today + 2.days

Row 8 - Dave is used for the import where the Need start_date = today

You can also see that the source for these has changed to reflect discussion in todays meeting of the Note.name becoming National Test and Trace Outbound Welfare Call

So this means that the need/check-in no longer appears in 'Future tab' need to check if this is ok


CNV-36133: Fix linking of details and disks in vm overview page

📝 Description
After changes in configuration tab linking need to be updated
🎥 Demo

Please add a video or an image of the behavior/changes

/retest


Initialize code objects with loop over table

Hopefully helps with https://github.com/cython/cython/issues/4425.
It reduces binary object size by ~0.5% (module-dependent of course). This isn't the same as compile-time, but it's likely to be correlated in this case.
Code objects can be initialized after all other Python constants because no other literals can depend on them. Unfortunately I wasn't able to use a module-level constant global table for them because I was fighting with the module name defines. That's an improvement for the future when we've got further with module-state.

Sorry, I removed the UtilityFunctionPredeclarations section in the master branch. The struct definition needs to be moved elsewhere. I moved the string tab declaration into the module_state section, makes kind of sense there.


Add missing "before_cache".

Hi @mxl,
Thank you for your contribution! We really value the time you've taken to put this together.
Before we proceed with reviewing this pull request, please sign the Lightbend Contributors License Agreement:
http://www.lightbend.com/contribute/cla

Thank you.


Include DBT DRY RUN as a utilities plugin

All Singer definitions are stored in /_data/taps/ or /_data/targets. The minimal requirement for adding a tap or target will match the following format:
commands:
  run:
    args:
      args:
        --target ${DBT_DRY_RUN_TARGET}
        --verbose
      definition: |
        Allows you to run the plugin. Requires that you specify a profile target.
        Note - Requires you run `dbt-bigquery compile` before executing.
      executable: dbt_dry_run_invoker

definition: |
  dbt-dry-run is a meltano plugin based on the awesome tool created by the team at AutoTraderUk.
  It allows dbt-bigquery users to validate if their models will run (without encuring costs).
  It leverages bigquery's [dry-run](https://cloud.google.com/bigquery/docs/dry-run-queries) feature.

  **A note**
  This plugin is at it's most powerful (in our opinion) in CI (we use github actions). It allows us to ensure that our changes will not break production.
domain_url: https://github.com/autotraderuk/dbt-dry-run
meltano_edk: true
executable: dbt-dry-run
keywords:
- dbt
- bigquery
- testing
- continuous-integrations
label: dbt-dry-run
logo_url: /assets/logos/utilities/dbt-dry-run.png
maintenance_status: active
name: dbt-dry-dryn
namespace: dbt-dry-run
next_steps: |
  To run this plugin for the first time, simply specify you DBT_BIGQUERY_PROFILES_DIR, DBT_BIGQUERY_PROJECT_DIR and DBT_DRY_RUN_TARGET.
  You will also need to compile your dbt models using the command `dbt-bigquery compile`.

  Once this is done, simply run `dbt-dry-run:run` and watch the magic happen!
pip_url: git+https://github.com/potloc/dbt-dry-run-ext
edk_repo: https://github.com/potloc/dbt-dry-run-ext
repo: https://github.com/autotraderuk/dbt-dry-run
settings:
  - name: project-dir
    kind: string
    value: ${MELTANO_PROJECT_ROOT}/transform/
    env: DBT_PROJECT_DIR
    description: Location of the directory hosting your `dbt_project.yml` file.
  - name: profiles-dir
    kind: string
    value: ${MELTANO_PROJECT_ROOT}/transform/profiles/bigquery/
    env: DBT_PROFILES_DIR
    description: Location of the directory hosting your `profiles.yml` file.
  - name: target
    kind: string
    description: Target profile in DBT.
variant: potloc

Checklist

[ ] Add/update the file in the appropriate folder (/taps or /targets). The name of the file should match the name of the tap. If there is already one, add a descriptor to the name such as -search.
[ ] Add/update the PNG logo image in /assets/logos/<taps or targets>. The image name must match the YAML file name.
[ ] Tag @tayloramurphy or @pnadolny13 to flag it for review. Or post to the #hub channel on Meltano slack.

Reviewer Checklist

[ ] Validate file against JSON Schema. https://www.jsonschema.net/home is an option.
[ ] Build website locally and validate everything works.

@SBurwash thanks for the PR! To fix the CI tests you'll need to remove entity_url and meltano_edk. The string meltano_edk can go in the keywords list to indicate that its EDK based. Also if you run the linter command in https://github.com/meltano/hub/blob/main/CONTRIBUTING.md#linters you it will attempt to fix your yaml to match our rules.

@SBurwash in addition to the other suggestions, what do you think of having the image be the dbt logo with the words "Dry Run" over it? Or even the BQ logo as well? I don't think just the checkmark would look good on the Hub currently.

@SBurwash in addition to the other suggestions, what do you think of having the image be the dbt logo with the words "Dry Run" over it? Or even the BQ logo as well? I don't think just the checkmark would look good on the Hub currently.

@tayloramurphy I'm super happy with that! I didn't like my logo to begin with, I just have no talent at designing logos

@pnadolny13 I'm having some issues with my python version for the linter. Is this new version acceptable? I'm not sure what's bad order and what's improper values in the linter tests :sweat_smile:

@pnadolny13 I'm having some issues with my python version for the linter. Is this new version acceptable? I'm not sure what's bad order and what's improper values in the linter tests 😅

@SBurwash we have an open issue around either disabling or making the linting step easier. I'd say once you have your new logo updated we can force merge this and I'll update the linting separately.
@tayloramurphy does that work?

@pnadolny13 works for me!

Tangental, but sharing here because it may be relevant to folks on this thread:
I've logged a discussion in dbt-core around dry-run features in general - as discussed today in office hours. Feel free to watch/upvote/comment if interesting:

https://github.com/dbt-labs/dbt-core/discussions/6989
https://github.com/autotraderuk/dbt-dry-run/issues/33

@SBurwash I almost forgot  - you should use the repo maintainer as the variant name and set it in the default_variants.yml. Like dbt-dry-run: autotraderuk. Like AJ mentioned your yaml definition should also be labeled after this variant name .../utilities/dbt-dry-run/autotraderuk.yml.

@pnadolny13 @aaronsteers thanks for the feedback! All requested changes should have been applied, please let me know if you would like me to do anything else!

:rocket:


remote-ssh connect error: "version mismatch"

Does this issue occur when all extensions are disabled?: No

VS Code Version:
Version: 1.68.0 (user setup)
Commit: 4af164ea3a06f701fe3e89a2bcbb421d2026b68f
Date: 2022-06-08T11:44:16.822Z
Electron: 17.4.7
Chromium: 98.0.4758.141
Node.js: 16.13.0
V8: <IP_ADDRESS>-electron.0
OS: Windows_NT x64 10.0.19044

Extensions: Remote-SSH

OS Version: Windows 10 21H2

Steps to Reproduce:

Simply connect to host. And it automatically downloads [4af164ea3a06f701fe3e89a2bcbb421d2026b68f] code-server.
Shows "version mismatch" error.

When I click [Open is browser], it cames up:

May be it's a version number update mistake ?

When you say code-server are you using this code-server? https://github.com/coder/code-server This is not officially supported

No. The [code-server] is automatically download by remote-ssh  plugin.
The download url is [https://update.code.visualstudio.com/commit:8dfae7a5cd50421d10cd99cb873990460525a898/server-linux-x64/stable].

Not sure how this happened, it looks like we are forwarding the server from the previous vscode version. Can you share the Remote-SSH output channel log? But updating to 1.68.1 might fix it for you. Running "Kill VS Code server on host" would also kill it

Not sure how this happened, it looks like we are forwarding the server from the previous vscode version. Can you share the Remote-SSH output channel log? But updating to 1.68.1 might fix it for you. Running "Kill VS Code server on host" would also fix it

Sorry, I want to continue my work, so I have downgraded my vscode to 1.67 and it works fine.
I don't have ver1.68 any more, so  I can't take the ver1.68 's remote-ssh log.
But when I upgrade to  ver1.68.1, it works fine.

That's ok - if it happens again, please share the log, thanks.


kubeadm: Add a tab 'Without a package manager'  in upgrade docs

Fix 34829

This PR is a duplicate of PR #35012. If you create a duplicate pull request, we recommend that you close one of the PRs. Thank you.
/close


TFGrid by Design: Deployment Architectures and Solution Categories

Following a TF meeting where Kristof talked about the need for more information on how to build, by design, reliable and redundant solutions on the TFGrid, here is a text to constitute the introdution to a new section of the tf manual that will cover best practices when it comes to building on the TFGrid.
This text offers a brief overview of:

compute units
storage units
network units

As well as the 3 types of solutions on tfgrid (diy workload, independant and tf commercial offerings)
We also go through some of the main components of the TFGrid.
The goal is to offer sysadmins enough information for them to build reliable and resilient solutions.

@AhmedHanafy725 @ashraffouda @mohamedamer453 @xmonader @ramezsaeed @A-Harby
Hi guys! Just a reminder if you could have a look at this PR.
There is no rush per se, but I know there's a lot going on so I ping you here for the current PRs.
Thanks!


HOTFIX: logic in QuerybaleStateIntegrationTest.shouldBeAbleToQueryState incorrect

The logic in verifyCanGetByKey was incorrect. It was
windowState.size() < keys.length &&
countState.size() < keys.length &&
System.currentTimeMillis() < timeout

but should be:
(windowState.size() < keys.length || countState.size() < keys.length) && System.currentTimeMillis() < timeout

@enothereska @guozhangwang @mjsax - the test has been failing occasionally in the build.

Good catch, LGTM.

The test failure in the jenkins build will be fixed by: https://github.com/apache/kafka/pull/1845

LGTM. Merged to trunk.


EC-637 In page nav added section now working with SSR

https://nicedigital.atlassian.net/browse/EC-637

This is ready to merge once tested


fromNow reports wrong duration

Running this in electron/chromium:
moment().startOf('day').add(27, 'days').fromNow(true) // a month
moment().startOf('day').add(26, 'days').fromNow(true) // 25 days

Really do not understand how's adding 27 days to "March, 6" makes it "a month". Less than a month, precisely 27 days from now on.
Something is fishy in there.

This is configurable: http://momentjs.com/docs/#/customization/relative-time-threshold/

Thanks @maggiepint

Running this in electron/chromium:
moment().startOf('day').add(27, 'days').fromNow(true) // a month
moment().startOf('day').add(26, 'days').fromNow(true) // 25 days

Really do not understand how's adding 27 days to "March, 6" makes it "a month". Less than a month, precisely 27 days from now on.
Something is fishy in there.

Did you manage to do it? Because I am not being able to do it using relativeTimeThreshold. In mi case I want a month ago if I have more 45 days instead of two months ago


Bancatransilvania - The location of all jobs is missing

ENVIROMENT: production
URL: https://scrapers.peviitor.ro/src/bancatransilvania/index.html
Browser: Chrome
Device: laptop
OS: Windows 10
STEPS TO REPRODUCE:

Open URL in browser
Click on 'Run Scraper' button
3)Check the location of any job

EXPECTED RESULTS:
All jobs have the job location displayed
ACTUAL RESULTS:
The location of the jobs is not displayed

Fixed!

After retesting the location of the jobs is visible. Fixed.


Add webhook methods

Adds webhook methods to abstract and to base.

Accidentally deleted a previous pull request.
Let me know if any changes are needed, I don't mind doing it myself.
I am new to the process of writing documentation but would like to learn.

I agree with separating out metadata from the ApiAbstract class into its own module, aside from maybe a single helper method for constructing a URL and calling an endpoint w/ the appropriate headers. The metadata APIs have quite a bit to them, and it's arguably clutter to put them all in the same namespace where developers are interacting with the contents of the base itself.


General feedback

Hi,
first of all, very nice little tool! I've been playing around with it and it seems to do one thing and do it reasonably well. I still have a few remarks:

It works very well in firefox, feel free to update the readme accordingly :)
there seems to be some kind of go-routine leak. When I first start srvfb, the CPU utilization is 0. This jumps to around 50% once an http client connects. When the screen isn't updating, the utilization drops down to around 20% and stays there, even if the client closes the connection. Opening a new connection has the CPU utilization spike to 60% and then drop down to between 30 and 40% after the client closes etc. Only after a certain timeout, the cpu utilization drops back down to 0. (After the log reports writes to broken pipes.)
some frames are still sent redundant. Here is how I know: In firefox, when accessing /video directly, I can watch individual frames being rendered. The last frame following some screen change is always rendered and transmitted twice.

Thanks for the feedback :)
It is to be expected that there is some background CPU usage even if the screen doesn't update. The reason is that as of now, we poll the screen content ever 500ms to see if it has changed. There are some ideas how to change that, but I'm not sure it's possible to do it reliably without polling. For example, we could listen for input-events - but then, if the screen ever updates without input (there are some obvious cases, like going to sleep, or the wifi-settings screen), it wouldn't be detected. I haven't yet found an API to get notified by actual changes to the framebuffer itself.
Similarly, we only know that a client became unavailable, by trying to send a frame to it - I think. I will have to check this, it's possible that the http server cancels the context in that case?
The duplicate frame, again, is to be expected, unfortunately. See this comment. If you have any idea why this is happening on chrome or how to fix it, I'd be happy to consider changing that :)
I will have a closer look at all of this when I have some time - probably this weekend (I'm travelling right now and am a bit busy with moving). But it might just be infeasible to fix any of this right now.

Since you mentioned looking for an API to be notified of changes to the framebuffer, you may be interested in the result of some investigation I did recently on that topic. This isn't possible in general, since the linux framebuffer interface doesn't have any damage-tracking capability, but the fact that the reMarkable uses an e-ink screen, where the controller needs to be explicitly notified when to update the screen, means that the information is actually available---in the ioctls on the framebuffer device that notify it to update. There isn't a standard way of getting that information in userspace, but I wrote https://github.com/peter-sa/mxc_epdc_fb_damage to allow access to it. (as a reference application, https://github.com/peter-sa/rM-vnc-server uses this information for efficient screen streaming over RFB/VNC).


Revert "Ensure that the toolbox user runs with 'wheel' as an ..."

The --group-add option only affects the entry point of the toolbox
container.
This reverts commit 4bda42d4146f3d3baa8003428d1c0fa4b71239bd.

After a bit of testing, I realized that podman create --group-add doesn't only affect the entry point of the container. It also affects podman exec. So, if we just drop the option then we lose the wheel group membership.
With master:
⬢[rishi@toolbox ~]$ id
uid=1000(rishi) gid=1000(rishi) groups=1000(rishi),10(wheel)

With this PR:
⬢[rishi@toolbox ~]$ id
uid=1000(rishi) gid=1000(rishi) groups=1000(rishi)

So this change is wrong.
The more correct thing to do would be to move the --group-add to the relevant podman exec calls. Right now, the entry point process, which runs as root:root, also belongs to the wheel group, which is unnecessary. However, that's currently not possible because podman exec doesn't have any such option, even though the underlying runc exec command does have a --additional-gids option. However, that's something to be done in a different PR.


adding a getApi function on contest_judging_sys.js

the getApi function runs an AJEX GET request.
params- apiUrl string, complete function

This is actually a really good idea! I'll merge your Git repo into mine as soon as possible.


createGlobalStyle typing error: TemplateStringsArray

System:

OS: macOS 13.0
CPU: (10) arm64 Apple M1 Pro
Memory: 281.03 MB / 32.00 GB
Shell: 5.8.1 - /bin/zsh

Binaries:

Node: 16.15.0 - ~/Library/Caches/fnm_multishells/48343_1670904342698/bin/node
npm: 8.5.5 - ~/Library/Caches/fnm_multishells/48343_1670904342698/bin/npm

npmPackages:

styled-components: ^6.0.0-rc.6 => 6.0.0-rc.6

Environment

npx envinfo --system --binaries --npmPackages styled-components,babel-plugin-styled-components --markdown
Reproduction

https://codesandbox.io/p/sandbox/pedantic-einstein-g6n337
I wanted to create a globa stylen using createGlobalStyle but it returns this type error:
Type '{}' is missing the following properties from type 'TemplateStringsArray': raw, length, concat, join, and 23 more.ts(2740)

Steps to reproduce

create any global style using createGlobalStyle
apply it to a component.
global style will show a type error.

Expected Behavior
Global style is applied with no type errors.
Actual Behavior
Global style is applied with a type error for the Global style.

Experiencing this also with latest RC

Having the same issue.

Closing this. The newly released stable 6.0.0 have fixed this issue. 😀


[Slideover] Unmount component on close

Description
As we can see bellow on the demonstration that i've create, we can see the counter inside the slideover never reset. There is a way to "unmount" the component and reset the states?
https://stackblitz.com/edit/nuxt-ui-bfd4fm?file=app.vue
Additional context
No response

This should have been fixed in https://github.com/nuxt/ui/pull/1624, it is just not released yet. You can use the Edge channel in the meanwhile if you cannot wait.

There is a date for the release?

Could be in a few days, I know quite some things have been fixed recently


Ability to stop looping at the end of a file

feature request
Howdy! I have a 3 second sound clip and I would like the user to be able to listen to it play a couple of times, then hit a button to have it stop. Ideally, I would like it to finish the current loop before coming to a stop.
I'd be able to do something like this:
sound.play(options{loop: true})
// wait for button input
sound.looping = false
// the current time finishes playing, then it stops at the end of the file.

Do you have any suggestions on how I might be able to do this with the current code base?
(Also, thanks so much, this is a really incredible library. It has enabled me to distribute a ton of super expressive composition tools to many listeners and performers)

sure


Error when I try to gatsby develop new designcodeweb https://github.com/mengto/gatsby-starter-designcode

I don't understand why I can't. When I try it this appear. I try to nom install to fix it but anything. However I can create without using the GitHub url so I think it's not about me.

Hello @Assadinho, I had the same issue and was able to fix it by deleting the package-lock.json and running the npm install, I'm using NodeJS version 16.13.0.
Hope it helps! 🙂

I tried but it still doesn't work :( and any reply of design code since 3 weeks ...

I was able to fix this by following the instructions here. The issue seems to be with the Gatsby dependency vips not being compatible with M1 Apple Silicon.
Also worth noting, I had issues using the latest Node version, but switching to 16 fixed it.

Hello @Assadinho, I had the same issue and was able to fix it by deleting the package-lock.json file and running npm install, I'm using NodeJS version 16.13.0.
Hope it helps! 🙂

It's work with the Intel Macbook. Thanks for sharing your solution 🙏🏻

Start with a fresh npm init gatsby, follow the prompts to call your site Gatsby Default Starter, name your folder gatsby-starter-designcode, select Typescript, CMS No (add later), install styled components, other plugins do not install , proceed with Yes and you should be good to follow along with MengTo from there.

Try starting again with npm init gatsby and incorporating Mento's changes 1 by 1 from scratch. You can see his changes in the GitHub code repo changelog. Example.


Add Runner, Task, Schedule, and their specs

Codecov Report

Merging #6 (d19dd5e) into master (4e9fe67) will decrease coverage by 8.04%.
The diff coverage is 59.72%.

@@            Coverage Diff             @@
##           master       #6      +/-   ##
==========================================
- Coverage   70.00%   61.95%   -8.05%
==========================================
  Files           2        5       +3
  Lines          20       92      +72
==========================================
+ Hits           14       57      +43
- Misses          6       35      +29

Impacted Files
Coverage Δ

lib/schedjewel/runner.rb
50.00% <50.00%> (ø)

lib/schedjewel/task.rb
56.00% <56.00%> (ø)

lib/schedjewel/schedule.rb
62.50% <62.50%> (ø)

lib/schedjewel.rb
93.75% <100.00%> (+4.86%)
:arrow_up:

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.


Add the "Live" category

This adds the "Live" category to all entries.
All categories in xmltv data are applied to Airings in Channels as tags. Tags are used extensively by Channels with Smart Rules and other presentation.
This gets the ESPlus airings working a little better inside Channels.

Closing in lieu of #14


Removes compiler warnings about converting a string constants

I made several changes to remove compiler warnings, and to fix external builds using the cmake Release configuration. I had to build the example against my own changed branch through CPM before rolling the CPM back to point at this repository.
The passing build can be seen here though:
https://github.com/ddrake-mitre/geodetic_library/actions/runs/6830537798/job/18578626110
Once this branch is merged, the CPM.cmake example can be updated.

Running regression tests internally against this build passes.


i2s audio examples

Adding i2s audio examples for Cosmic, Galactic and Stellar Unicorn.

Nice work, if we can bash the rough edges off then WavPlayer or "audio.py" can be baked into the MicroPython builds to avoid needing to haul it around with the examples.
There are some gotchas outstanding though -
These examples really like to explode with a burst of random-memory-played-as-audio when I hit "Stop" in Thonny. I can't seem to figure out how to fix that.
Also the POP sound when an audio file stops playing shouldn't happen, afaik, the transition to "silence" should be pretty much instant, and appending silence to a wav file causes it to...  not pop, as you might expect.
I tried heavily modifying audio.py to remove the silence buffer and use the playback buffer instead, queuing up the wav file and appending silence if there's a buffer underrun-
# SPDX-FileCopyrightText: 2023 Christopher Parrott for Pimoroni Ltd
#
# SPDX-License-Identifier: MIT

import os
import math
import struct
from machine import I2S, Pin

"""
A class for playing Wav files out of an I2S audio amp. It can also play pure tones.
This code is based heavily on the work of Mike Teachman, at:
https://github.com/miketeachman/micropython-i2s-examples/blob/master/examples/wavplayer.py
"""

class WavPlayer:
    # Internal states
    PLAY = 0
    PAUSE = 1
    FLUSH = 2
    STOP = 3
    NONE = 4

    MODE_WAV = 0
    MODE_TONE = 1

    # Default buffer length
    WAV_BUFFER_LENGTH = 10000
    INTERNAL_BUFFER_LENGTH = 10000

    TONE_SAMPLE_RATE = 44_100
    TONE_BITS_PER_SAMPLE = 16
    TONE_FULL_WAVES = 2

    def __init__(self, id, sck_pin, ws_pin, sd_pin, amp_enable=None, ibuf_len=INTERNAL_BUFFER_LENGTH, root="/"):
        self.__id = id
        self.__sck_pin = sck_pin
        self.__ws_pin = ws_pin
        self.__sd_pin = sd_pin
        self.__ibuf_len = ibuf_len
        self.__enable = None

        if amp_enable is not None:
            self.__enable = Pin(amp_enable, Pin.OUT)

        # Set the directory to search for files in
        self.set_root(root)

        self.__state = WavPlayer.NONE
        self.__mode = WavPlayer.MODE_WAV
        self.__wav_file = None
        self.__loop_wav = False
        self.__first_sample_offset = None
        self.__flush_count = 0
        self.__audio_out = None

        # Allocate a larger array for WAV audio samples, using a memoryview for more efficient access
        self.__wav_samples_mv = memoryview(bytearray(self.WAV_BUFFER_LENGTH))

        # Reserve a variable for audio samples used for tones
        self.__tone_samples = None
        self.__queued_samples = None

    def set_root(self, root):
        self.__root = root.rstrip("/") + "/"

    def play_wav(self, wav_file, loop=False):
        if os.listdir(self.__root).count(wav_file) == 0:
            raise ValueError(f"'{wav_file}' not found")

        self.__stop_i2s()                                       # Stop any active playback and terminate the I2S instance

        self.__wav_file = open(self.__root + wav_file, "rb")    # Open the chosen WAV file in read-only, binary mode
        self.__loop_wav = loop                                  # Record if the user wants the file to loop

        # Parse the WAV file, returning the necessary parameters to initialise I2S communication
        format, sample_rate, bits_per_sample, self.__first_sample_offset = WavPlayer.__parse_wav(self.__wav_file)

        self.__wav_file.seek(self.__first_sample_offset)        # Advance to first byte of sample data

        self.__start_i2s(bits=bits_per_sample,
                         format=format,
                         rate=sample_rate,
                         state=WavPlayer.PLAY,
                         mode=WavPlayer.MODE_WAV)

    def play_tone(self, frequency, amplitude):
        if frequency < 20.0 or frequency > 20_000:
            raise ValueError("frequency out of range. Expected between 20Hz and 20KHz")

        if amplitude < 0.0 or amplitude > 1.0:
            raise ValueError("amplitude out of range. Expected 0.0 to 1.0")

        # Create a buffer containing the pure tone samples
        samples_per_cycle = self.TONE_SAMPLE_RATE // frequency
        sample_size_in_bytes = self.TONE_BITS_PER_SAMPLE // 8
        samples = bytearray(self.TONE_FULL_WAVES * samples_per_cycle * sample_size_in_bytes)
        range = pow(2, self.TONE_BITS_PER_SAMPLE) // 2

        format = "<h" if self.TONE_BITS_PER_SAMPLE == 16 else "<l"

        # Populate the buffer with multiple cycles to avoid it completing too quickly and causing drop outs
        for i in range(samples_per_cycle * self.TONE_FULL_WAVES):
            sample = int((range - 1) * (math.sin(2 * math.pi * i / samples_per_cycle)) * amplitude)
            struct.pack_into(format, samples, i * sample_size_in_bytes, sample)

        # Are we not already playing tones?
        if not (self.__mode == WavPlayer.MODE_TONE and (self.__state == WavPlayer.PLAY or self.__state == WavPlayer.PAUSE)):
            self.__stop_i2s()                                       # Stop any active playback and terminate the I2S instance
            self.__tone_samples = samples
            self.__start_i2s(bits=self.TONE_BITS_PER_SAMPLE,
                             format=I2S.MONO,
                             rate=self.TONE_SAMPLE_RATE,
                             state=WavPlayer.PLAY,
                             mode=WavPlayer.MODE_TONE)
        else:
            self.__queued_samples = samples
            self.__state = WavPlayer.PLAY

    def pause(self):
        if self.__state == WavPlayer.PLAY:
            self.__state = WavPlayer.PAUSE          # Enter the pause state on the next callback

    def resume(self):
        if self.__state == WavPlayer.PAUSE:
            self.__state = WavPlayer.PLAY           # Enter the play state on the next callback

    def stop(self):
        if self.__state == WavPlayer.PLAY or self.__state == WavPlayer.PAUSE:
            if self.__mode == WavPlayer.MODE_WAV:
                self.__wav_file.close()
            else:
                self.__state = WavPlayer.STOP

    def is_playing(self):
        return self.__state != WavPlayer.NONE and self.__state != WavPlayer.STOP

    def is_paused(self):
        return self.__state == WavPlayer.PAUSE

    def __start_i2s(self, bits=16, format=I2S.MONO, rate=44_100, state=STOP, mode=MODE_WAV):
        import gc
        gc.collect()
        self.__audio_out = I2S(
            self.__id,
            sck=self.__sck_pin,
            ws=self.__ws_pin,
            sd=self.__sd_pin,
            mode=I2S.TX,
            bits=bits,
            format=format,
            rate=rate,
            ibuf=self.__ibuf_len,
        )

        print(f"Bits per sample: {bits}, format: {format}, rate: {rate}")

        self.__state = state
        self.__mode = mode
        self.__audio_out.irq(self.__i2s_callback)

        self.__silence()

        if self.__enable is not None:
            self.__enable.on()

    def __stop_i2s(self):
        self.stop()                     # Stop any active playback
        while self.is_playing():        # and wait for it to complete
            pass

        if self.__enable is not None:
            self.__enable.off()

        if self.__audio_out is not None:
            self.__audio_out.deinit()   # Deinit any active I2S comms

        self.__state == WavPlayer.NONE  # Return to the none state

    def __silence(self):
        # Generate silence, we probably just want to do this once
        for n in range(1024):
            self.__wav_samples_mv[n] = 0
        self.__audio_out.write(self.__wav_samples_mv[:1024])                  # Play silence

    def __i2s_callback(self, arg):
        # PLAY
        if self.__state == WavPlayer.PLAY:
            if self.__mode == WavPlayer.MODE_WAV:
                try:
                    num_read = self.__wav_file.readinto(self.__wav_samples_mv)      # Read the next section of the WAV file
                except ValueError:
                    self.__state = WavPlayer.STOP
                    self.__silence()
                    return

                # End of file, be it 0 or < target buffer
                # Or possibly a wav file with fewer samples than the output buffer size
                if num_read < self.__ibuf_len:
                    # If we're looping, seek to the start of the file and append the
                    # samples into the playback buffer-
                    if self.__loop_wav:
                        _ = self.__wav_file.seek(self.__first_sample_offset)    # Play again, so advance to first byte of sample data
                        self.__wav_file.readinto(self.__wav_samples_mv[num_read:])
                        self.__audio_out.write(self.__wav_samples_mv)
                        return

                    # ^ Early return for looped layback
                    # v Fill full buffer for single-shot playback

                    extra_bytes_needed = self.__ibuf_len - num_read
                    for n in range(extra_bytes_needed):
                        self.__wav_samples_mv[num_read + n] = 0
                    self.__audio_out.write(self.__wav_samples_mv)
                    self.__wav_file.close()                                 # Stop playing, so close the file
                    self.__state = WavPlayer.STOP                           # and enter the flush state on the next callback                              # Read 0 bytes, so we're clean off the end of the wav buffer

                else:
                    self.__audio_out.write(self.__wav_samples_mv)           # Write out our full buffer

            else:
                if self.__queued_samples is not None:
                    self.__tone_samples = self.__queued_samples
                    self.__queued_samples = None
                self.__audio_out.write(self.__tone_samples)

        # PAUSE or STOP
        elif self.__state == WavPlayer.PAUSE or self.__state == WavPlayer.STOP:
            self.__silence()

        # NONE
        elif self.__state == WavPlayer.NONE:
            pass

    @staticmethod
    def __parse_wav(wav_file):
        chunk_ID = wav_file.read(4)
        if chunk_ID != b"RIFF":
            raise ValueError("WAV chunk ID invalid")
        _ = wav_file.read(4)                            # chunk_size
        format = wav_file.read(4)
        if format != b"WAVE":
            raise ValueError("WAV format invalid")
        sub_chunk1_ID = wav_file.read(4)
        if sub_chunk1_ID != b"fmt ":
            raise ValueError("WAV sub chunk 1 ID invalid")
        _ = wav_file.read(4)                            # sub_chunk1_size
        _ = struct.unpack("<H", wav_file.read(2))[0]    # audio_format
        num_channels = struct.unpack("<H", wav_file.read(2))[0]

        if num_channels == 1:
            format = I2S.MONO
        else:
            format = I2S.STEREO

        sample_rate = struct.unpack("<I", wav_file.read(4))[0]
        # if sample_rate != 44_100 and sample_rate != 48_000:
        #    raise ValueError(f"WAV sample rate of {sample_rate} invalid. Only 44.1KHz or 48KHz audio are supported")

        _ = struct.unpack("<I", wav_file.read(4))[0]    # byte_rate
        _ = struct.unpack("<H", wav_file.read(2))[0]    # block_align
        bits_per_sample = struct.unpack("<H", wav_file.read(2))[0]

        # usually the sub chunk2 ID ("data") comes next, but
        # some online MP3->WAV converters add
        # binary data before "data".  So, read a fairly large
        # block of bytes and search for "data".

        binary_block = wav_file.read(200)
        offset = binary_block.find(b"data")
        if offset == -1:
            raise ValueError("WAV sub chunk 2 ID not found")

        return (format, sample_rate, bits_per_sample, 44 + offset)

    def __del__(self):
        if self.__enable is not None:
            self.__enable.off()

        if self.__audio_out is not None:
            self.__audio_out.deinit()   # Deinit any active I2S comms

This, however, does not fix the pop. And there's even a pop between loops if I try looped playback.
That's particularly surprising, since appending silence to the existing playback buffer should not be any different to that silence coming from the wav file in the first place...
Intuitively I would expect this problem to be a signedness mismatch between the silence and the audio file, but that does not seem to be the case. Appending silence to the audio works just fine and then inspecting that silence in a hex editor reveals the string of zeros it should be (though notably if you have 32bit float selected in Audacity you'll actually get a low amplitude, high frequency noise pattern due to quantisation error or something when exporting to s16.)
Finally just to be super, super weird I'm pretty just the first playback of doorbell.wav is normal speed, and subsequent playbacks are slightly sped up. Wut?

Okay, after a shower epiphany I think I've discovered the source of the pop. See if you can spot it... 😆

Bit of hex editing the data length to confirm my suspicion-

Here's how a Wav handling class might look if it kept track of bytes remaining and skipped over the metadata at the end-
# SPDX-FileCopyrightText: 2023 Christopher Parrott for Pimoroni Ltd
#
# SPDX-License-Identifier: MIT

import os
import math
import struct
from machine import I2S, Pin

"""
A class for playing Wav files out of an I2S audio amp. It can also play pure tones.
This code is based heavily on the work of Mike Teachman, at:
https://github.com/miketeachman/micropython-i2s-examples/blob/master/examples/wavplayer.py
"""

class WavPlayer:
    # Internal states
    PLAY = 0
    PAUSE = 1
    FLUSH = 2
    STOP = 3
    NONE = 4

    MODE_WAV = 0
    MODE_TONE = 1

    # Default buffer length
    WAV_BUFFER_LENGTH = 10000
    INTERNAL_BUFFER_LENGTH = 10000

    TONE_SAMPLE_RATE = 44_100
    TONE_BITS_PER_SAMPLE = 16
    TONE_FULL_WAVES = 2

    def __init__(self, id, sck_pin, ws_pin, sd_pin, amp_enable=None, ibuf_len=INTERNAL_BUFFER_LENGTH, root="/"):
        self.__id = id
        self.__sck_pin = sck_pin
        self.__ws_pin = ws_pin
        self.__sd_pin = sd_pin
        self.__ibuf_len = ibuf_len
        self.__enable = None

        if amp_enable is not None:
            self.__enable = Pin(amp_enable, Pin.OUT)

        # Set the directory to search for files in
        self.set_root(root)

        self.__state = WavPlayer.NONE
        self.__mode = WavPlayer.MODE_WAV
        self.__wav_file = None
        self.__loop_wav = False
        self.__first_sample_offset = None
        self.__flush_count = 0
        self.__audio_out = None

        # Allocate a larger array for WAV audio samples, using a memoryview for more efficient access
        self.__wav_samples_mv = memoryview(bytearray(self.WAV_BUFFER_LENGTH))

        # Reserve a variable for audio samples used for tones
        self.__tone_samples = None
        self.__queued_samples = None

    def set_root(self, root):
        self.__root = root.rstrip("/") + "/"

    def play_wav(self, wav_file, loop=False):
        if os.listdir(self.__root).count(wav_file) == 0:
            raise ValueError(f"'{wav_file}' not found")

        self.__stop_i2s()                                       # Stop any active playback and terminate the I2S instance

        self.__wav_file = open(self.__root + wav_file, "rb")    # Open the chosen WAV file in read-only, binary mode
        self.__loop_wav = loop                                  # Record if the user wants the file to loop

        # Parse the WAV file, returning the necessary parameters to initialise I2S communication
        format, sample_rate, bits_per_sample, self.__first_sample_offset = WavPlayer.__parse_wav(self.__wav_file)

        self.__wav_file.seek(self.__first_sample_offset)        # Advance to first byte of sample data

        self.__start_i2s(bits=bits_per_sample,
                         format=format,
                         rate=sample_rate,
                         state=WavPlayer.PLAY,
                         mode=WavPlayer.MODE_WAV)

    def play_tone(self, frequency, amplitude):
        if frequency < 20.0 or frequency > 20_000:
            raise ValueError("frequency out of range. Expected between 20Hz and 20KHz")

        if amplitude < 0.0 or amplitude > 1.0:
            raise ValueError("amplitude out of range. Expected 0.0 to 1.0")

        # Create a buffer containing the pure tone samples
        samples_per_cycle = self.TONE_SAMPLE_RATE // frequency
        sample_size_in_bytes = self.TONE_BITS_PER_SAMPLE // 8
        samples = bytearray(self.TONE_FULL_WAVES * samples_per_cycle * sample_size_in_bytes)
        range = pow(2, self.TONE_BITS_PER_SAMPLE) // 2

        format = "<h" if self.TONE_BITS_PER_SAMPLE == 16 else "<l"

        # Populate the buffer with multiple cycles to avoid it completing too quickly and causing drop outs
        for i in range(samples_per_cycle * self.TONE_FULL_WAVES):
            sample = int((range - 1) * (math.sin(2 * math.pi * i / samples_per_cycle)) * amplitude)
            struct.pack_into(format, samples, i * sample_size_in_bytes, sample)

        # Are we not already playing tones?
        if not (self.__mode == WavPlayer.MODE_TONE and (self.__state == WavPlayer.PLAY or self.__state == WavPlayer.PAUSE)):
            self.__stop_i2s()                                       # Stop any active playback and terminate the I2S instance
            self.__tone_samples = samples
            self.__start_i2s(bits=self.TONE_BITS_PER_SAMPLE,
                             format=I2S.MONO,
                             rate=self.TONE_SAMPLE_RATE,
                             state=WavPlayer.PLAY,
                             mode=WavPlayer.MODE_TONE)
        else:
            self.__queued_samples = samples
            self.__state = WavPlayer.PLAY

    def pause(self):
        if self.__state == WavPlayer.PLAY:
            self.__state = WavPlayer.PAUSE          # Enter the pause state on the next callback

    def resume(self):
        if self.__state == WavPlayer.PAUSE:
            self.__state = WavPlayer.PLAY           # Enter the play state on the next callback

    def stop(self):
        if self.__state == WavPlayer.PLAY or self.__state == WavPlayer.PAUSE:
            if self.__mode == WavPlayer.MODE_WAV:
                self.__wav_file.close()
            else:
                self.__state = WavPlayer.STOP

    def is_playing(self):
        return self.__state != WavPlayer.NONE and self.__state != WavPlayer.STOP

    def is_paused(self):
        return self.__state == WavPlayer.PAUSE

    def __start_i2s(self, bits=16, format=I2S.MONO, rate=44_100, state=STOP, mode=MODE_WAV):
        import gc
        gc.collect()
        self.__audio_out = I2S(
            self.__id,
            sck=self.__sck_pin,
            ws=self.__ws_pin,
            sd=self.__sd_pin,
            mode=I2S.TX,
            bits=bits,
            format=format,
            rate=rate,
            ibuf=self.__ibuf_len,
        )

        print(f"Bits per sample: {bits}, format: {format}, rate: {rate}")

        self.__state = state
        self.__mode = mode
        self.__audio_out.irq(self.__i2s_callback)

        self.__silence()

        if self.__enable is not None:
            self.__enable.on()

    def __stop_i2s(self):
        self.stop()                     # Stop any active playback
        while self.is_playing():        # and wait for it to complete
            pass

        if self.__enable is not None:
            self.__enable.off()

        if self.__audio_out is not None:
            self.__audio_out.deinit()   # Deinit any active I2S comms

        self.__state == WavPlayer.NONE  # Return to the none state

    def __silence(self):
        # Generate silence, we probably just want to do this once
        for n in range(1024):
            self.__wav_samples_mv[n] = 0
        self.__audio_out.write(self.__wav_samples_mv[:1024])                  # Play silence

    def __i2s_callback(self, arg):
        # PLAY
        if self.__state == WavPlayer.PLAY:
            if self.__mode == WavPlayer.MODE_WAV:
                try:
                    num_read = self.__wav_file.readinto(self.__wav_samples_mv)      # Read the next section of the WAV file
                except ValueError:
                    self.__state = WavPlayer.STOP
                    self.__silence()
                    return

                # End of file, be it 0 or < target buffer
                # Or possibly a wav file with fewer samples than the output buffer size
                if num_read < self.__ibuf_len:
                    # If we're looping, seek to the start of the file and append the
                    # samples into the playback buffer-
                    if self.__loop_wav:
                        _ = self.__wav_file.seek(self.__first_sample_offset)    # Play again, so advance to first byte of sample data
                        self.__wav_file.readinto(self.__wav_samples_mv[num_read:])
                        self.__audio_out.write(self.__wav_samples_mv)
                        return

                    # ^ Early return for looped layback
                    # v Fill full buffer for single-shot playback

                    extra_bytes_needed = self.__ibuf_len - num_read
                    for n in range(extra_bytes_needed):
                        self.__wav_samples_mv[num_read + n] = 0
                    self.__audio_out.write(self.__wav_samples_mv)
                    self.__wav_file.close()                                 # Stop playing, so close the file
                    self.__state = WavPlayer.STOP                           # and enter the flush state on the next callback                              # Read 0 bytes, so we're clean off the end of the wav buffer

                else:
                    self.__audio_out.write(self.__wav_samples_mv)           # Write out our full buffer

            else:
                if self.__queued_samples is not None:
                    self.__tone_samples = self.__queued_samples
                    self.__queued_samples = None
                self.__audio_out.write(self.__tone_samples)

        # PAUSE or STOP
        elif self.__state == WavPlayer.PAUSE or self.__state == WavPlayer.STOP:
            self.__silence()

        # NONE
        elif self.__state == WavPlayer.NONE:
            pass

    @staticmethod
    def __parse_wav(wav_file):
        chunk_ID = wav_file.read(4)
        if chunk_ID != b"RIFF":
            raise ValueError("WAV chunk ID invalid")
        _ = wav_file.read(4)                            # chunk_size
        format = wav_file.read(4)
        if format != b"WAVE":
            raise ValueError("WAV format invalid")
        sub_chunk1_ID = wav_file.read(4)
        if sub_chunk1_ID != b"fmt ":
            raise ValueError("WAV sub chunk 1 ID invalid")
        _ = wav_file.read(4)                            # sub_chunk1_size
        _ = struct.unpack("<H", wav_file.read(2))[0]    # audio_format
        num_channels = struct.unpack("<H", wav_file.read(2))[0]

        if num_channels == 1:
            format = I2S.MONO
        else:
            format = I2S.STEREO

        sample_rate = struct.unpack("<I", wav_file.read(4))[0]
        # if sample_rate != 44_100 and sample_rate != 48_000:
        #    raise ValueError(f"WAV sample rate of {sample_rate} invalid. Only 44.1KHz or 48KHz audio are supported")

        _ = struct.unpack("<I", wav_file.read(4))[0]    # byte_rate
        _ = struct.unpack("<H", wav_file.read(2))[0]    # block_align
        bits_per_sample = struct.unpack("<H", wav_file.read(2))[0]

        # usually the sub chunk2 ID ("data") comes next, but
        # some online MP3->WAV converters add
        # binary data before "data".  So, read a fairly large
        # block of bytes and search for "data".

        binary_block = wav_file.read(200)
        offset = binary_block.find(b"data")
        if offset == -1:
            raise ValueError("WAV sub chunk 2 ID not found")

        return (format, sample_rate, bits_per_sample, 44 + offset)

    def __del__(self):
        if self.__enable is not None:
            self.__enable.off()

        if self.__audio_out is not None:
            self.__audio_out.deinit()   # Deinit any active I2S comms

class WavFile:
    HEADER_SIZE = 36
    def __init__(self, path):
        self._file = open(path, "rb")
        self._data_offset = HEADER_SIZE
        header = self._file.read(HEADER_SIZE)

It would be cool if Tone could be implemented this same way- just a class you set up and it generates an appropriate stream of samples. This would empower users to follow that pattern and make their own audio-generating classes... ala a pure Python version of our Synth for example 😆
I am loathe to proceed any further with this since I got nerd sniped by the audio pop and got carried away. It's your baby!

Could we have an MicroPython example for Pico Audio Pack too? 👀

I don't recall if we quite tackled all the bugs here, but I've merged these with the expectation that they'll get more visibility in the main codebase than here.
Thanks all!


Should replace Overture special case with simple general solution

longboye dhall file?

The overture special case is gone now and longboye now floats any module with a Prelude component so I'm going to consider this done since adding a config file would not have a good power to weight ratio at this point.


webpack3 best practical

webpack3-best-practical

js & css path

https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/694#issuecomment-357294990

Webpack3.x Best Practical


PR #4283 broke traceback on import errors.

When using flask 2.0.2 and having an error in the import the flask cli does not output the traceback anymore.
It seems to have stopped to work after https://github.com/pallets/flask/pull/4283 was merged.
To reproduce: make an import error and run:
(.venv) PS D:\Workspace\private\notifications\python-api> flask run --debugger --reload
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.

Error: While importing 'wsgi', an ImportError was raised.

Expected the following traceback:
Python 3.10.2 (tags/v3.10.2:a58ebcc, Jan 17 2022, 14:12:15) [MSC v.1929 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from gna import create_app
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "D:\Workspace\private\notifications\python-api\gna\__init__.py", line 4, in <module>
    from . import models, routes, services
  File "D:\Workspace\private\notifications\python-api\gna\routes\__init__.py", line 4, in <module>
    from .api import api_bp
ImportError: cannot import name 'api_bp' from 'gna.routes.api' (D:\Workspace\private\notifications\python-api\gna\routes\api\__init__.py)
>>>

Environment:

Python version: 3.10.2
Flask version: 2.0.2

The fix has been re-introduced with https://github.com/pallets/flask/commit/e679a85b80df354f8632f8ab3e40135f16f5e6d0#diff-fed8939d1905b99bba605ad91e9ccdf5ede6223e03ccbc3f0121853035051e62
already in master, when do you plan a new release ?

Duplicate of #4307

Any idea on the new release tho? cause its not really deployed yet

Always saying "duplicate x" or something like that, but the issue is still here...


Error: Network error: Cannot read property 'append' of undefined

there was an error sending the query Error: Network error: Cannot read property 'append' of undefined
at new ApolloError (ApolloError.js:34)
at Object.error (QueryManager.js:118)
at SubscriptionObserver.error (zen-observable.js:178)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:388)
at Object.onInvoke (core.es5.js:3890)
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invoke (zone.js:387)
at Zone.webpackJsonp.../../../../zone.js/dist/zone.js.Zone.run (zone.js:138)
at zone.js:858
at ZoneDelegate.webpackJsonp.../../../../zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)     at Object.onInvokeTask (core.es5.js:3881)

export class AppModule {
constructor(apollo: Apollo, httpLink: HttpLink) {
// apollo.create({
//   link: httpLink.create({
//     uri: 'http://localhost:6060/authscure'
//   }),
//   cache: new InMemoryCache()
// });
const http = httpLink.create({ uri: 'http://localhost:6060/authscure' });
const auth = setContext((_, { headers }) => {
  // get the authentication token from local storage if it exists
  // const token = localStorage.getItem('token');
  const token = "auth5cur3";
  const signature = "FAC2CA55ED98AB2E39947CD70121DB194B52224D7DFF40A919865130DC1A2409";
  // return the headers to the context so httpLink can read them
  // in this example we assume headers property exists
  // and it is an instance of HttpHeaders

  if (!token) {
    return {};
  } else {

    return {
      headers: headers.append('Authorization', `Bearer ${token}`)

    };
  }
});

apollo.create({
link: auth.concat(http),
cache: new InMemoryCache(),
});
}
}

@s1gu Maybe there's no headers?
return {
  headers: headers.append('Authorization', `Bearer ${token}`)
};

@kamilkisiela @apollographql
HI,
I was about to open a new issue but I saw this first.
I had the same problem.
The solution is in this doc:
https://github.com/apollographql/apollo-angular/tree/master/packages/apollo-angular-link-headers
It seems there is documentation mismatch.
The solution that is working for me is:
const auth = setContext((request, previousContext) => ({         authorization: token    }));
Below is the full service, and it is working:
note: the token is gather by KeyCloak and is used on HTTP and WS
`import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import { KeycloakService } from 'keycloak-angular';
import { HttpHeaders } from '@angular/common/http';
import { Apollo } from 'apollo-angular';
import { HttpLink } from 'apollo-angular-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { WebSocketLink } from 'apollo-link-ws';
import { split } from 'apollo-link';
import { getMainDefinition } from 'apollo-utilities';
import { httpHeaders } from 'apollo-angular-link-headers';
@Injectable()
export class GatewayService {
constructor(
public apollo: Apollo,
private httpLink: HttpLink,
private keycloakService: KeycloakService
) {
//HTTP end-point
const http = httpLink.create({ uri: environment.api.gateway.graphql.httpEndPoint });

this.keycloakService.getToken().then(token => {

  const auth = setContext((request, previousContext) => ({
    authorization: token
  }));

  // //Add the JWT token in every request
  // const auth = setContext((operation, {headers}) => {

  // Create a WebSocket link:
  const ws = new WebSocketLink({
    uri: environment.api.gateway.graphql.wsEndPoint,
    options: {
      reconnect: true,
      connectionParams: {
        authToken: token,
      },
    }
  });

  // using the ability to split links, you can send data to each link
  // depending on what kind of operation is being sent
  const link = split(
    // split based on operation type
    ({ query }) => {
      const { kind, operation } = getMainDefinition(query);
      return kind === 'OperationDefinition' && operation === 'subscription';
    },
    ws,
    auth.concat(http),
  );

  //Create Apollo client
  this.apollo.create({
    link,
    cache: new InMemoryCache()
  });

});

}
}`

I had the same issue before. I'd successfully passed the authorization header by directly passing it inside the headers object.
return {
    headers: {
        Authorization: `Bearer ${token}`
    }
};

Yes, with Angular 6 it's no longer required to use HttpHeaders, simple objects are fine.


epic: New Model Support SOP + Ownership

Problem
We are not supporting new models fast enough.

New model is published by author
Create HF model card, with correct descriptions, attribution, etc
Trigger CI to convert the model into GGUF, TRTLLM, and ONNX, and upload to HF
Trigger QA automation to ensure default yaml works

Debug & curate the model.yaml params, alert cpp team of upstream blockers

Ensure it is downloadable and usable on Cortex
Ensure it is downloadable and usable on Jan
Craft a mini update to users with Emre

Related

#1155
#1346

I think we need to a process to support this:

Repo: janhq/models
Model Status:
Ownership of each Status + Process


Firefox doesn't work over HTTP basic auth with CORS

Firefox seems to be more stringent about downloading image assets over CORS when basic auth is enabled. This means that landmarking images is not possible on Firefox over a secure connection, and 3D meshes only work untextured. It is not yet known what steps can be taken to alleviate the issue.

This is fixed, see #67 #68